首页
/ VS Code Copilot Chat 扩展开发指南:环境搭建、TSX 提示词框架、分层架构与 Agent 模式源码级解析

VS Code Copilot Chat 扩展开发指南:环境搭建、TSX 提示词框架、分层架构与 Agent 模式源码级解析

2026-09-05 13:25:36作者:凌朦慧Richard

本文基于 GitHub Copilot Chat 扩展的官方贡献指南 CONTRIBUTING.md,系统讲解如何搭建 Copilot Chat 扩展的本地开发环境、编写与运行单元/集成/仿真三层测试、使用 TSX 提示词框架构建 LLM 请求,以及理解扩展的分层架构、运行时划分、Agent 模式与工具系统的源码组织方式。读完后你将具备在 VS Code 源码树内调试 Copilot Chat 扩展、修改其提示词与工具、并让其与 Code OSS 联动的完整实践能力。

一、创建高质量的 Issue

在动手开发前,贡献指南首先规范了问题反馈流程:

  • 先查已有 Issue:新建 Issue 前应先在 VS Code 的 open issues 中检索,确认问题或功能请求是否已存在;尤其要浏览标记为 feature-request 的高热请求。若已存在,用 reaction(👍 表示支持、👎 表示反对)代替 "+1" 评论。
  • 一个 Issue 只描述一个问题:不要在同一个 Issue 里罗列多个 bug 或功能请求;除非输入完全相同,也不要把自己的问题作为评论挂在别人的 Issue 下。
  • 使用内置报告工具:VS Code 帮助菜单中的 Report Issue 会自动附带 VS Code 版本、已安装扩展和系统信息,并搜索相似 Issue。

每个 Issue 应包含以下信息:

  • VS Code 与 copilot-chat 扩展的版本
  • 操作系统
  • 涉及的 LLM 模型(如适用)
  • 可复现的步骤(1... 2... 3...)
  • 期望结果与实际结果
  • 截图、动画或视频
  • 能演示问题的代码片段或提示词(注意:GIF 等媒体文件中的代码无法复制,需以文本形式提供),或一个开发者可直接拉取的代码仓库
  • Dev Tools 控制台错误(Help > Toggle Developer Tools 打开)

二、开发环境要求与首次搭建

环境要求

  • Node 22.x(当前仓库 package.jsonengines.node 声明为 >=22.14.0,两者一致)
  • Python >= 3.10 且 <= 3.12
  • Git Large File Storage(LFS)——运行测试需要
  • (Windows)Visual Studio Build Tools >= 2019 —— 用于 node-gyp 构建

首次搭建步骤

  1. Windows 上需以管理员身份在 PowerShell 执行 Set-ExecutionPolicy Unrestricted
  2. npm install
  3. npm run get_token(对应脚本 getToken.mts);
  4. 之后即可通过 Cmd+Shift+B(Windows 为 Ctrl+Shift+B)运行构建任务,或直接启动 "Launch Copilot Extension - Watch Mode" 调试配置。

提示:如果 "Launch Copilot Extension - Watch Mode" 不工作,可改用 "Launch Copilot Extension" 调试配置。说明:在 WSL 下按 VS Code 官方的 Selfhosting-on-Windows-WSL 文档流程同样支持。

三、三层测试体系:单元、集成与仿真

单元测试(Node 环境)

npm run test:unit

该脚本在 package.json 中定义为 vitest --run --pool=forks,即在 Node.js 中以 Vitest 运行。若测试报错,先确认 Node 版本正确且 git lfs 已安装(git lfs pull 可验证)。

集成测试(VS Code 内)

npm run test:extension

仿真测试(Simulation Tests)

仿真测试会真实访问 Copilot API 端点、调用 LLM,属于昂贵计算。为应对 LLM 的随机性,每条测试运行 10 次,所有运行结果快照保存在基线文件 baseline.json 中,它记录了测试套件在任一时点的"质量水位"。

由于 LLM 结果既随机又昂贵,仓库在 test/simulation/cache 目录中内置了缓存层,使重跑仿真测试更快且确定。相关命令:

npm run simulate                      # 运行仿真测试
npm run simulate-require-cache        # 校验缓存是否已生成
npm run simulate-update-baseline     # 接受本地新基线并更新 baseline 文件

贡献者注意:PR 在缓存未填充时会失败。npm run simulate 会在 test/simulation/cache/layers 中创建新的缓存层,但填充缓存必须由 VS Code 团队成员在其开发机上完成;社区成员若提交 PR 附带了新缓存层,PR 会失败,需由团队成员删除并在自己的机器上重建。此外,PR 中如有未提交的 baseline 变更同样会失败——若你本地看到测试结果变化并想接受新基线,运行 npm run simulate-update-baseline 并把该变更纳入提交。

四、复用 VS Code 仓库的 base/common 工具

Copilot Chat 团队希望沿用 microsoft/vscode 仓库中的 base/common 工具(如 async.tsstrings.tsmap.ts),而不是手动复制维护。为此提供了脚本 copySources.ts

  • 脚本末尾维护了一份从 vscode 仓库复制的模块清单;
  • 需要新模块时,将其加入清单并执行 npx tsx script/setup/copySources.ts
  • 前提是 copilot 仓库与 vscode 仓库为同级目录,脚本会把模块从 vscode 仓库复制到本仓库的 src/util/vs 目录(当前仓库中该目录已存在,见 src/util/vs);
  • src/util/vs 被标记为只读——对被复制源码的修改应回到 vscode 主仓库中完成。

五、TSX 提示词框架:把 Prompt 当组件写

这是本文最核心的技术部分。Copilot Chat 开发了一套基于 TSX 的提示词组合框架,解决两个问题:

动机

  1. 按 token 预算动态组合请求消息。普通字符串拼接出的 prompt 一旦组合完成就难以编辑;TSX 提示词把消息表示为组件树,每个节点带有 priority(概念上类似 zIndex,数值越大优先级越高)。当某个 intent 声明的消息超出 token 预算时,prompt 渲染器会从最终发送给 Copilot API 的 ChatMessage 数组中剪掉优先级最低的消息,并保持其余消息的声明顺序。这种树形结构也为未来更复杂的提示词管理(如提示词变体实验、子树递归摘要)留出了空间。
  2. 提示词对功能所有者透明且可复用。每个 intent 完整拥有并控制发给 Copilot API 的 SystemUserAssistant 消息,既保证了安全规则、上下文种类与会话历史的可见性,又便于复用 SafetyRules 等公共提示词片段。

快速上手

第一步:定义根 TSX 提示词组件,继承 PromptElement,实现同步的 render 方法返回要发送的聊天消息:

interface CatPromptProps extends BasePromptElementProps {
   query: string;
}

export class CatPrompt extends PromptElement<CatPromptProps, void> {
   render() {
      return (
         <>
            <SystemMessage>
               Respond to all messages as if you were a cat.
            </SystemMessage>
            <UserMessage>
               {this.props.query}
            </UserMessage>
         </>
      );
   }
}

第二步:用 PromptRenderer 渲染并接入 intent 调用PromptRenderer.render 产出适合经 ChatMLFetcher 发给 Copilot API 的 system/user/assistant 消息数组:

class CatIntentInvocation implements IIntentInvocation {
   constructor(private readonly accessor: ServicesAccessor, private readonly endpoint: IChatEndpoint, ) {}

   async buildPrompt({ query }: IBuildPromptContext, progress: vscode.Progress<vscode.ChatResponseProgressPart | vscode.ChatResponseReferencePart>, token: vscode.CancellationToken): Promise<RenderPromptResult> {
      // Render the `CatPrompt` prompt element
      const renderer = new PromptRenderer(this.accessor, this.endpoint, CatPrompt, { query });

      return renderer.render(progress, token);
   }
}

常用组件

  • SystemMessageUserMessageAssistantMessage:内部文本会被转换为 OpenAI API 对应的消息类型;
  • SafetyRules:通常应包含在 SystemMessage 中,确保功能符合 Responsible AI 规范;
  • 提示词组件可以返回其他提示词组件,全部由渲染器递归渲染。

异步预计算:若提示词需要异步工作(如 VS Code 扩展 API 调用、额外的 chunk 重排序请求),可在可选的异步 prepare 方法中预计算状态;prepare 先于 render 执行,准备好的状态会传回同步的 render 方法。

两条渲染规则要注意

  • 字符串字面量中的换行符渲染时不会被保留,必须显式用内置 <br /> 声明;
  • 当两条同优先级的提示词消息因超出 token 预算而面临驱逐时,先声明者不能驱逐后声明者声明的提示词消息子树。

六、代码结构:分层、目录与运行时

分层(Layers)

"层"指由可用环境 API 定义的运行时目标,与 VS Code 主仓库一致:

可用能力 可依赖的层
common 纯 JavaScript 及内置 API;可用 VS Code API 的类型但不运行时访问
vscode VS Code API 运行时访问 common
node Node.js API 与模块 commonnode
vscode-node VS Code + Node.js API commonvscodenode
worker Web Worker API common
vscode-worker VS Code + Web Worker API commonvscodeworker

顶层目录约定

  • src/util:跨模块通用工具代码。该目录下的文件可被 VS Code 外部运行的测试加载,应从 vscodeTypes 模块导入基础类型(测试环境会 shim 掉它),且不能导入 ./platform./extension
  • src/platform:用于实现扩展的服务(遥测、配置、搜索等),可导入 ./util
  • src/extension:所有功能实现的大文件夹,可导入 ./util./platform
  • test:测试代码可导入 base/ 但不能导入 extension/

双运行时:node.js 与 web worker

Copilot Chat 同时支持 node.js 扩展宿主与 web worker 扩展宿主,既能跑在桌面端,也能跑在无远端连接的 Web 环境("serverless")。因此构建两个形态的扩展,当前仓库中两个入口均已存在:

原则上应让同一份代码在两种宿主中运行;运行时特化代码应是例外。以下用法不受 web worker 宿主支持

  • 直接使用 node.js API(如 requireprocess.envfs);
  • 使用未构建为 web 版本的 node 模块;
  • 依赖 web 上不支持的其他扩展(例如 vscode.Git 扩展)。

从源码运行扩展

  • node:直接使用 "Launch Copilot Extension" 启动配置;
  • web
    1. 确保 package.json 中有入口 "browser": "./dist/web"
    2. 运行 npm run web(对应 vscode-test-web --headless --extensionDevelopmentPath=. .);
    3. 浏览器打开 http://localhost:3000
    4. 在 VS Code 中将隐藏设置 chat.experimental.serverlessWebEnabled 设为 true(首次设置后需重载)。

Contributions 与 Services

与 VS Code 一样,Copilot 扩展通过 contributions 与 services 让组件相互隔离又协同提供/消费服务。注册文件按运行时划分(当前仓库中以下文件均存在):

  • vscode/contributions.ts:两种宿主均可运行的 contributions;
  • vscode-node/contributions.ts:仅 node.js 宿主;
  • vscode-worker/contributions.ts:仅 web worker 宿主;
  • vscode/services.tsvscode-node/services.tsvscode-worker/services.ts:同样按宿主划分的 services,由主 instantiation service 自动装配。

建议尽量把 services 与 contributions 放在 vscode 层,使其在所有受支持运行时中可用。

七、Agent 模式的关键源码

贡献指南列出了 Agent 模式最相关的文件(路径已按仓库根目录给出):

  • agentPrompt.tsx:渲染 agent 提示词的主入口。从源码结构看,该目录还包含 promptRegistry.ts 与针对不同模型的提示词变体(如 anthropicPrompts.tsxgeminiPrompts.tsxopenai/ 等),印证了"按模型定制 agent 提示词"的实现方式;
  • defaultAgentInstructions.tsx:agent 模式的系统提示词(原文档链接的 agentInstructions.tsx 在当前源码树中对应此文件);
  • toolCallingLoop.ts:驱动 agentic loop(工具调用循环);
  • chatParticipants.ts:注册 agent 模式及其他 chat participants,以及来自 VS Code 的请求处理器。

从源码结构看,agent 模式本质上是一个注册给 VS Code 的 chat participant:主要使用标准 Chat API 加 vscode.lm.invokeTool 调用工具,并在 package.json 中以标志位声明自己为 "agent mode" participant;另有一些能力来自 VS Code 的 proposed API。

注意:代码库中部分 "agent" 一词可能指旧的 chat participants(@workspace@vscode 等),或经由 GitHub App 安装的 Copilot Extension agents,阅读时要区分语境。

八、工具(Tools)系统

Copilot 注册了多种工具;工具也可来自其他 VS Code 扩展或注册到 VS Code 的 MCP 服务器。VS Code 的工具选择器(tool picker)主要决定哪些工具被启用,该集合随 ChatRequest 传给 agent;部分编辑工具只对特定模型或基于配置/实验启用。agent 对最终请求中实际包含哪些工具拥有最终决定权,相关逻辑位于 agentIntent.tsgetTools 中。

开发新工具的关键位置

工具通过 VS Code 标准的 Language Model Tool API 注册。内建工具的关键部分:

  • package.json:工具描述与 JSON Schema 在此声明;
  • toolNames.ts:面向模型的工具名;
  • src/extension/tools/node/:工具实现所在目录。多数实现标准的 vscode.LanguageModelTool 接口;因部分工具有额外自定义行为,它们实现的是扩展接口 ICopilotTool

在新增工具之前,务必先阅读工具开发说明文档 docs/tools.md

Tree Sitter

Tree Sitter 的 WASM 预编译产物现已迁移至 microsoft/vscode-tree-sitter-wasm 项目维护,仓库内不再自行构建 WASM。

九、排障:阅读请求

要查看 Copilot Chat 发出的请求细节,执行命令 "Show Chat Debug View":会显示一个树视图,每个请求一条目,可看到发给模型的 prompt、启用的工具、响应及其他关键信息。

  • 修改任何逻辑后务必先读一遍渲染出的 prompt,确认其渲染结果符合预期;
  • 右键 > "Export As..." 可导出请求日志;
  • 视图还会为单独的 tool call 建立条目,并提供在 Simple Browser 中打开的 prompt-tsx 调试视图;
  • 该日志对排查 agent 行为问题非常有帮助,提 Issue 时附上会很受欢迎。但日志可能包含文件内容、终端输出等个人信息,分享前务必审查内容

十、Proposed API 更新与 engines.vscode 日期规范

当扩展使用的 VS Code proposed extension API 发生变更时,package.json 中的 engines.vscode 字段用于保证安装的扩展版本与 VS Code 版本兼容。当前仓库 package.json 中为 "vscode": "^1.137.0"(稳定版约束);一旦采用任何 proposed API 变更(无论是否向后兼容),都必须把该字段更新为带日期的形式,例如 "vscode": "^1.91.0-20240624"——这确保扩展只会在支持新 API 的 VS Code 版本中安装并激活。

必须与 VS Code 主仓库同步落地 API 变更:扩展侧的 API 采用必须与 VS Code 侧的变更同时完成,否则次日的 Insiders 构建将没有兼容的 Copilot Chat 扩展可用。

典型的 API 变更示例:

  • 重命名扩展使用的方法;
  • 修改已有方法的参数;
  • ChatResponseStream 新增响应类型;
  • 新增一个 API proposal;
  • 在已有接口上新增方法。

十一、与 Code OSS 联动运行

桌面端

在 Code OSS Desktop 中运行该扩展,只需三步:

  1. vscode 仓库顶层创建 product.overrides.json
  2. 写入以下 JSON 内容:
{
   "trustedExtensionAuthAccess": {
      "github": [
         "github.copilot-chat"
      ]
   }
}
  1. 在 Code OSS 中运行扩展启动配置。

Web 端

Code OSS for Web 不支持 product.overrides.json 技巧,需要手动把 defaultChatAgent 属性的内容复制进 src/vs/platform/product/common/product.ts(即 VS Code 主仓库 product.ts 中的 Object.assign(product, {...}) 块),并附带 trustedExtensionAuthAccess 配置。完整示例:

Object.assign(product, {
		version: '1.102.0-dev',
		nameShort: 'Code - OSS Dev',
		nameLong: 'Code - OSS Dev',
		applicationName: 'code-oss',
		dataFolderName: '.vscode-oss',
		urlProtocol: 'code-oss',
		reportIssueUrl: 'https://github.com/microsoft/vscode/issues/new',
		licenseName: 'MIT',
		licenseUrl: 'https://github.com/microsoft/vscode/blob/main/LICENSE.txt',
		serverLicenseUrl: 'https://github.com/microsoft/vscode/blob/main/LICENSE.txt',
		defaultChatAgent: {
			'extensionId': 'GitHub.copilot',
			'chatExtensionId': 'GitHub.copilot-chat',
			'documentationUrl': 'https://aka.ms/github-copilot-overview',
			'termsStatementUrl': 'https://aka.ms/github-copilot-terms-statement',
			'privacyStatementUrl': 'https://aka.ms/github-copilot-privacy-statement',
			'skusDocumentationUrl': 'https://aka.ms/github-copilot-plans',
			'publicCodeMatchesUrl': 'https://aka.ms/github-copilot-match-public-code',
			'manageSettingsUrl': 'https://aka.ms/github-copilot-settings',
			'managePlanUrl': 'https://aka.ms/github-copilot-manage-plan',
			'manageOverageUrl': 'https://aka.ms/github-copilot-manage-overage',
			'upgradePlanUrl': 'https://aka.ms/github-copilot-upgrade-plan',
			'signUpUrl': 'https://aka.ms/github-sign-up',
			'provider': {
				'default': {
					'id': 'github',
					'name': 'GitHub'
				},
				'enterprise': {
					'id': 'github-enterprise',
					'name': 'GHE.com'
				},
				'google': {
					'id': 'google',
					'name': 'Google'
				},
				'apple': {
					'id': 'apple',
					'name': 'Apple'
				}
			},
			'providerUriSetting': 'github-enterprise.uri',
			'providerScopes': [
				[
					'user:email'
				],
				[
					'read:user'
				],
				[
					'read:user',
					'user:email',
					'repo',
					'workflow'
				]
			],
			'entitlementUrl': 'https://api.github.com/copilot_internal/user',
			'entitlementSignupLimitedUrl': 'https://api.github.com/copilot_internal/subscribe_limited_user',
			'chatQuotaExceededContext': 'github.copilot.chat.quotaExceeded',
			'completionsQuotaExceededContext': 'github.copilot.completions.quotaExceeded',
			'walkthroughCommand': 'github.copilot.open.walkthrough',
			'completionsMenuCommand': 'github.copilot.toggleStatusMenu',
			'chatRefreshTokenCommand': 'github.copilot.refreshToken',
			'completionsAdvancedSetting': 'github.copilot.advanced',
			'completionsEnablementSetting': 'github.copilot.enable',
			'nextEditSuggestionsSetting': 'github.copilot.nextEditSuggestions.enabled'
		},
		trustedExtensionAuthAccess: {
			'github': [
				'github.copilot-chat'
			]
		}
});

其中 providerScopes 声明了 OAuth 权限范围的分级(仅 email、读用户信息、完整 repo/workflow 权限),entitlementUrl 用于查询用户 Copilot 权益,各 *Url 字段指向管理计划、升级、签名等入口——理解这些字段有助于排查 Code OSS 中 Copilot 登录与配额显示异常的问题。

十二、小结:贡献者工作流速查

目标 命令 / 文件
安装并获取 token npm installnpm run get_token
本地调试(node 宿主) "Launch Copilot Extension" 启动配置
本地调试(web 宿主) npm run web + 隐藏设置 chat.experimental.serverlessWebEnabled
单元 / 集成 / 仿真测试 npm run test:unit / npm run test:extension / npm run simulate
同步 vscode 工具源码 npx tsx script/setup/copySources.ts
调试渲染出的 prompt 命令 "Show Chat Debug View"
新增工具 package.json 声明 schema + tools/node 实现 + 先读 docs/tools.md

以上流程与路径均与当前仓库的实际目录结构(extensions/copilot 下的 src/extensiontest/simulationscript/setup 等)一致,可直接据此在当前仓库内定位、阅读并验证每一处实现。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
588
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
906
1.83 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
891
5.79 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.53 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.34 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
988
506
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384