从零开发一款ChatGPT VSCode插件

这篇具有很好参考价值的文章主要介绍了从零开发一款ChatGPT VSCode插件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

‍本文作者是360奇舞团开发工程师

引言

OpenAI发布了ChatGPT,就像是给平静许久的互联网湖面上扔了一颗重磅炸弹,刹那间所有人都在追捧学习它。究其原因,它其实是一款真正意义上的人工智能对话机器人。它使用了深度学习技术,通过大量的训练数据和自监督学习方法进行训练,以模拟人类的对话能力和生成自然语言回应。日常生产、学习中利用好ChatGPT这个工具,是绝对能够提升我们工作效率的,这一点对于我们程序员来说,感受应该尤为明显。我们最常用的开发工具VSCode,已经有许多的插件集成了ChatGPT功能,这篇文章将从零开始,介绍这些插件的实现原理与思路,希望对你有所帮助。

基本需求

实现一款可以跟ChatGPT对话的插件,可以通过一问一答的形式来进行对话,并且可以将我们选中的代码发送给ChatGPT,让其可以对代码进行优化。当然如果要访问ChatGPT,首先需要绑定我们在OpenAI后台申请的ApiKey.

VSCode 插件基本配置

首先简单介绍一下VSCode插件开发的基本流程

  1. 安装脚手架

npm install -g yo generator-code

然后cd到你的工作目录,运行yo code,根据向导一步步选择即可,没啥好说的,运行完后就生成了一个干净的可以运行的插件工程了。
2. 工程目录介绍
从零开发一款ChatGPT VSCode插件,chatgpt,vscode,ide,编辑器
查看当前目录,工程的核心是package.jsonextension.js.首先看下package.json的配置文件:

  • name:工程名称

  • displayName: 应用市场名称

  • description: 应用描述

  • version: 当前插件版本

  • engines: 表示插件最低支持的vscode版本

  • categories: 插件应用市场分类

  • main: 程序的主入口文件

  • activationEvents:重要,扩展的激活事件数组,表示可以被哪些事件激活当前插件。比如:

"activationEvents": [
    "onView:chatgpt-for-vscode.view",
    "onCommand:chatgpt-for-vscode.setAPIKey",
    "onCommand:chatgpt-for-vscode.askGPT",
    "onCommand:chatgpt-for-vscode.whyBroken",
    "onCommand:chatgpt-for-vscode.optimizeCode",
    "onCommand:chatgpt-for-vscode.explainCode",
    "onCommand:chatgpt-for-vscode.refactor"
  ],

onView:表示 通过视图触发,chatgpt-for-vscode.view是视图Id。当触发这个视图时,唤起当前插件
onCommand: 表示通过命令触发,后面是命令Id,这些都是我们自定义的命令。在VSCode中按下快捷键:Command + Shift + P 输入命令title后唤起插件,命令titlecontributes,commands模块里面定义,后面介绍。
除了这两个还有:onLanguageonUrionDebugworkspaceContainsonFileSystem等,如果设置为*,只要一启动VSCode,插件就会被激活,当然为了用户体验,官方不推荐这么做。

  • contributes重要,配置插件的主要功能点。比如:

"contributes": {
    "commands": [
      {
        "command": "chatgpt-for-vscode.setAPIKey",
        "title": "GPT:绑定APIKey"
      },
      {
        "command": "chatgpt-for-vscode.askGPT",
        "title": "GPT:询问 GPT"
      },
      {
        "command": "chatgpt-for-vscode.whyBroken",
        "title": "GPT:说明这段代码存在的问题"
      },
      {
        "command": "chatgpt-for-vscode.optimizeCode",
        "title": "GPT:优化这段代码"
      },
      {
        "command": "chatgpt-for-vscode.explainCode",
        "title": "GPT:解释这段代码"
      },
      {
        "command": "chatgpt-for-vscode.refactor",
        "title": "GPT:重构这段代码"
      }
    ],
    "menus": {
      "editor/context": [
        {
          "command": "chatgpt-for-vscode.askGPT",
          "group": "navigation@1"
        },
        {
          "command": "chatgpt-for-vscode.whyBroken",
          "group": "navigation@2"
        },
        {
          "command": "chatgpt-for-vscode.optimizeCode",
          "group": "navigation@3"
        },
        {
          "command": "chatgpt-for-vscode.explainCode",
          "group": "navigation@4"
        },
        {
          "command": "chatgpt-for-vscode.refactor",
          "group": "navigation@5"
        },
        {
          "command": "chatgpt-for-vscode.setAPIKey",
          "group": "navigation@6"
        }
      ]
    },
    "viewsContainers": {
      "activitybar": [
        {
          "id": "chatgpt-for-vscode",
          "title": "ChatGPT",
          "icon": "images/ChatGPT.png"
        }
      ]
    },
    "views": {
      "chatgpt-for-vscode": [
        {
          "type": "webview",
          "id": "chatgpt-for-vscode.view",
          "name": "ChatGPT"
        }
      ]
    }
  },
  • commands: command: 命令Id,这个命令Id跟activationEvents中配置的命令Id相同。title:输入的命令的名称。Command + Shift + P 输入这个命令title后找到对应的命令。
    从零开发一款ChatGPT VSCode插件,chatgpt,vscode,ide,编辑器

  • menus: editor/context:配置编辑器右键展示内容。command是命令Id,group:右键后展示看板的命令位置。这里navigation表示展示在模块的顶部。@*表示排序。
    从零开发一款ChatGPT VSCode插件,chatgpt,vscode,ide,编辑器

  • viewsContainersactivitybar:配置右侧工具栏视图入口,配置后展示,注意这里的id,要跟后面的
    views模块里面的视图key值保持一致,表示点击右侧icon后展示那个视图,icon是你本地的图片路径。
    从零开发一款ChatGPT VSCode插件,chatgpt,vscode,ide,编辑器

  • views: 配置视图,这里使用webview展示自定义视图

  1. 配置完成package.json后右键命令展示,左侧状态栏Icon,顶部命令行选择输入命令,已经可以展示了。运行npm run test 后会打开默认安装你插件的VSCode面板,接下来就是完善触发命令后的代码逻辑了,核心在extension.ts中实现。

extension.ts模块开发

extension.ts 是程序的入口文件,里面有两个核心方法:

export function activate(context: vscode.ExtensionContext) {}
export function deactivate() {}

看字面意思很好理解,分别表示插件被激活与释放调用的生命周期方法.

1. 绑定APIKey命令逻辑

要想使用OpenAI的api,首先需要将自己的ApiKey与插件进行关联。这里使用VSCode自有APIvscode.window.showInputBox来获取用户输入.

this.apiKey = await this.context.globalState.get('chatgpt-api-key');
 if (!this.apiKey) {
    const apiKeyInput = await vscode.window.showInputBox({
        prompt: "请输入你的API Key",
        ignoreFocusOut: true,
    });
    this.apiKey = apiKeyInput;
    this.context.globalState.update('chatgpt-api-key', this.apiKey);
 }
  • 使用上下文的globalState来持久化保存ApiKey

  • 如果要让这个命令生效,需要在activate中进行注册

context.subscriptions.push(vscode.commands.registerCommand('chatgpt-for-vscode.setAPIKey', resetToken))

async function resetToken() {
	await vscode.window.showInputBox({
          prompt: "请输入OpenAI API Key",
          ignoreFocusOut: true,
     });
}

执行command + shift + p 输入命令titleGPT:绑定APIKey后,展示效果如下:从零开发一款ChatGPT VSCode插件,chatgpt,vscode,ide,编辑器
这样就完成了对用户ApiKey的绑定逻辑.

2. 命令触发逻辑

与绑定用户ApiKey类似,其他命令的执行也是同样的流程,这里以onCommand:chatgpt-for-vscode.askGPT命令来说明:

// 注册命令
vscode.commands.registerCommand('chatgpt-for-vscode.askGPT', askChatGPT)
// 命令实现
async function askChatGPT(userInput: string) {
  let editor = vscode.window.activeTextEditor;
  if (editor) {
      const selectedCode = editor.document.getText(vscode.window.activeTextEditor?.selection);
      if(selectedCode.length) {
        chatViewProvider.sendOpenAiApiRequest(userInput, selectedCode);
        vscode.window.showInformationMessage(selectedCode);
      }else {
        vscode.window.showInformationMessage(`请选中一段代码`);
      }
  }
}
  • 注册命令后 使用editor.document.getText(vscode.window.activeTextEditor?.selection)来获取选中的代码段落,并判空.

  • 利用chatViewProvider.sendOpenAiApiRequest(userInput, selectedCode);利用这个方法用户输入的Prompt
    与选中的代码端传递出去,这个方法的实现后面介绍,注册所有的命令后,activate方法是这样的

export function activate(context: vscode.ExtensionContext) {

	const chatViewProvider = new view_provider.default(context);

	context.subscriptions.push(
	vscode.commands.registerCommand('chatgpt-for-vscode.askGPT', askChatGPT), 
	vscode.commands.registerCommand('chatgpt-for-vscode.whyBroken', askGPTWhyBroken), 
	vscode.commands.registerCommand('chatgpt-for-vscode.explainCode', askGPTToExplain), 
	vscode.commands.registerCommand('chatgpt-for-vscode.refactor', askGPTToRefactor), 
	vscode.commands.registerCommand('chatgpt-for-vscode.optimizeCode', askGPTToOptimize), 
	vscode.commands.registerCommand('chatgpt-for-vscode.setAPIKey', resetToken), 
	vscode.window.registerWebviewViewProvider("chatgpt-for-vscode.view", chatViewProvider, {
		webviewOptions: { retainContextWhenHidden: true }})
	);
	async function askGPTWhyBroken() { await askChatGPT('说明下面的代码会出现什么问题?'); }
	async function askGPTToExplain() { await askChatGPT('请帮我解释一下下面的代码?'); }
	async function askGPTToRefactor() { await askChatGPT('帮我重构下面的代码'); }
	async function askGPTToOptimize() { await askChatGPT('帮我优化下面的代码'); }
	async function resetToken() {
		await chatViewProvider.ensureApiKey();
	}

	async function askChatGPT(userInput: string) {
      
        let editor = vscode.window.activeTextEditor;
        if (editor) {
            const selectedCode = editor.document.getText(vscode.window.activeTextEditor?.selection);
			if(selectedCode.length) {
				chatViewProvider.sendOpenAiApiRequest(userInput, selectedCode);
				vscode.window.showInformationMessage(selectedCode);
			}else {
				vscode.window.showInformationMessage(`请选中一段代码`);
			}
        }
    }
}
3.webView与chatViewProvider

上面的代码除了注册命令的APIregisterCommand,还有一个注册自定义webview视图的API,registerWebviewViewProvider,作用是展示我们自定义的webview,它有三个参数:

  • chatgpt-for-vscode.view是视图Id,跟package.jsonviews模块对应的Id相同,表示为那个视图Id注册provider.

  • chatViewProvider 视图提供者.

  • 第三个参数:webview的属性配置,retainContextWhenHidden: true表示:webview被隐藏时保持状态,避免被重置.
    接下来重点来看chatViewProvider:
    作为自定义视图的provider首先需要继承vscode.WebviewViewProvider这个接口

export interface WebviewViewProvider {
		/**
		 * Revolves a webview view.
		 *
		 * `resolveWebviewView` is called when a view first becomes visible. This may happen when the view is
		 * first loaded or when the user hides and then shows a view again.
		 *
		 * @param webviewView Webview view to restore. The provider should take ownership of this view. The
		 *    provider must set the webview's `.html` and hook up all webview events it is interested in.
		 * @param context Additional metadata about the view being resolved.
		 * @param token Cancellation token indicating that the view being provided is no longer needed.
		 *
		 * @return Optional thenable indicating that the view has been fully resolved.
		 */
		resolveWebviewView(webviewView: WebviewView, context: WebviewViewResolveContext, token: CancellationToken): Thenable<void> | void;
	}

这个接口只有一个方法,resolveWebviewView在视图首次可见时被调用。这可能发生在视图第一次加载时,或者当用户隐藏然后再次显示视图时。在这个方面里面设置webviewhtml与视图属性。

export default class ChatGptViewProvider implements vscode.WebviewViewProvider {
    private webView?: vscode.WebviewView;
    private apiKey?: string;
    private message?: any;

    constructor(private context: vscode.ExtensionContext) { }

    public resolveWebviewView(
        webviewView: vscode.WebviewView,
        _context: vscode.WebviewViewResolveContext,
        _token: vscode.CancellationToken,
    ) {
        this.webView = webviewView;
        // webview属性设置
        webviewView.webview.options = {
            enableScripts: true,
            localResourceRoots: [this.context.extensionUri]
        };
        // 返回Html代码
        webviewView.webview.html = this.getHtml(webviewView.webview);
        // 接收
        webviewView.webview.onDidReceiveMessage(data => {
            if (data.type === 'askChatGPT') {
                this.sendOpenAiApiRequest(data.value);
            }
        });

        if (this.message !== null) {
            this.sendMessageToWebView(this.message);
            this.message = null;
        }
    }
}
4. 通信机制

自定义的webview和普通网页非常类似,都不能直接调用任何VSCodeAPI,但是,它唯一特别之处就在于多了一个名叫acquireVsCodeApi的方法,执行这个方法会返回一个超级阉割版的vscode对象.利用这个对象,可以实现webview与插件也就是provider的通信。

  • providerwebview发送消息:

this.webView?.webview.postMessage(message);
  • webview端接收消息:

window.addEventListener('message', event => {
	const message = event.data;
	console.log('Webview接收到的消息:', message);
}
  • webview主动发送消息给provider

const vscode = acquireVsCodeApi();
vscode.postMessage({text: '你好,我是Webview啊!'});
  • provider接收消息:

this.webView?.webview.onDidReceiveMessage(data => {
    if (data.type === 'askChatGPT') {
        this.sendOpenAiApiRequest(data.value);
    }
});

了解完双方的通信机制后,基本逻辑是:当点击webview上的发送按钮后,将用户输入发送给ChatGPTChatGPT处理完成后将返回信息发送给webviewwebview将回答信息展示出来,完成一次对话逻辑。

// 按钮绑定点击事件
document.getElementById("ask-button")?.addEventListener("click", submitHandler);
let submitHandler = function (e) {
    e.preventDefault();
    e.stopPropagation();
    const input = document.getElementById("question-input");
    if (input.value?.length > 0) {
      // 发送消息给 插件,使其完成ChatGPT请求
        vscode.postMessage({
            type: "askChatGPT",
            value: input.value,
        });

        input.value = "";
    }
};
5. 调用OPenAI接口

要想完成一次对话,需要调用OPenAI的API.具体的API你可以在官网找到:
从零开发一款ChatGPT VSCode插件,chatgpt,vscode,ide,编辑器

  • 参数model是你要对话的ChatGPT模型代码,不同模型针对同一个问题的答案会有所区别。具体模块区别可以参考下面图片:
    从零开发一款ChatGPT VSCode插件,chatgpt,vscode,ide,编辑器
    更多模型可以点击这里去查看

  • 参数messages: 你的问题信息

  • 参数temperature: 它是一个用于控制生成文本的创造性的参数,其值介于0到2之间。值为1意味着模型将使用其默认采样策略,而值低于1.0将导致更保守和可预测的响应,值大于1.0将导致更有创造性和多样化的响应。

  • 参数max_tokens: 生成对话的最大token数量。这里的token可以理解为模型的构建块。了解完成上面的参数,可以利用fetch发起请求了:

let completion =  await fetch('https://api.openai.com/v1/chat/completions', {
    method: 'POST',
    body: JSON.stringify({
        model: "text-davinci-003",
        messages: [{ role: "user", content: question }],
        temperature: 0.7
    }),
    headers: {
        // eslint-disable-next-line @typescript-eslint/naming-convention
        "Content-Type": 'application/json',
        Authorization: 'Bearer ' + this.apiKey,
    },
}) as any;

根据返回的数据结构,解析响应数据,并将结果发送给webview进行展示,完成开发。
从零开发一款ChatGPT VSCode插件,chatgpt,vscode,ide,编辑器

发布插件
  • 扩展安装
    通过以上步骤基本完成了插件的开发,接下来有两种方式发布我们的插件,如果你的插件只是在内网使用,可以通过命令:vsce package, 将插件打包为vsix插件包,通过VSCode的扩展,从VSIX安装.
    当然首先要安装vsce这个工具

npm i vsce -g

从零开发一款ChatGPT VSCode插件,chatgpt,vscode,ide,编辑器

  • 上传到应用VSCode插件市场

    插件上传到VSCode应用市场,需要有应用市场的publisher账号,具体的账号创建流程这里不再涉及,创建账号后,登录当前账号,执行vsce publish,发布成功后大概需要过几分钟才能在应用市场搜到.发布账号有几个注意事项:

  • README.md文件默认会显示在插件主页;

  • README.md中的资源必须全部是HTTPS的,如果是HTTP会发布失败;

  • CHANGELOG.md会显示在变更选项卡;

  • 如果代码是放在git仓库并且设置了repository字段,发布前必须先提交git,否则会提示Git working directory not clean

  • 发布后需要等待几分钟应用市场才会更新;

  • 当然你可以在插件市场里面搜索chatgpt-for-vscode 来试用这个插件;

    从零开发一款ChatGPT VSCode插件,chatgpt,vscode,ide,编辑器

总结

以上就是一个ChatGPT插件的基本创建流程,核心是对VSCode API以及ChatGPT API的了解与使用。当然你所需要的功能都可以在对应的官方文档中找到。

参考文献:

https://code.visualstudio.com/api/extension-guides/overview
https://platform.openai.com/docs/api-reference/chat/create
http://blog.haoji.me/vscode-plugin-publish.html

- END -

关于奇舞团

奇舞团是 360 集团最大的大前端团队,代表集团参与 W3C 和 ECMA 会员(TC39)工作。奇舞团非常重视人才培养,有工程师、讲师、翻译官、业务接口人、团队 Leader 等多种发展方向供员工选择,并辅以提供相应的技术力、专业力、通用力、领导力等培训课程。奇舞团以开放和求贤的心态欢迎各种优秀人才关注和加入奇舞团。

从零开发一款ChatGPT VSCode插件,chatgpt,vscode,ide,编辑器文章来源地址https://www.toymoban.com/news/detail-696496.html

到了这里,关于从零开发一款ChatGPT VSCode插件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 关于写vscode ChatGPT插件遇到的一些问题

    出于对技术的专研想还原ChatGPT里面的一些交互,中间遇到遇到一些小问题做下总结 一、还原里面的富文本展示 chatgpt返回结果是这样的 最终实现效果 这里不仅还原了文本格式的展示,而且也还原了代码高亮。 可以看出chatgpt返回的是markdawn文本格式,要对markdawn文本格式做下

    2024年02月02日
    浏览(22)
  • 我做了一个 VSCode 插件版的 ChatGPT

    大家好,我是风筝 其实很早之前就想学学 VSCode 插件开发了,但是又不知道做什么,加上我这半吊子前端水平,迟迟没有动手。 最近 ChatGPT 火的一塌糊涂,我也一直在用,真的非常好用,有些问题之前需要 Google 搜索,现在用 ChatGPT 基本上都能直接解决,效率提升了不少。

    2024年02月03日
    浏览(27)
  • 【人工智能】VScode中使用ChatGPT之Bito插件

    之前在VScode中使用ChatGPT中文版,后来要注册与收费,可采用一些ChatGPT中文版的替代插件。 后发现 BitoAI插件 功能同样强大,免费,可中文,真香! 未来Bito若不能使用,可继续在VScode的扩展功能中搜索相关插件,已备使用。 https://code.visualstudio.com 可选择合适的版本,我选的

    2024年02月08日
    浏览(27)
  • 我在 vscode 插件里接入了 ChatGPT,解决了代码变量命名的难题

    lowcode 插件 已经迭代了差不多3年。作为我的生产力工具,平常一些不需要动脑的搬砖活基本上都是用 lowcode 去完成,比如管理脚手架,生成 CURD 页面,根据接口文档生成 TS 类型,生成 mock 等等。 借助 lowcode 的区块物料的功能,能快速生成 CURD 页面,但是前一段时间在做一些

    2024年02月08日
    浏览(23)
  • Bito:一款 iead/webstorm 神级插件,由 ChatGPT 团队开发,堪称辅助神器

            idea(后端),webstorm(前端)中可以用的一款辅助插件:Bito 个人尝试体验效果: 优点是:可以自动完成一些场景代码。 缺点:太慢了,大部分时间一直转圈 什么是Bito? Bito是一款在IntelliJ IDEA编辑器中的插件,Bito插件是由ChatGPT团队开发的,它是ChatGPT团队为了提高开发效

    2024年02月01日
    浏览(25)
  • 推荐一款 IntelliJ IDEA 神级插件,由 ChatGPT 团队开发,免费使用,堪称辅助神器!

    来源:https://blog.csdn.net/m0_64880608/article/details/130201349 Bito是一款在IntelliJ IDEA编辑器中的插件,Bito插件是由ChatGPT团队开发的,它是ChatGPT团队为了提高开发效率而开发的一款工具。 ChatGPT团队是一支专注于自然语言处理技术的团队,他们开发了一款基于GPT的自然语言处理模型,可

    2024年02月02日
    浏览(21)
  • Chatgpt团队研发的idea、vscode免费无需外网的AI插件Bito 保姆级安装教程

    Bito是由chatgpt团队研发的一款ai工具,可以在idea和vscode中直接使用 本文详细介绍在idea、vscode中安装和使用Bito Bito是一款在编程软件中使用的插件,由ChatGPT团队开发的,它是ChatGPT团队为了提高开发效率而开发的一款工具。 官方说明: Bito helps developers dramatically accelerate their

    2024年02月04日
    浏览(27)
  • copilot收费高,推荐一款vscode替代插件

    copilot好不好用?废话!非常好用!!但是。。收费太TM贵了。。。 所以!推荐一款类似copilot的vscode插件! 插件的功能是根据你的代码上下文,提供智能的代码补全和生成建议。插件的名字叫做**mainPilot**。可以直接在 vscode插件市场安装 。 插件市场直接搜 mainPilot 。  mainPi

    2024年02月10日
    浏览(22)
  • ChatGPT聊天机器人搭建全攻略精心整理汇总:微信 Discord 小爱同学 VSCode QQ 飞书 Siri OpenAI Translato翻译插件

    一、ChatGPT接入微信: ChatGPT接入微信 ChatGPT近期以强大的对话和信息整合能力风靡全网,可以写代码、改论文、讲故事,几乎无所不能,这让人不禁有个大胆的想法,能否用他的对话模型把我们的微信打造成一个智能机器人,可以在与好友对话中给出意想不到的回应,而且再

    2024年02月04日
    浏览(37)
  • 【VScode Embedded IDE】Keil工程导入VScode,与Keil协同开发MCU

    由于最近实习要练手一份代码量巨大的Keil项目(写得过于繁杂。由于有几百份第三方设备的源文件头文件,再加上各种条件编译,使得一份c文件里都有近6k行代码),让我这个小白非常头疼,再加之Keil相较于现在的IDE,编辑器在代码阅读,编写等方面都显得老旧些。在这么

    2024年02月05日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包