目录

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等其他内容,你可以回顾我之前的文章查看详细说明。

本文是转载文章,点击查看原文
如有侵权,请联系 xyy@jishuzhan.net 删除
相关推荐
旭久15 分钟前
react+antd封装一个可回车自定义option的select并且与某些内容相互禁用
前端·javascript·react.js
是纽扣也是烤奶20 分钟前
关于React Redux
前端
阿丽塔~22 分钟前
React 函数组件间怎么进行通信?
前端·javascript·react.js
冴羽1 小时前
SvelteKit 最新中文文档教程(17)—— 仅服务端模块和快照
前端·javascript·svelte
uhakadotcom1 小时前
Langflow:打造AI应用的强大工具
前端·面试·github
前端小张同学1 小时前
AI编程-cursor无限使用, 还有谁不会🎁🎁🎁??
前端·cursor
yanxy5121 小时前
【TS学习】(15)分布式条件特性
前端·学习·typescript
uhakadotcom1 小时前
Caddy Web服务器初体验:简洁高效的现代选择
前端·面试·github
前端菜鸟来报道2 小时前
前端react 实现分段进度条
前端·javascript·react.js·进度条