腾讯云 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/
相关文章:

腾讯云 AI 代码助手:产品研发过程的思考和方法论
一、文章摘要 本文将详细阐述 腾讯云 AI 代码助手的历史发展形态与产品整体架构,并从技术、研发方法论的角度分别阐述了产品的研发过程。 全文阅读约 5~8 分钟。 二、产品布局 AI 代码助手产品经历了三个时代的发展 第一代诸如 Eclipse、Jetbrains、V…...

Matlab 深度学习 PINN测试与学习
PINN 与传统神经网络的区别 与传统神经网络的不同之处在于,PINN 能够以微分方程形式纳入有关问题的先验专业知识。这些附加信息使 PINN 能够在给定的测量数据之外作出更准确的预测。此外,额外的物理知识还能在存在含噪测量数据的情况下对预测解进行正则…...
【Angular】async详解
在 Angular 中,async 关键字用于定义异步函数,通常与 await 一起使用来处理 Promise。这使得异步代码看起来更像同步代码,从而更容易理解和维护。 基本用法 定义异步函数:使用 async 关键字。等待 Promise 解析:使用…...

抖音SEO矩阵系统:开发技术分享
市场环境剖析 短视频SEO矩阵系统是一种策略,旨在通过不同平台上的多个账号建立联系,整合同一品牌下的各平台粉丝流量。该系统通过遵循每个平台的规则和内容要求,输出企业和品牌形象,以矩阵形式增强粉丝基础并提升商业价值。抖音作…...

SpringBoot集成minio,并实现文件上传
SpringBoot集成minio 什么是minioSpringBoot集成minio1、引入minio依赖2、配置Minio相关参数3、在代码里读取自定义的minio配置4、在minio配置类里,注册ConfigurationProperties实现文件上传到minio1、利用SpringMVC实现接口的异常全局处理2、返回文件路径给前端3、返回文件流…...
centos为用户赋予sudo权限
在CentOS系统中,要为用户test赋予sudo权限,你需要按照以下步骤操作: 确保sudo包已安装: 如果系统中没有安装sudo,你可以通过yum(CentOS 7及以下)或dnf(CentOS 8及以上)来…...

SAP 零售方案 CAR 系统的介绍与研究
前言 当今时代,零售业务是充满活力和活力的业务领域之一。每天,由于销售运营和客户行为,它都会生成大量数据。因此,公司迫切需要管理数据并从中检索见解。它将帮助公司朝着正确的方向发展他们的业务。 这就是为什么公司用来处理…...
Android Framework AudioFlinge 面试题及参考答案
目录 请解释什么是 AudioFlinger? AudioFlinger 在 Android 系统中的位置是什么? AudioFlinger 的主要职责有哪些? AudioFlinger 如何管理音频流? 在 AudioFlinger 中,什么是音频会话? 请简述 AudioFlinger 的工作流程。 AudioFlinger 是如何与硬件交互的? 在 A…...
嵌入式系统与单片机工作原理详解
随着现代科技的发展,嵌入式系统已经深入到我们日常生活中的方方面面。无论是智能家居、汽车电子,还是工业控制、医疗设备,都离不开嵌入式系统的支持。而单片机作为嵌入式系统的核心组件,是实现这些功能的关键之一。本文将详细介绍…...

Diving into the STM32 HAL-----Timers笔记
嵌入式设备会按时间执行某些活动。对于真正简单且不准确的延迟,繁忙的循环可以执行任务,但是使用 CPU 内核执行与时间相关的活动从来都不是一个聪明的解决方案。因此,所有微控制器都提供专用的硬件外设:定时器。定时器不仅是时基生…...
对比 MyBatis 批处理 BATCH 模式与 INSERT INTO ... SELECT ... UNION ALL 进行批量插入
前言 在开发中,我们经常需要批量插入大量数据。不同的批量插入方法有不同的优缺点,适用于不同的场景。本文将详细对比两种常见的批量插入方法: MyBatis 的批处理模式。使用 INSERT INTO ... SELECT ... UNION ALL 进行批量插入。 MyBatis …...
AI大模型如何重塑软件开发流程与模式
AI大模型如何重塑软件开发流程与模式 随着人工智能技术的不断发展,AI大模型正在逐步改变软件开发的方式。传统的软件开发流程,尽管经过多年的演进,使得许多企业能够顺利进行软件开发,但仍然面临着许多挑战,例如开发周…...

NUXT3学习日记五(composables、$fetch和useAsyncData、useFetch,lazy,refresh)
composables 在 Nuxt 3 中,composables(组合式函数)是一种用于封装和复用有状态逻辑的机制。它类似于 Vue 3 中的组合式 API,允许你将相关的逻辑(如数据获取、状态管理等)提取到独立的函数中,然…...
MySQL原理简介—10.SQL语句和执行计划
大纲 1.什么是执行计划 2.执行计划包含哪些内容 3.SQL语句和执行计划的总结 4.SQL语句使用多个二级索引 5.多表关联的SQL语句如何执行 6.全表扫描执行计划的成本计算方法 7.索引的成本计算方法 8.MySQL如何优化执行计划 9.explain的参数说明 1.什么是执行计划 (1)什么…...
wordpress二开-WordPress新增页面模板-说说微语
微语说说相当于一个简单的记事本,使用还是比较方便的。这个版本的说说微语CSS样式不兼容,可能有些主题无法适配,但是后台添加内容,前端显示的逻辑已经实现。可以当作Word press二开中自定义页面模板学习~ 一、后台添加说说微语模…...
001 MATLAB介绍
前言: 软件获取渠道有很多,难点也就是百度网盘下载慢; 线上版本每月有时间限制。 01 MATLAB介绍 性质: MATLAB即Matrix Laboratory 矩阵实验室的意思,是功能强大的计算机高级语言, 已广泛应用于各学科研究部门、…...

Linux—进程概念学习-03
目录 Linux—进程学习—31.进程优先级1.1Linux中的进程优先级1.2修改进程优先级—top 2.进程的其他概念3.进程切换4.环境变量4.0环境变量的理解4.1环境变量的基本概念4.2添加环境变量—export4.3Linux中环境变量的由来4.4常见环境变量4.5和环境变量相关的命令4.6通过系统调用获…...

低速接口项目之串口Uart开发(二)——FIFO实现串口数据的收发回环测试
本节目录 一、设计思路 二、loop环回模块 三、仿真模块 四、仿真验证 五、上板验证 六、往期文章链接本节内容 一、设计思路 串口数据的收发回环测试,最简单的硬件测试是把Tx和Rx连接在一起,然后上位机进行发送和接收测试,但是需要考虑到串…...

java: itext8.05 create pdf
只能调用windows 已安装的字体,这样可以在系统中先预装字体,5.0 可以调用自配文件夹的字体文件。CSharp donetItext8.0 可以调用。 /*** encoding: utf-8* 版权所有 2024 ©涂聚文有限公司 言語成了邀功盡責的功臣,還需要行爲每日來值班…...
如何用通义灵码快速绘制流程图?
使用通义灵码快速绘制流程图?新功能体验 不想读前人“骨灰级”代码,不想当“牛马”程序员,想像看图片一样快速读复杂代码和架构? 通义灵码已经支持代码逻辑可视化,可以把你的每段代码画成流程图。像个脑图工具一样帮你…...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...

实战三:开发网页端界面完成黑白视频转为彩色视频
一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 二、实现思路 总体思路: 用户通过Gradio界面上…...
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么?它的作用是什么? Spring框架的核心容器是IoC(控制反转)容器。它的主要作用是管理对…...

Python训练营-Day26-函数专题1:函数定义与参数
题目1:计算圆的面积 任务: 编写一个名为 calculate_circle_area 的函数,该函数接收圆的半径 radius 作为参数,并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求:函数接收一个位置参数 radi…...