腾讯云 AI 代码助手:产品研发过程的思考和方法论

一、文章摘要

本文将详细阐述 腾讯云 AI 代码助手的历史发展形态与产品整体架构,并从技术、研发方法论的角度分别阐述了产品的研发过程。

全文阅读约 5~8 分钟。

二、产品布局

AI 代码助手产品经历了三个时代的发展

第一代诸如 Eclipse、Jetbrains、Visual Studio Code 等自带的代码补全功能,背后是基于代码语法、语义分析技术,提供的也是基于语词级别的代码补全,补全粒度小。

第二代 AI 代码助手产品是在 2010 年后,比较典型的产品是欧美的 kite 和 Tabnine,背后使用的是基于 LSTM、GPT2 的代码模型,提供的是基于表达式、行内、单行、多行的补全,补全粒度进一步扩充到了行级别。

第三代 AI 代码助手产品是当前流行的大模型时代,典型产品包括微软 GitHub Copilot,以及亚马逊 CodeWhisperer 等,背后都是采用自家训练的代码大模型,并结合代码分析技术,为用户提供多维度、多模式的代码补全,包括单行、多行、注释生成代码、基于 Chat 对话的能力等,为软件开发提供了全新的代码交互体验。

腾讯在 2017 年就聚焦在代码智能赛道上进行探索,当时还是用 LSTM 训练代码模型,但泛化效果不好,比如模型学习 pytorch 的代码,仅仅在 pytorch 相关代码的推荐上表现可以,但其他场景的代码推荐表现很一般。同时我们也加入一些 AST 代码特征,性能上有一些提升;在 GNN 上加入代码的控制流、数据流,训练和推理速度都比较慢,基本不能满足实际的工业场景。

直到 2021年7月 GitHub Copilot 推出多行代码补全、注释生成完整的函数等功能,已经证明大模型在代码智能赛道落地的技术可行性。随后开始在腾讯组建代码智能化团队,布局代码智能赛道。

三、产品整体架构

腾讯云 AI 代码助手的产品整体架构如下:

产品架构

我们提供了两种产品形态和场景,一种是在 IDE 中的场景,包括主屏写代码模式和侧屏 Chat 对话模式,同时在产品设计思想上我们采用主侧屏协同的方式打造极致的用户体验,其产品形态如下图所示:

一种是在腾讯内部源代码托管平台中进行代码评审时的场景,其自动生成 CR 的产品形态如图所示:

四、产品研发体系和技术、方法

腾讯在内部建立了一套双环驱动的 AI 大模型产品研发体系,如下图所示。从用户需求或用户反馈出发,我们先进入模型迭代的小环,首先是数据工程,包含数据采集、数据清洗、数据分析、数据构造、人工标注 5 个步骤,然后进入模型训练,模型评测,部署到测试环境;同时产品迭代也可在模型迭代的同时同步进行,当模型部署到测试环境时,需要和产品功能进行适配,然后测试验证,上线 AB,对 AB 环境下的实验结论进行分析,经评估后进行正式发布上线和运营推广,整个产品迭代的大环结束。在模型迭代的过程中,主要依靠线上的 AB 实验和试点用户反馈来确认迭代效果,因线上 AB 实验和用户反馈到结论才是真实效果的体现。为快速、高效的进行 AB 实验,我们建立了整个 AB 实验流程和流量规范管理制度,能同时驱动多个实验模型在 AB 环境下进行实验,从而高效、规范的管理整个模型到应用的迭代过程。在腾讯内部,AI 代码助手不论是针对用户反馈的 Bad Case 的模型迭代研发到正式上线发布,或者基于需求的产品功能迭代开发到正式上线发布均控制在双周时间内完成一个迭代开发周期

双环驱动的大模型产品研发体系

数据工程流程

1、代码大模型

借助混元全链路自研的技术优势,腾讯云AI代码助手与混元携手共同推动代码大模型达到业界标准。在预训练阶段我们考虑了训练策略、更高质量的代码数据、以及能增强代码能力的代码特征数据;在精调阶段我们构建了基于Bad Case 快速精调迭代上线 AB 的系统化流程。

(1)预训练

在高质量代码数据方面,我们提出了一套高质量代码数据研制方法。对采集的开源代码数据,包括The Stack、GitHub 等进行安全扫描,包括敏信息、缺陷、漏洞等检测,代码规范检测,全复杂度分析,License 分析,代码去重分析(通过自研的支持 type3 级别的代码克隆检测算法,过滤相似的代码文件),代码格式化(将每种语言的代码进行标准的格式化后,模型将会学习标准的代码,所以最终推荐的代码在格式上也是标准的),代码质量评估,经过以上流程研制出高质量的代码数据。因此模型学习的是高质量代码,最终推荐的代码质量也会更高(安全、格式问题相对较少)。其研制流程如下图所示:

高质量代码数据研制流程

在 FIM 代码数据方面,由于主流大模型都是 GPT 式、Decoder-only 的大模型,它是一种自回归的生成式模型,根据上文预测下文。但这显然无法完全满足代码场景需求,因为很多编码场景是上文和下文预测中间部分的代码。比如类的“}”场景,或者在类中的函数中间插入另一个函数。FIM 方法将文本随机分成三部分(Prefix, Middle, Suffix),然后将 Prefix 和 Suffix 顺序打乱重新拼接,来预测 Middle。Prefix、Middle分割点随机选取,Middle、Suffix 分割点采用空格来分割。我们也正在探索与落地基于 AST 结构进行分割的 FIM 技术

在代码数据配比方面,我们通过实验得出通用语料在 10% 的时候对代码能力的影响较小,当通用语料配比增大到 15% 后代码能力有明显下降。在训练的过程中我们同时会考虑代码特征,代码结构等,包括在学习代码文件前先学习文件中引用符号的定义等相关依赖代码,包括函数定义、变量定义、类型定义等;考虑代码文件相似的代码作为先验知识;在一个窗口中基于完整代码仓的学习,这样自注意力机制能更好的学习到代码之间的依赖关系。

(2)精调


为了让大模型具有特定格式、贴合真实业务场景的输出,我们主要采用了 SFT 来激发大模型的代码能力。SFT 就像做练习题,目的是让大模型快速的适应特定的考试场景,而预训练则是让大模型阅读大量课本知识。因此,构建特定的练习题,尤其是高质量的题目是 SFT 的关键。在代码领域,我们构建各种代码任务的高质量练习题的流程,如下图所示,图中 Seed 数据来源包括:开源高质量代码中基于代码静态分析构造的各种代码任务数据对,经过质量评估和人工标注筛选获取小部分作为高质量的种子数据,另外也基于线上 Bad/Good Case 数据进行清洗,包括脱敏、去重等操作,Bad Case 数据还需要进行数据矫正,获取正样本数据,可以通过分析提交代码仓获得或者基于 SOTA 大模型蒸馏的方式获得,但都需要人工标注确认,最后通过 Evol、Oss 的方式进行数据扩充。

SFT 数据研制流程

2、Trigger策略

Trigger 决定代码补全的触发时机。为什么要加触发时机的判断呢?因为需要考虑代码补全的上下文场景,什么时候该触发,什么时候不该触发,做到该触发的时候一定要触发,不该触发的时候就不能触发,否则随意触发推荐会干扰用户的编程思路。整个触发流程如下图所示,首先采用简单的规则判断,针对不确定的情况采用基于模型的触发决策。

启发式规则包括:代码文件 <=5 个字符不触发; 特殊字符触发,如空格,回车,括号等;空注释且没有下文不触发,如 # 等。

基于模型的触发时机当前复用了业界通用的逻辑回归模型。其特征如下图所示,当前采用了业界的权重值,最后通过一个 sigmoid 函数计算一个 0-1 之间的值。我们也正在根据内部数据训练AI代码助手的触发时机模型。

触发时机特征

3、 Prompt 策略

“Prompt engineering” 是一种构建文本的过程,这种文本可以被生成型 AI 模型解读和理解;Prompt 需具体明确、简洁避免冗余信息、适应不同的场景、可以结合注释和关键词描述等。但在代码任务中,其中的“文本”是指”代码上下文”,或者与代码上下文相关的文本描述等。有很多关于 Prompt 的研究工作,包括华盛顿大学的生成知识提示,北大李戈老师团队针对代码生成任务Prompt的结构化思维链, 及Google/ Deepmind 团队提出的 COC 。

如何构建语义清晰、且能最大化激发代码任务的 Prompt ,我们结合大模型 in -context learning 能力以及代码本身的特征提出代码任务的 Prompt 建模方法

代码任务的 Prompt 包含代码上下文和代码知识 2 大部分,其中代码上下文根据不同的代码任务有一些差异,针对代码补全、代码生成任务,代码上下文是当前光标位置处上下文的代码;针对 CR 生成任务,代码上下文是 Diff 片段的上下文代码;针对测试函数生成任务,代码上下文是原始的测试函数。

代码知识是辅助激发大模型代码能力的相关知识,需要清晰的语义表达和相似的实例来激发大模型的在线学习能力。代码知识由代码上下文的位置描述、Import Files 中的符号定义、相似代码(代码块或函数)、代码上下文精准的符号定义、API 序列、领域专有知识 6 大组分构成,如下图所示:

代码使用的Prompt

代码上下文的位置描述是补全中光标位置处、CR 生成任务中的 Diff 片段、单测生成任务中原始的测试函数等所在的函数、类、文件描述,以及相对的文件路径。

Import Files 中的符号定义是代码上下文的代码文件 Import 的符号定义,它是代码特有的属性,反映的是直接依赖关系。因为引用符号需要配套符号定义,没有符号定义不能清晰、明确的表达符号的含义。这些符号可能在代码上下文中引用,也可能在推理的代码中引用,包括函数、类、变量、结构体等。其中 Import 的符号包含仓内定义的符号,也包含三方依赖仓定义的符号。

相似代码包含相似的代码块和相似函数 2 种。相似代码块是在代码仓中与代码上下文相似的代码片段,相似函数是在代码仓中与代码上下文相似的代码函数,通过代码仓分析获取具有继承关系的不同派生类中相同函数签名的函数。该相似块、相似函数可以作为代码示例来激发大模型的 One-Shot/Few-Shot 能力,也包括相似的代码调用方式,调用风格的参考等。

代码上下文精准的符号定义是代码上下文中引用符号的所有符号的精准定义。它是代码特有的属性,反映的是间接依赖关系,如链式调用 'A.b.getXXX()' 中每个符号的定义。

API序列是增加基础组件(如 tRPC 等)的 API 序列调用知识,增强内部组件业务逻辑代码能力。我们专门抽取组件的 API 调用训练了一个 API 调用序列知识模型。

领域专有知识是与领域相关的代码知识集合。可以是领域相关函数功能实现、领域代码的需求描述、功能规格、测试代码描述等,采用向量数据库存储,基于 RAG 的方式实现,实现推荐效果提升。

下面以代码补全任务为例,给出了基于代码分析的 Prompt 自动生成过程:

代码补全 Prompt 生成方法

在代码上下文精准的符号定义分析过程中的难点是针对链式调用场景中的 invoker 的分析,如下图是我们链式调用中精准的 invoker 分析流程:

链式调用精准 invoker 分析

4、Stop 策略

代码大模型推荐的代码是基于文本、按 token 来推荐的,因没有考虑代码的语法结构,则可能造成推荐的代码结构不完整,用户可读性差,如下图所示:

推荐代码结构不完整示例

基于以上问题,我们提出了静态 Stop 策略:根据代码补全场景,结合 AST 分析,并设置相应的停止词让大模型提前按结构终止推理。其对应的代码补全场景和 Stop 词如下图所示:

代码补全细分场景及其 Stop Words

静态 Stop 策略有效,但不能解决用户在类内敲击回车键补全或跟手补全时采用静态 Stop 策略 '\n' 截断的情况,如下图中所示的问题,所以需要动态 Stop 策略来解决以上问题。

静态Stop截断推荐代码示例

5、Show策略

Show 策略是模型推荐异常时不展示的兜底策略,包括 3 类:

模型推荐为空时不 Sho

模型推荐特殊字符时不 Show,如:\n,\t,空格,// to do,重复括号等

模型重复推荐不 Show

重复推荐的检测包含 4 类:

行内重复

如下图所示的是字面量和数组元素重复。行内重复往往会引发超量生成,当产生行内重复时,重复一定发生在最后一行。检测规则是检测生成的内容是否超量生成(是否包含 eos)并判断最后一行的长度是否超过阈值( 256 个 token )。

图片

行类重复示例

单行重复

单行重复发生在用户敲下回车键推荐单行代码的场景,如下图所示为注释重复和变量赋值语句重复。检测规则是基于 AST 分析判定为注释、变量定义、函数调用场景,计算上下的一行和推荐的当前行的相似度值,超过阈值为重复。

单行重复示例

多行重复

多行重复多发生在 python 语言的补全,用户敲下回车键推荐多行代码的场景,如下图所示。检测规则是分别计算对应的上文行或对应的下文行和推荐行的相似度值,若都超过阈值为重复。 

多行重复示例

前后缀重复

前后缀重复发生在修改函数签名时,推荐的代码和下文代码的前缀有重叠,则判定为前后缀重复,如下图所示:

前后缀重复示例

五、总结与展望

本文系统化的给出了腾讯在代码智能赛道打造 AI 代码助手产品的思考和技术方法,从产品、技术和研发方法论的角度分别阐述了产品对腾讯内部服务的研发过程,包括产品层面打造主侧屏协同交互的编码和 Chat 对话相结合的沉浸式 AI 体验,技术上代码补全、代码生成、CR 生成、基于 Chat 对话的代码能力等模型训练和精调,Trigger、Prompt、Stop、Show等产品核心策略和算法,以及构建了一套双环驱动的 AI 大模型产品研发体系,目的是在智能化时代高效、快速的迭代我们的产品,给用户提供极致的开发体验。

如感兴趣,可复制下方链接免费体验产品

​​​​​​​https://copilot.tencent.com/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/62131.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt实现窗口内的控件自适应窗口大小

前言&#xff1a;因为有时候窗口内的控件比较大&#xff0c;但是为了同时操作多个窗口&#xff0c;希望可以根据情况&#xff0c;在调整窗口大小时&#xff0c;控件能自适应大小&#xff0c;于是通过遍历整个界面内的控件&#xff0c;并在调整大小的事件中按比率调整控件大小实…

WebGIS技术汇总

WebGIS系统通常都围绕地图进行内容表达&#xff0c;但并不是有地图就一定是WebGIS&#xff0c;所以有必要讨论下基于Web的地图API分类及应用场景。 Web上的Map API主要分类如下几类&#xff1a; Charts&#xff1a;以D3.js&#xff0c;Echarts等为代表。LBS&#xff1a;以高德…

sql server 获取当前日期的时间戳

SQL Server 获取当前日期的时间戳 在 SQL Server 中&#xff0c;可以使用 GETDATE() 函数获取当前日期和时间。如果想要获取当前日期的时间戳&#xff0c;可以将日期转换为 UNIX 时间戳格式。本文将介绍如何在 SQL Server 中获取当前日期的时间戳&#xff0c;并提供示例代码。 …

Java与C#

Java和C#&#xff08;C Sharp&#xff09;是两种流行的面向对象编程语言&#xff0c;它们在很多方面非常相似&#xff0c;因为它们都受到了类似的编程范式和语言设计理念的影响。然而&#xff0c;它们之间也存在一些重要的区别。 平台依赖性&#xff1a; Java&#xff1a;Java是…

Oracle 深入学习 Part 9: Storage Structure and Relationships(存储结构与关系)

在数据库管理系统&#xff08;DBMS&#xff09;中&#xff0c;Segment&#xff08;段&#xff09;、Extent&#xff08;区块&#xff09; 和 Block&#xff08;块&#xff09; 是描述数据库物理存储结构的三个重要概念。这些概念帮助理解数据库是如何在磁盘等存储设备上组织和管…

活着就好20241127

今天是27号&#xff0c;周三&#xff0c;一个承前启后并积蓄力量的日子。亲爱的朋友们&#xff0c;大家早上好&#xff01;在度过了周二这个巩固成果、深化努力的阶段后&#xff0c;我们迎来了又一个充满挑战与机遇的周三。周三&#xff0c;作为一周的转折点&#xff0c;是我们…

C语言实例之10求0-200内的素数

1. 素数 素数&#xff08;Prime number&#xff09;&#xff0c;也叫质数&#xff0c;是指在大于 1 的自然数中&#xff0c;除了 1 和它自身外&#xff0c;不能被其他自然数整除的数。例如 2、3、5、7、11 等都是素数&#xff0c;而 4 能被 2 整除、6 能被 2 和 3 整除&#x…

区块链知识体系

1. 区块链基础知识 Q: 什么是区块链&#xff1f; A: 区块链是一种去中心化的分布式账本技术&#xff0c;通过加密算法保证数据的不可篡改性和透明性。它由一系列按时间顺序链接的区块组成&#xff0c;每个区块包含一批交易记录。 Q: 区块链的主要特点是什么&#xff1f; 去…

使用Python和Pybind11调用C++程序(CMake编译)

目录 一、前言二、安装 pybind11三、编写C示例代码四、结合Pybind11和CMake编译C工程五、Python调用动态库六、参考 一、前言 跨语言调用能对不同计算机语言进行互补&#xff0c;本博客主要介绍如何实现Python调用C语言编写的函数。 实验环境&#xff1a; Linux gnuPython3.10…

哈希C++

文章目录 一.哈希的概念1.直接定址法2.负载因子 二.哈希函数1.除法散列法 / 除留余数法2.乘法散列法3.全域散列法&#xff08;了解&#xff09; 三.处理哈希冲突哈希冲突&#xff1a;1.开放定址法&#xff08;1&#xff09;线性探测&#xff1a;&#xff08;2&#xff09;二次探…

SAR ADC系列15:基于Vcm-Base的开关切换策略

VCM-Based开关切换策略&#xff1a;采样~第一次比较 简单说明: 电容上下极板分别接Vcm&#xff08;一般Vcm1/2Vref&#xff09;。采样断开瞬间电荷锁定&#xff0c;进行第一次比较。 当VIP > VIN 时&#xff0c;同时 减小VIP 并 增大VIN 。P阵列最高权重电容从Vcm(1/2Vref)…

深度学习模型:循环神经网络(RNN)

一、引言 在深度学习的浩瀚海洋里&#xff0c;循环神经网络&#xff08;RNN&#xff09;宛如一颗独特的明珠&#xff0c;专门用于剖析序列数据&#xff0c;如文本、语音、时间序列等。无论是预测股票走势&#xff0c;还是理解自然语言&#xff0c;RNN 都发挥着举足轻重的作用。…

网络--传输层协议--UDP

传输层作用:负责数据能够从发送端传输到接收端。 1、再谈端口号 端口号标识了一个主机上进行通信的不同的应用程序。 1.1、端口号划分范围 0 - 1023 : 知名端口号,HTTP、FTP、SSH等这些广为使用的应用层协议,他们的端口号都是固定的。 10234 - 65536:操作系统动态分配的…

【IEEE独立出版 | 厦门大学主办】第四届人工智能、机器人和通信国际会议(ICAIRC 2024,12月27-29日)

第四届人工智能、机器人和通信国际会议&#xff08;ICAIRC 2024&#xff09; 2024 4th International Conference on Artificial Intelligence, Robotics, and Communication 重要信息 会议官网&#xff1a;www.icairc.net 三轮截稿时间&#xff1a;2024年11月30日23:59 录…

vue的理解

什么是vue vue是一套用于构建用户界面的渐进式框架&#xff0c;与其他框架不同的是&#xff0c;vue被设计为可以自底向上逐层应用&#xff0c;它也是创建单页面应用的web应用框架。vue的核心库只关注视图层&#xff0c;不仅易上手&#xff0c;还便于与第三方库或既有项目整合。…

第十六届蓝桥杯模拟赛第二期题解—Java

第十六届蓝桥杯模拟赛/校赛第二期个人题解&#xff0c;有错误的地方欢迎各位大佬指正 问题一(填空题) 【问题描述】 如果一个数 p 是个质数&#xff0c;同时又是整数 a 的约数&#xff0c;则 p 称为 a 的一个质因数。 请问&#xff0c; 2024 的最大的质因数是多少&#xff1f; …

二代三代社保卡读卡器串口命令协议,适用于单片机等嵌入式系统使用

接触读社保卡&#xff1a;EA EB EC ED 04 00 7E 7A BB 非接读社保卡&#xff1a;EA EB EC ED 04 00 2E 2A BB 返回格式数据&#xff1a; EAEBECED长度信息类型域状态数据校验BB 例如&#xff1a; EA EB EC ED 57 00 00 7E 7B 22 6E 61 6D 65 22 3A 22 D5 C5 CE AC B1 A6 2…

CLIP-Adapter: Better Vision-Language Models with Feature Adapters

当前的问题 由于CLIP的过度参数化和缺乏足够的训练样例&#xff0c;简单的微调会导致对特定数据集的过拟合&#xff0c;并且训练过程会非常缓慢由于在所有CLIP层之间的向前和向后传播。 方法 视觉适配器 A v ( ⋅ ) A_v(\cdot) Av​(⋅)(包含 W 1 v , W 2 v \textbf{W}^v_1,\…

微软Ignite 2024:建立一个Agentic世界!

在今年的Microsoft Ignite 2024上&#xff0c;AI Agent无疑成为本次大会的重点&#xff0c;已经有十万家企业通过Copilot Studio创建智能体了。微软更是宣布&#xff1a;企业可以在智能体中&#xff0c;使用Azure目录中1800个LLM中的任何一个模型了&#xff01; 建立一个Agent…

微信小程序 WXS 的概念与基本用法教程

微信小程序 WXS 的概念与基本用法教程 引言 在微信小程序的开发中,WXS(WeiXin Script)是一种特殊的脚本语言,旨在解决小程序在逻辑处理和数据处理上的一些限制。WXS 允许开发者在小程序的 WXML 中嵌入 JavaScript 代码,以便实现更复杂的逻辑处理。本文将深入探讨 WXS 的…