聊天参与者 API
聊天参与者是专业的助手,允许用户通过领域专家扩展 VS Code 中的聊天功能。用户通过 @-提及(@-mentioning)来调用聊天参与者,随后由参与者负责处理用户的自然语言提示。
在本扩展指南中,您将学习如何使用聊天参与者 API 创建一个聊天参与者。
VS Code 有几个内置的聊天参与者,如 @vscode、@terminal 或 @workspace。它们经过优化,可以回答各自领域的问题。
聊天参与者与语言模型工具不同,后者是作为 LLM 编排解析用户聊天提示所需步骤的一部分被调用的。聊天参与者接收用户的提示并自行编排所需的任务。
为什么要为您的扩展实现聊天参与者?
在您的扩展中实现聊天参与者有几个好处:
- 扩展聊天功能:提供专门的领域知识和专业技能。例如,内置的
@vscode参与者拥有关于 VS Code 及其扩展 API 的知识。 - 掌控对话:管理端到端的聊天提示和响应。
- 与 VS Code 深度集成:利用广泛的扩展 API。例如,使用调试 API 获取当前的调试上下文,并将其作为工具功能的一部分使用。
- 分发和部署:通过 Visual Studio Marketplace 分发聊天参与者,为用户提供可靠且无缝的体验。用户无需单独的安装和更新过程。
如果您想提供可在自主代理编码会话中自动调用的领域特定功能,可以考虑实现语言模型工具或 MCP 服务器。有关不同选项以及如何决定使用哪种方法的详细信息,请参阅 AI 可扩展性概述。
聊天用户体验的组成部分
以下屏幕截图展示了示例扩展中 VS Code 聊天体验中的不同聊天概念。

- 使用
@语法调用@cat聊天参与者 - 使用
/语法调用/teach命令 - 用户提供的查询,也称为用户提示
- 图标和参与者
fullName,表明 Copilot 正在使用@cat聊天参与者 - Markdown 响应,由
@cat提供 - 包含在 Markdown 响应中的代码片段
- 包含在
@cat响应中的按钮,该按钮调用 VS Code 命令 - 由聊天参与者提供的建议后续问题
- 聊天输入框,带有由聊天参与者的
description属性提供的占位符文本
创建聊天参与者
实现聊天参与者包含以下部分:
- 在扩展的
package.json文件中定义聊天参与者。 - 实现请求处理程序以处理用户的聊天提示并返回响应。
- (可选)实现聊天斜杠命令,为用户提供常见任务的简写符号。
- (可选)定义建议的后续问题。
- (可选)实现参与者检测,使 VS Code 能够自动将聊天请求路由到合适的参与者,而无需用户显式提及。
您可以从一个基础示例项目开始。

1. 注册聊天参与者
创建聊天扩展的第一步是在 package.json 中注册它,并包含以下属性:
id:聊天参与者的唯一标识符,定义在package.json文件中。name:聊天参与者的简称,用于聊天中的 @-提及。fullName:聊天参与者的全名,显示在响应的标题区域。description:聊天参与者用途的简要说明,用作聊天输入框中的占位符文本。isSticky:布尔值,指示聊天参与者在响应后是否保留在聊天输入框中。
"contributes": {
"chatParticipants": [
{
"id": "chat-sample.my-participant",
"name": "my-participant",
"fullName": "My Participant",
"description": "What can I teach you?",
"isSticky": true
}
]
}
我们建议使用小写的 name 并对 fullName 使用标题大小写,以与现有的聊天参与者保持一致。获取关于聊天参与者命名约定的更多信息。
一些参与者名称是保留的。如果您使用此类保留名称,VS Code 会显示您的聊天参与者的全限定名称(包括扩展 ID)。
2. 实现请求处理程序
使用 Chat Participant API 实现聊天参与者。这包含以下步骤:
-
在扩展激活时,使用
vscode.chat.createChatParticipant创建参与者。提供您在
package.json中定义的 ID,以及对您在下一步中实现的请求处理程序的引用。export function activate(context: vscode.ExtensionContext) { // Register the chat participant and its request handler const cat = vscode.chat.createChatParticipant('chat-sample.my-participant', handler); // Optionally, set some properties for @cat cat.iconPath = vscode.Uri.joinPath(context.extensionUri, 'cat.jpeg'); // Add the chat request handler here } -
在
activate函数中,定义vscode.ChatRequestHandler请求处理程序。请求处理程序负责处理 VS Code 聊天视图中的用户聊天请求。每当用户在聊天输入框中输入提示时,就会调用聊天请求处理程序。
const handler: vscode.ChatRequestHandler = async ( request: vscode.ChatRequest, context: vscode.ChatContext, stream: vscode.ChatResponseStream, token: vscode.CancellationToken ): Promise<ICatChatResult> => { // Chat request handler implementation goes here }; -
从
vscode.ChatRequest中确定用户的意图。要确定用户请求的意图,您可以参考
vscode.ChatRequest参数来访问用户的提示文本、命令和聊天位置。(可选)您可以利用语言模型来确定用户的意图,而不是使用传统的逻辑。作为
request对象的一部分,您会获得用户在聊天模型下拉列表中选择的语言模型实例。了解如何在您的扩展中使用 Language Model API。以下代码片段展示了首先使用命令,然后使用用户提示来确定用户意图的基本结构:
const handler: vscode.ChatRequestHandler = async ( request: vscode.ChatRequest, context: vscode.ChatContext, stream: vscode.ChatResponseStream, token: vscode.CancellationToken ): Promise<ICatChatResult> => { // Test for the `teach` command if (request.command == 'teach') { // Add logic here to handle the teaching scenario doTeaching(request.prompt, request.variables); } else { // Determine the user's intent const intent = determineUserIntent(request.prompt, request.variables, request.model); // Add logic here to handle other scenarios } }; -
添加逻辑以处理用户请求。
通常,聊天扩展使用
request.model语言模型实例来处理请求。在这种情况下,您可能需要调整语言模型提示以匹配用户的意图。或者,您可以通过调用后端服务、使用传统的编程逻辑或结合所有这些选项来实现扩展逻辑。例如,您可以调用网络搜索来收集额外信息,然后将其作为上下文提供给语言模型。
在处理当前请求时,您可能希望参考以前的聊天消息。例如,如果之前的响应返回了一个 C# 代码片段,用户当前的请求可能是“用 Python 提供这段代码”。了解如何使用聊天消息历史记录。
如果您想根据聊天输入的位置(聊天视图、快速聊天、内联聊天)以不同方式处理请求,可以使用
vscode.ChatRequest的location属性。例如,如果用户从终端内联聊天发送请求,您可能会查找 shell 命令。而如果用户使用聊天视图,您可以返回更详尽的响应。 -
向用户返回聊天响应。
处理完请求后,您必须在聊天视图中向用户返回响应。您可以使用流式传输来响应用户的查询。
响应可以包含不同的内容类型:Markdown、图像、引用、进度、按钮和文件树。

扩展可以通过以下方式使用响应流:
stream.progress('Picking the right topic to teach...'); stream.markdown(`\`\`\`typescript const myStack = new Stack(); myStack.push(1); // pushing a number on the stack (or let's say, adding a fish to the stack) myStack.push(2); // adding another fish (number 2) console.log(myStack.pop()); // eating the top fish, will output: 2 \`\`\` So remember, Code Kitten, in a stack, the last fish in is the first fish out - which we tech cats call LIFO (Last In, First Out).`); stream.button({ command: 'cat.meow', title: vscode.l10n.t('Meow!'), arguments: [] });获取关于支持的聊天响应输出类型的更多信息。
实际上,扩展通常会向语言模型发送请求。一旦从语言模型获得响应,它们可能会进一步处理它,并决定是否应该向用户流式传输任何内容。VS Code Chat API 是基于流的,并与流式 Language Model API 兼容。这允许扩展持续报告进度和结果,旨在提供流畅的用户体验。了解如何使用 Language Model API。
3. 注册斜杠命令
聊天参与者可以贡献斜杠命令,这是扩展提供的特定功能的快捷方式。用户可以通过 / 语法在聊天中引用斜杠命令,例如 /explain。
回答问题时的任务之一是确定用户意图。例如,VS Code 可以推断 Create a new workspace with Node.js Express Pug TypeScript 意味着您想要一个新项目,但 @workspace /new Node.js Express Pug TypeScript 更明确、简洁且节省输入时间。如果您在聊天输入框中输入 /,VS Code 会提供已注册命令及其说明的列表。

聊天参与者可以通过在 package.json 中添加斜杠命令及其说明来贡献它们:
"contributes": {
"chatParticipants": [
{
"id": "chat-sample.cat",
"name": "cat",
"fullName": "Cat",
"description": "Meow! What can I teach you?",
"isSticky": true,
"commands": [
{
"name": "teach",
"description": "Pick at random a computer science concept then explain it in purfect way of a cat"
},
{
"name": "play",
"description": "Do whatever you want, you are a cat after all"
}
]
}
]
}
获取关于斜杠命令命名约定的更多信息。
4. 注册后续请求
在每次聊天请求后,VS Code 会调用后续提供程序以获取建议的后续问题展示给用户。用户随后可以选择后续问题,并立即将其发送给聊天扩展。使用 ChatFollowupProvider API 来注册 ChatFollowup 类型的后续提示。
以下代码片段展示了如何在聊天扩展中注册后续请求:
cat.followupProvider = {
provideFollowups(result: ICatChatResult, context: vscode.ChatContext, token: vscode.CancellationToken) {
if (result.metadata.command === 'teach') {
return [{
prompt: 'let us play',
label: vscode.l10n.t('Play with the cat')
} satisfies vscode.ChatFollowup];
}
}
};
后续问题应写成问题或指导,而不仅仅是简洁的命令。
5. 实现参与者检测
为了使聊天参与者更容易通过自然语言使用,您可以实现参与者检测。参与者检测是一种自动将用户问题路由到合适参与者的方法,而无需在提示中明确提及该参与者。例如,如果用户询问“如何向我的项目添加登录页面?”,该问题将自动路由到 @workspace 参与者,因为它能够回答关于用户项目的问题。
VS Code 使用聊天参与者的描述和示例来确定将聊天提示路由到哪个参与者。您可以在扩展 package.json 文件的 disambiguation 属性中指定此信息。disambiguation 属性包含一个检测类别列表,每个类别都有描述和示例。
| 属性 | 描述 | 示例 |
|---|---|---|
category |
检测类别。如果参与者有不同的用途,您可以为每个用途创建一个类别。 |
|
描述 |
对此参与者适用的问题类型的详细描述。 |
|
examples |
代表性示例问题的列表。 |
|
您可以为整体聊天参与者、特定命令或两者的组合定义参与者检测。
以下代码片段展示了如何在参与者级别实现参与者检测。
"contributes": {
"chatParticipants": [
{
"id": "chat-sample.cat",
"fullName": "Cat",
"name": "cat",
"description": "Meow! What can I teach you?",
"disambiguation": [
{
"category": "cat",
"description": "The user wants to learn a specific computer science topic in an informal way.",
"examples": [
"Teach me C++ pointers using metaphors",
"Explain to me what is a linked list in a simple way",
"Can you explain to me what is a function in programming?"
]
}
]
}
]
}
同样,您也可以通过在 commands 属性中的一项或多项添加 disambiguation 属性,在命令级别配置参与者检测。
应用以下准则以提高扩展的参与者检测准确性:
- 具体明确:描述和示例应尽可能具体,以避免与其他参与者冲突。在参与者和命令信息中避免使用通用术语。
- 使用示例:示例应代表适合该参与者的问题类型。使用同义词和变体来涵盖广泛的用户查询。
- 使用自然语言:描述和示例应以自然语言编写,就好像您在向用户解释该参与者一样。
- 测试检测:用各种示例问题测试参与者检测,并验证是否与内置聊天参与者没有冲突。
内置聊天参与者在参与者检测中具有优先权。例如,在工作区文件上操作的聊天参与者可能会与内置的 @workspace 参与者发生冲突。
使用聊天消息历史记录
参与者可以访问当前聊天会话的消息历史记录。参与者只能访问提到它本身的消息。history 项目是 ChatRequestTurn 或 ChatResponseTurn。例如,使用以下代码片段检索用户在当前聊天会话中发送给您的参与者的所有先前请求:
const previousMessages = context.history.filter(h => h instanceof vscode.ChatRequestTurn);
历史记录不会自动包含在提示中,参与者需要自行决定在将消息传递给语言模型时是否要添加历史记录作为额外上下文。
支持的聊天响应输出类型
要响应聊天请求,您需要使用 ChatRequestHandler 上的 ChatResponseStream 参数。
以下列表提供了聊天视图中聊天响应的输出类型。聊天响应可以组合多种不同的输出类型。
-
Markdown
渲染 Markdown 文本片段、简单文本或图像。您可以使用 CommonMark 规范中包含的任何 Markdown 语法。使用
ChatResponseStream.markdown方法并提供 Markdown 文本。代码片段示例
// Render Markdown text stream.markdown('# This is a title \n'); stream.markdown('This is stylized text that uses _italics_ and **bold**. '); stream.markdown('This is a [link](https://vscode.js.cn).\n\n'); stream.markdown(''); -
代码块
渲染支持 IntelliSense、代码格式化和交互式控件的代码块,以将代码应用到活动编辑器。要显示代码块,请使用
ChatResponseStream.markdown方法并应用代码块的 Markdown 语法(使用反引号)。代码片段示例
// Render a code block that enables users to interact with stream.markdown('```bash\n'); stream.markdown('```ls -l\n'); stream.markdown('```'); -
命令链接
在聊天响应中渲染一个内联链接,用户可以选择该链接来调用 VS Code 命令。要显示命令链接,请使用
ChatResponseStream.markdown方法并使用链接的 Markdown 语法[link text](command:commandId),其中您在 URL 中提供命令 ID。例如,以下链接会打开命令面板:[Command Palette](command:workbench.action.showCommands)。为了防止从服务加载 Markdown 文本时发生命令注入,您必须使用
vscode.MarkdownString对象,并将isTrusted属性设置为受信任的 VS Code 命令 ID 列表。此属性是启用命令链接正常工作的必要条件。如果未设置isTrusted属性或命令未列出,命令链接将无法工作。代码片段示例
// Use command URIs to link to commands from Markdown let markdownCommandString: vscode.MarkdownString = new vscode.MarkdownString( `[Use cat names](command:${CAT_NAMES_COMMAND_ID})` ); markdownCommandString.isTrusted = { enabledCommands: [CAT_NAMES_COMMAND_ID] }; stream.markdown(markdownCommandString);如果命令带有参数,您需要首先对参数进行 JSON 编码,然后将 JSON 字符串编码为 URI 组件。然后,您可以将编码后的参数作为查询字符串附加到命令链接中。
// Encode the command arguments const encodedArgs = encodeURIComponent(JSON.stringify(args)); // Use command URIs with arguments to link to commands from Markdown let markdownCommandString: vscode.MarkdownString = new vscode.MarkdownString( `[Use cat names](command:${CAT_NAMES_COMMAND_ID}?${encodedArgs})` ); markdownCommandString.isTrusted = { enabledCommands: [CAT_NAMES_COMMAND_ID] }; stream.markdown(markdownCommandString); -
命令按钮
渲染一个调用 VS Code 命令的按钮。该命令可以是内置命令,也可以是您在扩展中定义的命令。使用
ChatResponseStream.button方法并提供按钮文本和命令 ID。代码片段示例
// Render a button to trigger a VS Code command stream.button({ command: 'my.command', title: vscode.l10n.t('Run my command') }); -
文件树
渲染一个文件树控件,允许用户预览单个文件。例如,当提议创建新工作区时显示工作区预览。使用
ChatResponseStream.filetree方法并提供文件树元素数组和文件的基本位置(文件夹)。代码片段示例
// Create a file tree instance var tree: vscode.ChatResponseFileTree[] = [ { name: 'myworkspace', children: [{ name: 'README' }, { name: 'app.js' }, { name: 'package.json' }] } ]; // Render the file tree control at a base location stream.filetree(tree, baseLocation); -
进度消息
在长时间运行的操作期间渲染进度消息,以向用户提供中间反馈。例如,报告多步操作中每一步的完成情况。使用
ChatResponseStream.progress方法并提供消息。代码片段示例
// Render a progress message stream.progress('Connecting to the database.'); -
参考
在引用列表中添加外部 URL 或编辑器位置的引用,以指明您将哪些信息用作上下文。使用
ChatResponseStream.reference方法并提供参考位置。代码片段示例
const fileUri: vscode.Uri = vscode.Uri.file('/path/to/workspace/app.js'); // On Windows, the path should be in the format of 'c:\\path\\to\\workspace\\app.js' const fileRange: vscode.Range = new vscode.Range(0, 0, 3, 0); const externalUri: vscode.Uri = vscode.Uri.parse('https://vscode.js.cn'); // Add a reference to an entire file stream.reference(fileUri); // Add a reference to a specific selection within a file stream.reference(new vscode.Location(fileUri, fileRange)); // Add a reference to an external URL stream.reference(externalUri); -
内联引用
添加对 URI 或编辑器位置的内联引用。使用
ChatResponseStream.anchor方法并提供锚点位置和可选标题。要引用符号(例如,类或变量),您将使用编辑器中的位置。代码片段示例
const symbolLocation: vscode.Uri = vscode.Uri.parse('location-to-a-symbol'); // Render an inline anchor to a symbol in the workspace stream.anchor(symbolLocation, 'MySymbol');
重要提示:图像和链接仅在源自受信任域列表中的域时才可用。获取关于 VS Code 中链接保护的更多信息。
实现工具调用
为了响应用户请求,聊天扩展可以调用语言模型工具。了解有关 语言模型工具和 工具调用流程 的更多信息。
您可以通过两种方式实现工具调用:
- 使用
@vscode/chat-extension-utils库 来简化在聊天扩展中调用工具的过程。 - 自行实现工具调用,这使您对工具调用过程有更多控制权。例如,执行额外的验证或在将工具响应发送给 LLM 之前以特定方式处理它们。
使用聊天扩展库实现工具调用
您可以使用 @vscode/chat-extension-utils 库 来简化在聊天扩展中调用工具的过程。
在聊天参与者的 vscode.ChatRequestHandler 函数中实现工具调用。
-
确定当前聊天上下文的相关工具。您可以通过使用
vscode.lm.tools访问所有可用工具。以下代码片段展示了如何将工具筛选为仅具有特定标签的工具。
const tools = request.command === 'all' ? vscode.lm.tools : vscode.lm.tools.filter(tool => tool.tags.includes('chat-tools-sample')); -
使用
sendChatParticipantRequest将请求和工具定义发送给 LLM。const libResult = chatUtils.sendChatParticipantRequest( request, chatContext, { prompt: 'You are a cat! Answer as a cat.', responseStreamOptions: { stream, references: true, responseText: true }, tools }, token );ChatHandlerOptions对象具有以下属性:prompt:(可选)聊天参与者提示的说明。model:(可选)用于请求的模型。如果未指定,将使用聊天上下文中的模型。tools:(可选)请求需考虑的工具列表。requestJustification:(可选)描述进行该请求原因的字符串。responseStreamOptions:(可选)使sendChatParticipantRequest能够将响应流式传输回 VS Code。或者,您还可以启用引用和/或响应文本。
-
返回来自 LLM 的结果。这可能包含错误详细信息或工具调用元数据。
return await libResult.result;
此 工具调用示例 的完整源代码可在 VS Code 扩展示例存储库中找到。
自行实现工具调用
对于更高级的场景,您也可以自行实现工具调用。您可以选择使用 @vscode/prompt-tsx 库来构建 LLM 提示。通过自行实现工具调用,您可以对工具调用过程拥有更多控制权。例如,执行额外的验证或在将工具响应发送给 LLM 之前以特定方式处理它们。
在 VS Code 扩展示例存储库中查看使用 prompt-tsx 实现 工具调用 的完整源代码。
衡量成功
我们建议您通过为 Unhelpful(无帮助)用户反馈事件以及您的参与者处理的总请求数添加遥测日志记录来衡量参与者的成功。初始参与者成功指标可以定义为:unhelpful_feedback_count / total_requests。
const logger = vscode.env.createTelemetryLogger({
// telemetry logging implementation goes here
});
cat.onDidReceiveFeedback((feedback: vscode.ChatResultFeedback) => {
// Log chat result feedback to be able to compute the success metric of the participant
logger.logUsage('chatResultFeedback', {
kind: feedback.kind
});
});
与您的聊天响应进行的任何其他用户交互都应作为正向指标进行衡量(例如,用户选择了在聊天响应中生成的按钮)。在使用 AI 时,通过遥测衡量成功至关重要,因为它是一项非确定性技术。进行实验、衡量并迭代改进您的参与者,以确保良好的用户体验。
准则和约定
准则
聊天参与者不应仅仅是问答机器人。在构建聊天参与者时,要有创造力,并利用现有的 VS Code API 在 VS Code 中创建丰富的集成。用户也喜欢丰富便捷的交互,例如响应中的按钮、将用户带到聊天中您的参与者的菜单项。考虑 AI 可以帮助您用户的现实生活场景。
并不是每个扩展都贡献一个聊天参与者才有意义。在聊天中拥有太多的参与者可能会导致糟糕的用户体验。当您想要控制完整提示(包括对语言模型的指令)时,聊天参与者效果最好。您可以重用精心制作的 Copilot 系统消息,并可以向其他参与者贡献上下文。
例如,语言扩展(如 C++ 扩展)可以通过其他各种方式做出贡献:
- 贡献工具,将语言服务智能带入用户查询。例如,C++ 扩展可以将
#cpp工具解析为工作区的 C++ 状态。这为 Copilot 语言模型提供了正确的 C++ 上下文,从而提高 Copilot 对 C++ 答案的质量。 - 贡献智能操作,使用语言模型(可选地结合传统的语言服务知识)来提供出色的用户体验。例如,C++ 可能已经提供了一个“提取到方法”的智能操作,该操作使用语言模型为新方法生成合适的默认名称。
如果聊天扩展即将执行昂贵的操作,或者即将编辑或删除不可撤销的内容,则应明确征求用户同意。为了获得良好的用户体验,我们不鼓励扩展贡献多个聊天参与者。每个扩展最多一个聊天参与者是一种简单且在 UI 中扩展性良好的模型。
聊天参与者命名约定
| 属性 | 描述 | 命名准则 |
|---|---|---|
id |
聊天参与者的全局唯一标识符 |
|
|
聊天参与者的名称,用户通过 @ 符号引用 |
|
fullName |
(可选)参与者的全名,显示为来自该参与者的响应标签 |
|
描述 |
(可选)关于聊天参与者功能的简短说明,显示为聊天输入框中的占位符文本或参与者列表中的文本 |
|
在任何面向用户的元素(如属性、聊天响应或聊天用户界面)中提及您的聊天参与者时,建议不要使用术语 participant,因为这是 API 的名称。例如,@cat 扩展可以称为“GitHub Copilot 的 Cat 扩展”。
斜杠命令命名约定
| 属性 | 描述 | 命名准则 |
|---|---|---|
|
斜杠命令名称,用户通过 / 符号引用 |
|
描述 |
(可选)斜杠命令功能的简短说明,显示为聊天输入框或参与者和命令列表中的占位符文本 |
|
发布您的扩展
创建 AI 扩展后,您可以将其发布到 Visual Studio Marketplace
- 在发布到 VS Marketplace 之前,我们建议您阅读 Microsoft AI 工具和实践准则。这些准则为 AI 技术的负责任开发和使用提供了最佳实践。
- 通过发布到 VS Marketplace,您的扩展遵守 GitHub Copilot 可扩展性可接受的开发和使用政策。
- 按照 发布扩展 中的描述上传到 Marketplace。
- 如果您的扩展已经提供了除聊天以外的功能,我们建议您不要在 扩展清单 中引入对 GitHub Copilot 的扩展依赖。这确保不使用 GitHub Copilot 的扩展用户可以在无需安装 GitHub Copilot 的情况下使用非聊天功能。
通过 GitHub Apps 扩展 GitHub Copilot
或者,可以通过创建在聊天视图中贡献聊天参与者的 GitHub App 来扩展 GitHub Copilot。GitHub App 由服务支持,并可在所有 GitHub Copilot 界面(如 github.com、Visual Studio 或 VS Code)中使用。另一方面,GitHub Apps 无法完全访问 VS Code API。要了解更多关于通过 GitHub App 扩展 GitHub Copilot 的信息,请参阅 GitHub 文档。
使用语言模型
聊天参与者可以以多种方式使用语言模型。一些参与者仅使用语言模型来获取自定义提示的答案,例如 示例聊天参与者。其他参与者更高级,表现得像自主代理,在语言模型的帮助下调用多种工具。此类高级参与者的一个示例是内置的 @workspace,它了解您的工作区并可以回答有关它的问题。在内部,@workspace 由多种工具驱动:GitHub 的知识图谱,结合语义搜索、本地代码索引和 VS Code 的语言服务。