- 文档
- 教程
【免费下载链接】vscode-docs
Public documentation for Visual Studio Code
Language Model API 是 VS Code 提供给扩展作者的官方接口,它让扩展可以直接调用语言模型(如 GitHub Copilot 背后的 GPT 系列模型),从而在编辑器、聊天、调试等场景中注入 AI 能力。本文以 api/extension-guides/ai/language-model.md 为核心,系统讲解从提示词构建、模型选择、请求发送到流式响应解析的完整链路,并结合仓库中的 Chat Participant API 指南、prompt-tsx 提示词编排指南 与 Code Tutor 实战教程 展开源码级补充,读完你将能独立实现一个具备自然语言理解能力的 AI 扩展。
适用场景与完整使用流程
Language Model API 允许你通过 API 参考 中的lm命名空间"使用语言模型",把 AI 驱动的功能与自然语言处理能力集成进 VS Code 扩展。它的典型用途是 Chat 扩展:用语言模型解读用户的自然语言请求并生成回答。但它的使用并不局限于聊天场景,你完全可以在以下类型的扩展中使用:
- 语言扩展:例如 Rust 扩展可以用语言模型为重命名操作提供更智能的默认命名建议;
- 调试器扩展:辅助分析堆栈、生成调试建议;
- 命令 与 任务提供方:把 AI 能力作为自定义命令或任务的一部分。
使用 Language Model API 的过程由三个步骤构成:
- 构建语言模型提示词(Build the language model prompt)——组织给模型的指令与上下文;
- 发送语言模型请求(Send the language model request)——选择合适的模型并提交请求;
- 解析响应(Interpret the response)——处理流式返回的文本,输出给用户或触发后续逻辑。
构建语言模型提示词
与语言模型交互前,扩展首先要精心组织提示词(prompt):提示词既承载"这个模型要完成什么任务"的宽泛指令,也定义"用户消息应该如何在上下文中被解读"。Language Model API 支持两种消息类型来构建提示词:
| 消息类型 | 用途 |
|---|---|
| User(用户消息) | 提供指令与用户的具体请求 |
| Assistant(助手消息) | 把之前语言模型的响应历史作为上下文加入提示词 |
注意:当前 Language Model API不支持 system 消息。如果你需要设定系统级角色约束,请把它写进第一条 User 消息中(下文示例正是这么做的)。
构建提示词有两种方式:
LanguageModelChatMessage类:直接以字符串形式提供一条或多条消息,适合刚上手 Language Model API 的开发者;@vscode/prompt-tsx库:用 TSX 语法声明式编排提示词,适合对提示词组合有更强控制需求的场景。例如该库可以动态适配不同模型各自的上下文窗口大小。
技巧:善用 VS Code 丰富的扩展 API 获取最相关的上下文并写入提示词——例如把编辑器当前活动文件的内容包含进去,能让模型基于真实代码作答。
使用 LanguageModelChatMessage 类
Language Model API 提供了LanguageModelChatMessage类来表示和创建聊天消息,通过LanguageModelChatMessage.User与LanguageModelChatMessage.Assistant两个静态方法分别创建用户消息与助手消息。
下面示例中的第一条消息为提示词提供上下文:
- 模型回复时采用的人设(这里是一只猫);
- 模型生成回复时必须遵守的规则(这里要求:用猫的比喻以幽默方式讲解计算机科学概念)。
第二条消息则给出用户的具体请求或指令,它决定在第一条消息给定的上下文之上要完成的具体任务:
const craftedPrompt = [ vscode.LanguageModelChatMessage.User('You are a cat! Think carefully and step by step like a cat would. Your job is to explain computer science concepts in the funny manner of a cat, using cat metaphors. Always start your response by stating what concept you are explaining. Always include code samples.'), vscode.LanguageModelChatMessage.User('I want to understand recursion') ];消息数组可以包含任意多条消息,这正是把多轮对话历史塞进提示词的基础:近期的 User/Assistant 轮次按时间顺序排列,模型即可"读懂"上下文。
用 prompt-tsx 编排复杂提示词
当提示词结构变复杂(需要动态拼接对话历史、按优先级裁剪内容以适配上下文窗口)时,api/extension-guides/ai/prompt-tsx.md 介绍的@vscode/prompt-tsx库提供了更工程化的方案。它的核心能力包括:
- 基于 TSX 的提示词渲染:用组件组合提示词,可读性与可维护性更高;
- 基于优先级的裁剪(priority-based pruning):自动裁剪提示词中优先级较低的部分,使其适配模型上下文窗口;
- 灵活的 token 管理:通过
flexGrow、flexReserve、flexBasis等属性协同分配 token 预算; - 工具集成:与 VS Code 的语言模型工具 API 对接。
对话历史的优先级处理是 prompt-tsx 的典型用法。通常建议按如下顺序排列优先级(从高到低):
- 基础提示词指令;
- 当前用户查询;
- 最近几轮聊天历史;
- 任何支撑性数据;
- 放得下的剩余历史。
在库中每个 TSX 节点的优先级类似于zIndex,数值越大优先级越高。通过定义HistoryMessages与MyPrompt等PromptElement组件,配合PrioritizedList辅助组件(自动为子节点分配升序或降序优先级),即可把历史消息合理地分层融入提示词——较新的对话轮次优先保留,较早的历史在需要时最先被裁剪。
发送语言模型请求
提示词构建完成后,进入请求阶段,包含两步:选择模型与发送请求。
选择语言模型:selectChatModels
使用selectChatModels方法选择要使用的语言模型,它返回符合指定条件的模型数组。可以指定以下属性来筛选模型:
vendor(供应商)id(模型唯一标识)family(模型家族)version(版本)
通过这些属性,你可以宽泛匹配某个供应商或家族的所有模型,也可以精确选中某个具体 ID 的模型。例如,以下代码选择所有Copilot供应商的模型,不区分家族与版本:
const models = await vscode.lm.selectChatModels({ vendor: 'copilot' }); // No models available if (models.length === 0) { // TODO: handle the case when no models are available }如果没有任何模型匹配指定条件,selectChatModels返回空数组,扩展必须妥善处理这种情况(例如提示用户登录 GitHub Copilot 或选择可用模型)。
重要:Copilot 的语言模型要求用户先同意,扩展才能使用它们。同意机制表现为一次身份验证对话框,因此
selectChatModels应该由用户主动发起的动作(如一条命令)触发,而不应在扩展激活时静默调用。
提示:当前支持的模型家族包括
gpt-4o、gpt-4o-mini、o1、o1-mini、claude-3.5-sonnet。如果不确定该选哪个,综合性能与质量推荐gpt-4o;针对编辑器内的直接交互场景,推荐响应更快的gpt-4o-mini。
若你正在实现 Chat 参与者,官方强烈建议直接使用 chat request handler 的request对象中传入的模型,而不是自行调用selectChatModels——这样扩展会尊重用户在聊天模型下拉框中自行选择的模型。
发送请求:sendRequest 与错误处理
选中模型后,调用模型实例上的sendRequest方法发送请求。你需要传入之前构建好的提示词、附加选项(示例中为空对象{})以及取消令牌(CancellationToken)。
请求可能失败,例如:模型不存在、用户未同意使用 Language Model API、配额(quota)超限等。请使用LanguageModelError区分不同类型的错误:
try { const [model] = await vscode.lm.selectChatModels({ vendor: 'copilot', family: 'gpt-4o' }); const request = model.sendRequest(craftedPrompt, {}, token); } catch (err) { // Making the chat request might fail because // - model does not exist // - user consent not given // - quota limits were exceeded if (err instanceof vscode.LanguageModelError) { console.log(err.message, err.code, err.cause); if (err.cause instanceof Error && err.cause.message.includes('off_topic')) { stream.markdown(vscode.l10n.t('I\'m sorry, I can only explain computer science concepts.')); } } else { // add other error handling logic throw err; } }注意LanguageModelError的三个关键字段:
err.message——人类可读的错误描述;err.code——机器可读的错误码,可用于精确分支;err.cause——底层原始错误对象,例如包含off_topic标记的拒绝原因(模型拒绝回答越界话题),可以据此给用户更友好的本地化提示(如上面的vscode.l10n.t(...))。
完整命令示例:把流式响应写回编辑器
下面的完整示例注册一个文本编辑器命令,它用语言模型把当前活动编辑器里的所有变量名改成"有趣的猫名",并边生成边流式写入编辑器,保证流畅的用户体验:
vscode.commands.registerTextEditorCommand('cat.namesInEditor', async (textEditor: vscode.TextEditor) => { // Replace all variables in active editor with cat names and words const [model] = await vscode.lm.selectChatModels({ vendor: 'copilot', family: 'gpt-4o' }); let chatResponse: vscode.LanguageModelChatResponse | undefined; const text = textEditor.document.getText(); const messages = [ vscode.LanguageModelChatMessage.User(`You are a cat! Think carefully and step by step like a cat would. Your job is to replace all variable names in the following code with funny cat variable names. Be creative. IMPORTANT respond just with code. Do not use markdown!`), vscode.LanguageModelChatMessage.User(text) ]; try { chatResponse = await model.sendRequest(messages, {}, new vscode.CancellationTokenSource().token); } catch (err) { if (err instanceof vscode.LanguageModelError) { console.log(err.message, err.code, err.cause) } else { throw err; } return; } // Clear the editor content before inserting new content await textEditor.edit(edit => { const start = new vscode.Position(0, 0); const end = new vscode.Position(textEditor.document.lineCount - 1, textEditor.document.lineAt(textEditor.document.lineCount - 1).text.length); edit.delete(new vscode.Range(start, end)); }); try { // Stream the code into the editor as it is coming in from the Language Model for await (const fragment of chatResponse.text) { await textEditor.edit(edit => { const lastLine = textEditor.document.lineAt(textEditor.document.lineCount - 1); const position = new vscode.Position(lastLine.lineNumber, lastLine.text.length); edit.insert(position, fragment); }); } } catch (err) { // async response stream may fail, e.g network interruption or server side error await textEditor.edit(edit => { const lastLine = textEditor.document.lineAt(textEditor.document.lineCount - 1); const position = new vscode.Position(lastLine.lineNumber, lastLine.text.length); edit.insert(position, (<Error>err).message); }); } });这个示例同时演示了三个关键点:提示词中的"只回复代码、不要用 Markdown"指令约束输出格式;for await...of chatResponse.text异步迭代流式分片;以及发送请求与流式消费响应两处都必须分别做错误处理(后者常因网络中断或服务端错误失败)。
解析语言模型响应
发送请求后,必须处理语言模型 API 返回的响应。取决于使用场景,你可以把响应直接透传给用户,也可以解析响应并执行额外逻辑(例如上面的示例中把文本插入编辑器)。
LanguageModelChatResponse是**基于流(streaming)**的响应,这让你能提供平滑的用户体验——例如与 Chat API 结合时持续汇报结果与进度。流式处理过程中也可能出错(如网络连接问题),务必在代码中加入相应的错误处理。
流式响应的消费模式总结如下:
- 使用
for await (const fragment of chatResponse.text)逐片读取文本分片; - 分片通常很短(一个词甚至一个标点),所以累积拼接后再按业务规则切分(例如:等到出现完整 JSON 的收尾
}再解析); - 每个
textEditor.edit(...)都是一次编辑事务,需要基于文档当前末尾位置动态计算插入点; - 流式消费的
try/catch与发送请求的try/catch要分开写,因为失败时机与原因不同。
端到端实战:从提示词到编辑器注解
api/extension-guides/ai/language-model-tutorial.md 提供了一个完整的端到端实践:构建一个Code Tutor(代码导师)扩展,用 Language Model API 生成代码改进建议,并通过 VS Code 的 decoration(装饰)机制以内联注解形式展示在编辑器中,用户悬停即可查看完整建议。其实现链路可以归纳为四步,正好覆盖本指南的三个核心步骤:
- 获取带行号的代码:使用
registerTextEditorCommand拿到用户当前打开的TextEditor,再通过textEditor.visibleRanges[0]获取可视区域的首尾行,逐行拼出行号: 代码内容的文本串; - 发送代码与提示词:
selectChatModels({ vendor: 'copilot', family: 'gpt-4o' })选中模型,把一段精心构造的ANNOTATION_PROMPT(角色设定 + 输出格式约束 + few-shot 示例,要求模型以{ "line": 1, "suggestion": "..." }形式的 JSON 对象逐条输出建议)与带行号代码作为两条 User 消息一起发送; - 流式解析注解:在
parseChatResponse中累积流式分片,每当遇到}就尝试JSON.parse出完整注解并应用 decoration,未解析成功则静默跳过继续累积; - 以 decoration 展示:
createTextEditorDecorationType定义内联样式(灰色、截断到 25 字符),setDecorations把注解渲染到对应行末尾,完整建议通过hoverMessage在悬停时展示。
教程还在package.json的contributes中通过menus的editor/title分组把命令挂到编辑器标题栏(配合 图标规范 中的$(comment)图标),用户一键即可开关注解。这说明 Language Model API 与编辑器 UI 扩展能力可以无缝组合——AI 能力不再是"聊天框专属",而是可以深度嵌入开发者的日常编辑流。
使用注意事项
模型可用性
没有任何具体模型会被承诺"永久支持"。在扩展中引用语言模型时,请对请求采取防御式策略:优雅地处理"无法访问某个特定模型"的情况——例如模型下架、用户所在地区/账户不可用、未登录 GitHub Copilot 等,这些都可能导致selectChatModels返回空数组或sendRequest抛错。
选择合适的模型
扩展作者可以自行判断哪个模型最适合自己的扩展。官方推荐gpt-4o(性能与质量均衡)。要获取当前可用的完整模型列表,可用如下代码:
const allModels = await vscode.lm.selectChatModels(MODEL_SELECTOR);注意:推荐的 GPT-4o 模型有
64Ktoken 的上限。selectChatModels返回的模型对象带有maxInputTokens属性,可以直接读出该模型的 token 上限。这些上限会随着对扩展使用方式的了解而逐步放宽。
速率限制(Rate limiting)
扩展应负责任地使用语言模型并留意速率限制。VS Code 对用户保持透明:用户可以看到扩展正在如何使用语言模型、每个扩展发送了多少请求、这些请求如何影响各自的配额。另外,不要用 Language Model API 做集成测试——受速率限制影响,这类测试不稳定。VS Code 内部使用专用的非生产语言模型进行模拟测试,官方正在思考如何为扩展提供可扩展的语言模型测试方案。
测试你的扩展
Language Model API 的响应是非确定性的:完全相同的请求可能得到不同的响应,这给测试带来挑战。因此测试策略要区分对待:
- 可单元测试的部分:构建提示词、解析语言模型响应这两段逻辑是确定性的,可以在不调用真实语言模型的情况下进行单元测试;
- 不可轻易测试的部分:与语言模型本身的交互及响应获取是非确定性的,难以稳定测试。
官方建议把扩展代码设计成模块化结构,让"提示词构建 + 响应解析"与"模型调用"解耦,从而对确定性的部分充分做单元测试。例如 Code Tutor 教程中的getVisibleCodeWithLineNumbers、parseChatResponse、applyDecoration都是职责单一、便于单独测试的函数。
发布你的扩展
创建好 AI 扩展后,可以将其发布到 Visual Studio Marketplace。发布前请注意以下几点:
- 发布前建议阅读Microsoft AI 工具与实践准则(Microsoft AI tools and practices guidelines),它提供了负责任地开发与使用 AI 技术的最佳实践;
- 通过发布到 Marketplace,你的扩展即遵循GitHub Copilot 可扩展性可接受开发与使用政策(GitHub Copilot extensibility acceptable development and use policy);
- 如果你的扩展除了使用 Language Model API 之外还贡献了其他功能,不要在扩展清单中引入对 GitHub Copilot 的扩展依赖。这样,不使用 GitHub Copilot 的用户也能正常使用扩展中与语言模型无关的功能,而无须安装 GitHub Copilot——当然,访问语言模型的代码路径仍要做好相应的错误处理;
- 按 发布扩展 中描述的流程上传到 Marketplace。
相关文档
- Language Model API 参考(
lm命名空间、LanguageModelChat、LanguageModelChatResponse等类型定义) - 构建语言模型提示词(prompt-tsx)
- 构建 VS Code 聊天扩展(Chat Participant API)
- 教程:用 Language Model API 生成 AI 代码注解
- AI 可扩展性全景概览(语言模型、工具与聊天 API 的选型对比)
- 文档
- 教程
【免费下载链接】vscode-docs
Public documentation for Visual Studio Code
相关推荐
VS Code AI 扩展能力全指南:Language Model 工具、MCP 工具、Chat Participant 与 Language Model API 的选择与实现
VS Code AI 扩展能力全指南:Language Model 工具、MCP 工具、Chat Participant 与 Language Model AP
文档教程在 Roo Code 中使用 VS Code Language Model API:接入 GitHub Copilot 与其他扩展模型
在 Roo Code 中使用 VS Code Language Model API:接入 GitHub Copilot 与其他扩展模型 Roo Code 内置了
人工智能AI Agent代码智能体开发工具工具调用MCP ClientsVS Code 扩展实战:使用 GitHub Copilot Language Model API 构建 Code Tutor 行内代码注释扩展
VS Code 扩展实战:使用 GitHub Copilot Language Model API 构建 Code Tutor 行内代码注释扩展 本篇文章基于
示例工程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考