VSCode插件开发九:扩展中接入Copilot AI

自从 AI 大模型在编程中普及以来,我已经很少写技术文章了。有时候突然想写点什么,但转念一想,这些问题问一下 AI 不就解决了吗?于是写作的动力又消失了。不过最近收到一些朋友的反馈,说读了我的文章后得到了帮助,这让我觉得写文章还是有价值的。恰好最近我在更新Dodo Reader插件------这个插件自 2013 年以来从未更新,慢慢积累下来也有将近 3k 下载量了。我在想,如果阅读时能有 AI 辅助,会不会让体验更好?于是,我决定给这个项目集成 Copilot AI。Copilot 在编程中确实很有帮助,但有一些更智能、更个性化的功能,可能还是需要通过扩展来完成,比如对文件的高级处理,而且我相信一些朋友可能还有更多的奇思妙想。

那么接下来就来看看怎么接入 Copilot AI。VSCode 主要提供了两种接入方式:一是聊天参与者,通过 Copilot AI 增加聊天角色;另一个是通过 API 集成到自己的界面。此外,官方提到的语言模型工具,个人理解其实是对这两种方式的扩展。

聊天参与者

聊天参与者就是集成到 Copilot 的聊天界面的,通过@来调用,如图:

  1. 注册参与者,就是告诉 VSCode 我要注册一个什么名称、用来干什么的角色。这个需要在package.json添加:
json 复制代码
{
  "contributes": {
    "chatParticipants": [
      {
        "id": "chat-ai.dodo-reader",
        "fullName": "Dodo Reader",
        "name": "dodo-reader",
        "description": "我是一个EPUB文件阅读助手,你有什么可以问我哦~",
        "isSticky": true,
        "commands": [
          {
            "name": "translate",
            "description": "输入你要翻译的目标语言"
          },
          {
            "name": "summarize",
            "description": "总结这段文本"
          }
        ]
      }
    ]
  }
}
  1. 创建参与者,通过参与者id去创建:
js 复制代码
export function activate(context: vscode.ExtensionContext) {
  // handler 是对请求的处理
  const tutor = vscode.chat.createChatParticipant('chat-ai.dodo-reader', handler)

  // 定义角色的头像
  tutor.iconPath = vscode.Uri.joinPath(context.extensionUri, 'dist/web/logo.png')
}
  1. 处理请求并响应,handler中你能够接收到用户输入内容和指令:
js 复制代码
const handler: vscode.ChatRequestHandler = async (
  request: vscode.ChatRequest,
  context: vscode.ChatContext,
  stream: vscode.ChatResponseStream,
  token: vscode.CancellationToken
): Promise<ICatChatResult> => {
  if (request.command === 'translate') {
    // translate 指令处理
    return
  }
  if (request.command === 'summarize') {
    // summarize 指令处理
    return
  }

  // 给模型发起请求
  const chatResponse = await request.model.sendRequest(
    [vscode.LanguageModelChatMessage.User(request.prompt)],
    {},
    token
  )
  // text 是一个异步迭代器
  for await (const fragment of chatResponse.text) {
    // 通过 stream.markdown 给聊天输出内容
    stream.markdown(fragment)
  }
}

stream.markdown可以将模型返回的 markdown 内容输出,其实这只是一种形式,另外还有其他类型:

js 复制代码
stream.button // 发送按钮,可以调用扩展命令
stream.filetree // 发送文件树
stream.progress // 发送进度消息
stream.reference // 发送引用
stream.anchor // 发送内联引用

如果你想要联系上下文进行聊天,还需要把历史记录一起发送,通过context.history组合新的消息数组,然后再发起请求:

js 复制代码
const messages = []
context.history.forEach((h) => {
  if (h instanceof vscode.ChatRequestTurn) {
    messages.push(vscode.LanguageModelChatMessage.User(h.prompt))
  } else if (h instanceof vscode.ChatResponseTurn) {
    let fullMessage = ''
    h.response.forEach((r) => {
      const mdPart = r as vscode.ChatResponseMarkdownPart
      fullMessage += mdPart.value.value
    })
    messages.push(vscode.LanguageModelChatMessage.Assistant(fullMessage))
  }
})

messages.push(vscode.LanguageModelChatMessage.User(request.prompt))

模型 API

可能你并不需要 Copilot 聊天界面,你有自己的 webview 界面希望输出模型的聊天结果,或者直接输出到编辑器里面,这时候模型 API 就能派上用场。

你可以列举所有的内置模型:

js 复制代码
const models = await vscode.lm.selectChatModels({
  vendor: 'copilot',
})

接下来,假设你有个 webview 界面,接收到 webview 发来的消息,你需要进行模型请求:

js 复制代码
const panel = vscode.window.createWebviewPanel(/* webview 参数 */)
panel.webview.html = 'HTML内容'

panel.webview.onDidReceiveMessage(async (message) => {
  if (message.command === 'chat') {
    // 接收到 webview 请求,发起模型请求
    const [model] = await vscode.lm.selectChatModels({ vendor: 'copilot', family: 'gpt-4o' })
    // 使用 gpt-4o 进行请求发送
    const request = await model.sendRequest(
      vscode.LanguageModelChatMessage.User(message.text),
      {},
      new vscode.CancellationTokenSource().token
    )
    for await (const fragment of chatResponse.text) {
      // 处理请求结果
      console.log(fragment)
    }
  }
})

示例很简单,请求的方法sendRequest其实跟前面是一样的,只是获取模型的方式不同:前面是回调传递过来的 Copilot 选中模型,这里是主动设置的模型。在实际开发中,你可以创建一个设置界面让用户自行选择模型。

最后,本文只是讲解如何调用模型,关于创建命令、创建webview等其他内容,你可以回顾我之前的文章查看详细说明。

相关推荐
tech_zjf17 分钟前
当 AI 把 Next.js Route 越写越快:我为什么做了 next-route-kit
前端·后端
常宇佳20 分钟前
vue3 @代指src路径设置
前端·typescript·vue
砚凝霜36 分钟前
软考网络工程师|案例分析:Eth‑Trunk 链路聚合、iStack 堆叠、CSS 集群核心考点总结
前端·css·网络
二级小助手1 小时前
二级Web前端选择题高频真题20道与考场避坑笔记
javascript·css3·html5·web前端·计算机二级·二级web·web真题
珐恩AI-人工智能1 小时前
大模型意图召回偏差分析:GEO如何解决“有收录却不触发问答曝光”的难题
大数据·前端·人工智能·html·流量运营·geo优化
程序员老赵1 小时前
Docker 部署禅道 ZenTao:轻松搭建研发项目管理平台
前端·后端·github
前端小卡拉1 小时前
用了大半年 AI 编程工具,我才搞懂 Skill 到底是什么
前端·javascript
hunterandroid1 小时前
[鸿蒙从零到一] HarmonyOS 单元测试与 UI 自动化测试实战:从代码质量到用户体验的全链路保障
前端
郭邯1 小时前
用 Intl.DateTimeFormat 手写一个时区转换器,顺便聊聊我和 AI 结对编程的日常
前端·javascript
阿奇__2 小时前
微前端、iframe与Auth Code技术方案对比
前端