• 前端开发神器之 VsCode AI 辅助插件 DevChat



    #AI编程助手哪家好?DevChat“真”好用 #

    前言

    我们都有过写代码时反复看了半天也不知道bug在哪,大大浪费了时间。一些基础的代码可能看一会儿能够解决,但是复杂的代码就要花上一二个小时去检查,甚至更久。如果有个AI工具,可以帮助我们搞定基础代码,复杂的逻辑给我们提供给逻辑,那岂不是更好啦。本文给大家介绍一款VS Code AI辅助工具-DevChat,开发效率直接翻倍!

    DevChat介绍

    在这里插入图片描述
    DevChat 是一个集成了多种主流大模型的 AI 编程工具,专注于提升程序员的编程效率。它整合了ChatGPT等热门 AI 应用,支持自然语言编程、代码编写、代码生成、代码补全等功能。Devchat 最大的优势是一站式服务,集成热门大模型,并且可以根据需求随心切换,省去了选择和整合不同AI模型的麻烦,无需过多配置就可以快速上手,从而全面提升开发效率。

    产品务实高效,近期还在2023QCon全球软件大会亮相,斩获众多圈内开发者的好评 |

    DevChat 独特优势

    DevChat 兼容多种主流大模型,多种模板快速响应,不用纠结AI编程助手哪家好,大模型包括GPT-4 8k/32k、GPT-3.5 4k/16k、Claude2、文心一言、星火、ChatGLM、Code Llama等;可根据需求选择代码片段进行AI咨询。所以DevChat AI辅助工具对开发者提高工作效率真的很有帮助,具体优势如下:

    1、多种大模型任意选。复杂任务非 GPT-4 莫属,简单任务交给低成本模型,组合使用效能最佳。

    2、精准的“上下文”管理。对上下文的精确控制是有效使用人工智能的关键。DevChat 将控制权交给用户,以实现真正的生产力,并提供用户友好的方法来简化上下文选择。

    3、上手简单。您不必学习特定编程语言的新框架来扩展人工智能以满足您的需求。 提示应该对用户可见且易于编辑,而不是隐藏在复杂的框架中。您不需要复杂的框架来让人工智能为您服务。所需要的只是一个在您的文件系统上运行的标准编辑器。

    4、实用。利用人工智能编码能力的瓶颈在于如何在提示中嵌入正确的上下文,仅当人工智能真正增加价值时才使用它

    5、简单可扩展的提示词目录。开放提示词扩展,Prompts as Code,满足团队和个人自定义需求。

    6、灵活的 Prompt 模板管理,ask-code功能解答代码库的各类问题。

    7、产品设计务实,迭代反馈快。

    8、代码和文档自由生成,而非简单补全。

    9、对接微软 Azure 服务,可信赖的企业级数据安全

    官方地址:https://meri.co/tvy

    注册账号

    DevChat账号注册地址:链接直达,注册之后发送到邮箱的key,注意保存下来,在安装插件之后需要用到。

    安装插件

    打开VS Code开发工具,在应用市场搜索DevChat,然后点击install
    在这里插入图片描述
    安装完之后就可以在侧边栏有个类似小兔子图标,点击之后就可以看到插件的视图。

    设置密钥访问

    插件需要密钥访问,密钥是在注册时发送到邮箱里的。

    在 Visual Studio Code 中按 ⇧⌘P / Ctrl+Shift+PF1 打开命令面板。接下来,输入devchat access key并输入上面的访问密钥。注意不要忘记安装Python 3.8+和Git来使用 DevChat。

    在这里插入图片描述
    然后输入邮箱里的key就可以啦
    在这里插入图片描述
    之后就可以正常使用啦!

    指令

    DevChat提供了下面的指令,方便了我们在开发时的操作以及对代码的分析。

    • 自定义本地命令
      单击此项并输入您想要的命令以运行。返回将被添加到上下文中。
    • git diff --cached
      自上次提交以来已暂存的更改
    • git diff HEAD
      自上次提交以来的所有更改
    • git log for release note
      自指定提交以来的格式化提交历史记录
    • symbol definitions
      在所选代码中查找类、函数等的相关定义
    • symbol references
      查找引用所选符号(类、函数、变量等)的代码站点

    比如我要用symbol references分析下面的代码:

    let transAudioData = {
      transcode(audioData) {
        let output = transAudioData.to16kHz(audioData)
        output = transAudioData.to16BitPCM(output)
        output = Array.from(new Uint8Array(output.buffer))
        self.postMessage(output)
        // return output
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    选择symbol references之后,可以看到控制台中的OUTPUT输出一段JSON。
    在这里插入图片描述
    将图中的字符串转JSON之后如下:

    {
        "languageId": "javascript",
        "path": "../study-demo/kedaxunfei/src/until/transcode.worker.js",
        "startLine": 6,
        "content": "  transcode(audioData) {\r\n    let output = transAudioData.to16kHz(audioData)\r\n    output = transAudioData.to16BitPCM(output)\r\n    output = Array.from(new Uint8Array(output.buffer))\r\n    self.postMessage(output)"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    AI 解疑

    DevChat提供了图中8种AI模型,根据需求选择其中一种进行对话操作。

    选择GPT-3.5模型,然后向DevChat输入需求:手写Promise,让其帮助我们进行解答。DevChat回答如下:
    在这里插入图片描述
    下面是回答的全部代码,可见回答的十分详细。

    enum PromiseStatus {
      Pending = 'pending',
      Fulfilled = 'fulfilled',
      Rejected = 'rejected'
    }
    
    class MyPromise<T> {
      private status: PromiseStatus;
      private value: T;
      private reason: any;
      private onFulfilledCallbacks: ((value: T) => void)[];
      private onRejectedCallbacks: ((reason: any) => void)[];
    
      constructor(executor: (resolve: (value?: T) => void, reject: (reason?: any) => void) => void) {
        this.status = PromiseStatus.Pending;
        this.value = undefined;
        this.reason = undefined;
        this.onFulfilledCallbacks = [];
        this.onRejectedCallbacks = [];
    
        const resolve = (value?: T) => {
          if (this.status === PromiseStatus.Pending) {
            this.status = PromiseStatus.Fulfilled;
            this.value = value;
            this.onFulfilledCallbacks.forEach(callback => callback(this.value));
          }
        };
    
        const reject = (reason?: any) => {
          if (this.status === PromiseStatus.Pending) {
            this.status = PromiseStatus.Rejected;
            this.reason = reason;
            this.onRejectedCallbacks.forEach(callback => callback(this.reason));
          }
        };
    
        try {
          executor(resolve, reject);
        } catch (err) {
          reject(err);
        }
      }
    
      then<U>(onFulfilled?: (value: T) => U | PromiseLike<U>, onRejected?: (reason: any) => U | PromiseLike<U>): MyPromise<U> {
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
        onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };
    
        const promise = new MyPromise<U>((resolve, reject) => {
          const handleFulfilled = (value: T) => {
            try {
              const result = onFulfilled!(value);
              if (result instanceof MyPromise) {
                result.then(resolve, reject);
              } else {
                resolve(result);
              }
            } catch (err) {
              reject(err);
            }
          };
    
          const handleRejected = (reason: any) => {
            try {
              const result = onRejected!(reason);
              if (result instanceof MyPromise) {
                result.then(resolve, reject);
              } else {
                resolve(result);
              }
            } catch (err) {
              reject(err);
            }
          };
    
          if (this.status === PromiseStatus.Pending) {
            this.onFulfilledCallbacks.push(handleFulfilled);
            this.onRejectedCallbacks.push(handleRejected);
          } else if (this.status === PromiseStatus.Fulfilled) {
            setTimeout(() => {
              handleFulfilled(this.value);
            }, 0);
          } else if (this.status === PromiseStatus.Rejected) {
            setTimeout(() => {
              handleRejected(this.reason);
            }, 0);
          }
        });
    
        return promise;
      }
    
      catch<U>(onRejected: (reason: any) => U | PromiseLike<U>): MyPromise<U> {
        return this.then(undefined, onRejected);
      }
    
      static resolve<U>(value?: U | PromiseLike<U>): MyPromise<U> {
        return new MyPromise<U>(resolve => resolve(value));
      }
    
      static reject<U>(reason?: any): MyPromise<U> {
        return new MyPromise<U>((_, reject) => reject(reason));
      }
    
      static all<U>(promises: (U | PromiseLike<U>)[]): MyPromise<U[]> {
        return new MyPromise<U[]>((resolve, reject) => {
          const results: U[] = [];
          let count = 0;
    
          const handleResolve = (value: U, idx: number) => {
            results[idx] = value;
            count++;
            if (count === promises.length) {
              resolve(results);
            }
          };
    
          promises.forEach((promise, idx) => {
            if (promise instanceof MyPromise) {
              promise.then(value => handleResolve(value, idx), reject);
            } else {
              handleResolve(promise, idx);
            }
          });
        });
      }
    
      static race<U>(promises: (U | PromiseLike<U>)[]): MyPromise<U> {
        return new MyPromise<U>((resolve, reject) => {
          promises.forEach(promise => {
            if (promise instanceof MyPromise) {
              promise.then(resolve, reject);
            } else {
              resolve(promise);
            }
          });
        });
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138

    当然,如果我们在编辑器中有部分代码有疑惑,可以右键选择Add to AddChat,然后在左侧对话框输入我们的问题。比如,编辑器中我对下面的代码有疑惑,然后询问DevChat帮我解答疑惑。

      resolve: {
        alias: {
          '@': path.resolve(__dirname, 'src'),
          'components': path.resolve(__dirname, 'src/components'),
        },
        extensions: ['.js', '.json', '.ts', '.vue'], // 使用路径别名时想要省略的后缀名,可以自己 增减
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    可以看到当点击Add to AddChat后,左侧输入框就多个图标内容,主要记录的是你的操作。

    下面是DevChat的回答:

    这段代码是设置在一个使用Vite的项目中的路径别名(alias)和默认文件后缀(extensions)的配置。

    • alias: 这个属性允许你创建一些路径别名,在你引用这个路径时,可以使用别名代替真实路径。例如,在此代码中,‘@’ 代表了 ‘src’
      目录,‘components’ 代表了 ‘src/components’ 目录。所以如果你在项目中想引用 ‘src/components’
      目录下的 ‘Example.vue’ 文件,你可以这么做:import Example from
      ‘components/Example.vue’ 或 import Example from ‘@/Example.vue’。

    • extensions: 这个属性可以设置一些默认的文件后缀。例如在此代码中,设置了 ‘.js’, ‘.json’, ‘.ts’,
      ‘.vue’ 这几种文件后缀名,这样在引用文件时就可以省略这些后缀了。例如 import Example from
      ‘@/Example’,系统会自动尝试加载 ‘src/Example’ + 这些后缀名的文件。

    这两个选项的配置都是用于简化路径引用和提高代码的可读性。

    DevChat进行解答,这种形式不需要我们通过搜索引擎去搜索问题答案,真的是太高效了!

    最后

    体验之后,真的感受到人工智能的强大。提高开发效率是每一位程序猿的综合素养。在互联网降本增效的时代,希望我们每位程序猿都能顺应潮流,更高效地工作,减少无用功,将自身价值发挥到有意义的地方!

  • 相关阅读:
    Github每日精选(第30期):javascript 日期时间选择器flatpickr
    海外版外卖系统,目前国外都有哪些呢?
    Java标识符和关键字,Java常量的定义和分类
    (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
    HDFS 读写解析
    【Lua 入门基础篇(一)】基本语法&数据类型
    js 数据 删除元素 splice
    HTTP协议【网络基础/应用层】
    产品第一次兼项目经理积累了经验也踩过坑
    从网页的canvas上保存渲染的图片
  • 原文地址:https://blog.csdn.net/qq_38951259/article/details/134107580