VS Code 扩展开发:集成 GitHub Copilot 的完整指南

引言

2024年6月,VS Code 团队发布了重要更新,允许扩展开发者直接使用 GitHub Copilot 的能力。这意味着你可以在自己的扩展中集成 AI 对话、代码生成等功能,无需从零搭建 AI 基础设施。

官方资料来源:


一、两种集成方式

1.1 Chat Participant API

适用场景: 需要在 Copilot Chat 面板中添加自定义命令

核心概念:

  • Chat Participant - 在聊天界面中注册一个 @your-extension 参与者
  • Slash Commands - 支持 /command 形式的子命令
  • Follow-ups - 可以返回建议的后续问题

基础示例:

typescript 复制代码
import * as vscode from 'vscode';

export function activate(context: vscode.ExtensionContext) {
  // 注册 Chat Participant
  const participant = vscode.chat.createChatParticipant(
    'myextension.helper',
    async (request, context, stream, token) => {
      // 处理用户输入
      const userMessage = request.prompt;
      
      // 返回响应
      stream.markdown(`你问了: ${userMessage}\n\n`);
      stream.markdown('这是我的回答...');
      
      // 返回建议的后续问题
      return {
        followUp: [
          { prompt: '告诉我更多细节', label: '📖 详细说明' },
          { prompt: '给我一个例子', label: '💡 示例代码' }
        ]
      };
    }
  );

  context.subscriptions.push(participant);
}

使用方式:

用户在 Copilot Chat 中输入 @myextension 你的问题


1.2 Language Model API

适用场景: 需要在扩展内部调用 AI 模型(不显示在 Chat 面板)

核心能力:

  • 直接调用 GPT-4 / GPT-3.5 等模型
  • 支持流式响应
  • 可以传递上下文(代码、文件内容等)

基础示例:

typescript 复制代码
import * as vscode from 'vscode';

async function generateCode(prompt: string) {
  // 获取可用的语言模型
  const models = await vscode.lm.selectChatModels({
    vendor: 'copilot',
    family: 'gpt-4'
  });

  if (models.length === 0) {
    throw new Error('No Copilot model available');
  }

  const model = models[0];

  // 构建消息
  const messages = [
    vscode.LanguageModelChatMessage.User(prompt)
  ];

  // 发送请求
  const response = await model.sendRequest(messages, {}, new vscode.CancellationTokenSource().token);

  // 处理流式响应
  let fullText = '';
  for await (const chunk of response.text) {
    fullText += chunk;
  }

  return fullText;
}

二、实战案例:代码审查助手

结合两种 API,实现一个智能代码审查扩展:

2.1 注册 Chat Participant

typescript 复制代码
const reviewer = vscode.chat.createChatParticipant(
  'codereview.assistant',
  async (request, context, stream, token) => {
    const command = request.command; // 获取 slash command

    if (command === 'review') {
      await reviewCurrentFile(stream, token);
    } else if (command === 'explain') {
      await explainSelection(stream, token);
    } else {
      stream.markdown('支持的命令:\n- `/review` - 审查当前文件\n- `/explain` - 解释选中代码');
    }
  }
);

// 注册 slash commands
reviewer.iconPath = vscode.Uri.file(path.join(context.extensionPath, 'icon.png'));
reviewer.followupProvider = {
  provideFollowups(result, context, token) {
    return [
      { prompt: '修复这些问题', label: '🔧 自动修复' },
      { prompt: '解释第一个问题', label: '❓ 详细说明' }
    ];
  }
};

2.2 调用 Language Model 进行审查

typescript 复制代码
async function reviewCurrentFile(stream: vscode.ChatResponseStream, token: vscode.CancellationToken) {
  const editor = vscode.window.activeTextEditor;
  if (!editor) {
    stream.markdown('❌ 请先打开一个文件');
    return;
  }

  const code = editor.document.getText();
  const language = editor.document.languageId;

  stream.progress('正在分析代码...');

  // 调用 Language Model
  const models = await vscode.lm.selectChatModels({ vendor: 'copilot' });
  const model = models[0];

  const messages = [
    vscode.LanguageModelChatMessage.User(
      `请审查以下 ${language} 代码,指出潜在问题:\n\n\`\`\`${language}\n${code}\n\`\`\``
    )
  ];

  const response = await model.sendRequest(messages, {}, token);

  // 流式输出结果
  stream.markdown('## 审查结果\n\n');
  for await (const chunk of response.text) {
    stream.markdown(chunk);
  }
}

三、最佳实践

3.1 权限和依赖

package.json 中声明:

json 复制代码
{
  "enabledApiProposals": [
    "chatParticipant",
    "languageModels"
  ],
  "contributes": {
    "chatParticipants": [
      {
        "id": "codereview.assistant",
        "name": "Code Reviewer",
        "description": "智能代码审查助手",
        "commands": [
          {
            "name": "review",
            "description": "审查当前文件"
          },
          {
            "name": "explain",
            "description": "解释选中代码"
          }
        ]
      }
    ]
  }
}

3.2 错误处理

typescript 复制代码
try {
  const models = await vscode.lm.selectChatModels({ vendor: 'copilot' });
  if (models.length === 0) {
    stream.markdown('⚠️ 未检测到 GitHub Copilot,请先安装并登录');
    return;
  }
  // ... 调用模型
} catch (error) {
  if (error instanceof vscode.LanguageModelError) {
    stream.markdown(`❌ AI 调用失败: ${error.message}`);
  }
}

3.3 上下文管理

利用 ChatContext 获取对话历史:

typescript 复制代码
async (request, context, stream, token) => {
  // 获取之前的对话
  const history = context.history;
  
  const messages = history.map(msg => {
    if (msg instanceof vscode.ChatRequestTurn) {
      return vscode.LanguageModelChatMessage.User(msg.prompt);
    } else {
      return vscode.LanguageModelChatMessage.Assistant(msg.response.markdown);
    }
  });

  // 添加当前问题
  messages.push(vscode.LanguageModelChatMessage.User(request.prompt));

  // 发送给模型
  const response = await model.sendRequest(messages, {}, token);
}

四、进阶技巧

4.1 工具调用(Tool/Function Calling)

typescript 复制代码
const tools: vscode.LanguageModelChatTool[] = [
  {
    name: 'searchCode',
    description: '在工作区中搜索代码',
    inputSchema: {
      type: 'object',
      properties: {
        query: { type: 'string', description: '搜索关键词' }
      }
    }
  }
];

const response = await model.sendRequest(messages, { tools }, token);

// 处理工具调用
for await (const part of response.stream) {
  if (part instanceof vscode.LanguageModelToolCallPart) {
    const result = await executeToolCall(part.name, part.input);
    // 将结果返回给模型继续对话
  }
}

4.2 自定义模型选择

typescript 复制代码
// 优先使用 GPT-4,降级到 GPT-3.5
const models = await vscode.lm.selectChatModels({
  vendor: 'copilot',
  family: 'gpt-4'
});

const model = models[0] || (await vscode.lm.selectChatModels({
  vendor: 'copilot',
  family: 'gpt-3.5-turbo'
}))[0];

五、调试和测试

5.1 本地测试

  1. F5 启动扩展开发主机
  2. 在新窗口中打开 Copilot Chat
  3. 输入 @your-extension 测试

5.2 日志输出

typescript 复制代码
const outputChannel = vscode.window.createOutputChannel('My Extension');

outputChannel.appendLine(`User prompt: ${request.prompt}`);
outputChannel.appendLine(`Model response: ${fullText}`);

六、发布和分发

6.1 发布到 Marketplace

bash 复制代码
# 安装 vsce
npm install -g @vscode/vsce

# 打包
vsce package

# 发布
vsce publish

6.2 注意事项

  • 扩展需要用户安装 GitHub Copilot 才能使用
  • 在 README 中明确说明依赖关系
  • 提供降级方案(如果 Copilot 不可用)

总结

VS Code 的 Chat 和 Language Model API 让扩展开发者能够轻松集成 AI 能力:

  • Chat Participant 适合面向用户的对话式交互
  • Language Model API 适合后台的 AI 处理
  • 两者可以结合使用,打造强大的智能扩展

参考资料:


相关推荐
此生只爱蛋2 小时前
【vscode环境配置心得】C++版
c++·ide·vscode
技术程序猿华锋3 小时前
OpenAI GPT Image 2 教程:API Key 获取、参数说明与 Python/Node.js 示例
python·gpt·node.js·ai绘画
xinhuanjieyi5 小时前
windows安装vscode服务端
ide·windows·vscode
开开心心就好5 小时前
解决打印机共享难题的实用工具
人工智能·vscode·游戏·macos·音视频·语音识别·媒体
米丘6 小时前
vue3.x 编译 script setup 编译过程
vue.js·node.js·babel
心之所向,自强不息7 小时前
VSCode + EmmyLua 调试 Unity Lua(最简接入 + 不阻塞运行版)
vscode·unity·lua
网络点点滴7 小时前
Node.js从URL中解析变量
node.js
石油人单挑所有7 小时前
基于多设计模式下的同步&异步日志系统测试报告
服务器·c++·vscode·设计模式
乐飞鱼~万维网7 小时前
vscode 调试xdebug 配置问题
ide·vscode·编辑器