前言
得益于大模型的发展,新版VScode
内置了copilot
,而且免费使用,想必jym应该都有用过吧,但是在web端很少见到类似copilot功能的代码编辑器,所以尝试自己实现一下。
本文主要讲述了
Copilot插件
的功能作用,并讲解如何将这种生成代码的形式复刻在Monaco Editor
代码编辑器当中,实现了在线网页版的Copilot
Copilot
作为程序员的你可能已经听说或者正在使用像Copilot
这样的IDE插件。
具体来说,它可以在当前光标处自动生成补全代码,包括但不限于以下几种场景:
- 根据光标所处的上下文,自动生成补全代码并在编辑器中显示
- 根据写的注释,自动生成相应代码;
- 根据已有代码生成测试代码。
除了Copilot
,还有很多类似的产品,如CodeWhisperer
、CodeGeeX
、通义灵码
、iFlyCode
…
我自己使用Copilot
进行开发确实能提高日常工作效率。它能够减少开发过程中的心智负担,让我能更专注于业务分析和需求开发。
我实现的Copilot
体验一下我实现的在线版copilot : codeagle.codeasily.net
实现Copilot代码补全
实现代码补全
的关键分为两个部分:
-
编辑器展示出灰色的补充代码,并支持
Tab
键插入补全代码;这个功能很好处理,就是利用
Monaco Editor
提供的API:monaco.languages.registerInlineCompletionsProvider 以及provideInlineCompletions 就能实现代码提示,与VSCode
体验一致可以打开官网playground示例Monaco Editor (microsoft.github.io) 进行调试,把左边的代码框替换成以下代码可以实时查看效果:
monaco.languages.registerInlineCompletionsProvider("javascript", { provideInlineCompletions: async function (model, position, context, token) { return Promise.resolve({ items: [ { insertText: "cument.addEventListener('", range: new monaco.Range(position.lineNumber, 3, position.lineNumber, "cument.addEventListener('".length) }, ] }) }, freeInlineCompletions(arg) { } }); const myEditor = monaco.editor.create(document.getElementById("container"), { value: '//start type "doc"\n', language: "javascript", wordBasedSuggestions: false, inlineSuggest: { enabled: true, showToolbar: 'onHover', mode: 'subword', suppressSuggestions: false, }, });
效果如图:
-
补全代码的API
有两种方案:
实现Copilot对话框
实现对话框
也是分为两个关键部分:
-
对话输出打字机效果 大模型一般按token逐个生成,所以大模型的回复一般都是逐字显示犹如打字机效果的输出形式,这个功能很多jy都有些相关的教程,我简单概括一下步骤:
- 首先需要确保大模型api启用了stream模式,响应头为
content-type: text/event-stream
- 然后客户端解析响应流,通过
res.body.getReader()
读取响应流内容 - 再得到数据拼接到内容数据中,更新视图
- 得到的内容一般是markdown语法,所以得用第三方库
markdown-it
解析渲染出带样式的内容
- 首先需要确保大模型api启用了stream模式,响应头为
-
核心的大模型对话api 这部分也是跟之前的代码补全api大差不差,用
prompt预训练
一个用于代码问答方面的应用,再训练一些特定指令(/comment是为代码生成注释、/explain是解释代码、/fixbug是修复代码、/test是生成单元测试)让模型处理特定场景即可。