首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

代码采纳率从 22% 到 33%,通义灵码辅助数据库智能编码实践

  • 25-04-18 21:28
  • 3522
  • 12136
juejin.cn

作者:蒲松洋

通义灵码本质上是一个AI agent,它已经进行了大量的优化。然而,为了更完美或有效地调用模型的潜在能力,我们在使用时仍需掌握一些技巧。通常,大多数人在使用通义灵码时会直接上手,这是 AI agent 的一个优势,即 zero shot 使用,无需任何上下文即可直接使用通义灵码的能力。

例如,如果你熟悉通义灵码,@workspace 针对整个代码仓库提出问题时,通义灵码将立即帮助你总结。在这种情况下,我们通常将其称为 zero shot。例如,像“0帧起手”这样的称呼,实际上没有任何上下文,因此通义灵码所获取的信息也相对较少。在这种情况下,它更容易发散性地进行发挥。综上所述,使用 zero shot 时,我们大约只能提取到通义灵码的 70% 的能力,这类似于人类大脑中的快速思维和慢速思维。后面的内容将更详细地讨论如何优化提示词prompt,以最大限度地提取通义灵码的能力。

接手一个新项目,无从下手?

我以一个名为“Cline”的开源项目为例进行演示。它实质上是一个类似于通义灵码的AI插件。当我们面对一个开源仓库时,首要任务是对其有一个全面的理解,明确其技术栈以及整体架构。因此,我们首先需要明确这个代码仓库是做什么的。

css
代码解读
复制代码
@workspace 这个代码仓库是做什么的?

然后大家可以看到通义灵码会提取本地代码仓库的一些信息,并进行本地化信息检索,将关键信息上传至通义灵码后台。接着,通义灵码将针对当前问题做出相应反应。

然而,通义灵码作为一个 AI agent,通过渐进式的增强,如学习用户的习惯不断优化其模型,能够迅速生成回复。它能告诉你当前这个代码仓库是名为 cline 的 VS code 扩展项目,并且能够提供一个AI助手。

在面对新项目时,我们常遇到对新起手项目一无所知的情况。使用IDE能够避免我们阅读大量源码来学习新项目,它为我们提供了很大的便利。向其他同学或对项目熟悉的同学请教相关知识,可能会打扰到他们,而且我们也不能保证他们是否能理解我们的水平和需求。

图片

UnitTest

在许多项目中,通过利用通义灵码,我们能够实现跨站或跨领域的学习。在其他案例中,例如单元测试,我们也会利用单测作为指标性的事情去做。因此,我们会借助通义灵码的能力,比如对于一个从 0 到 1 的项目,如果没有既有的单元测试框架或解决方案,我们可以通过通义灵码来指导项目引入单元测试,搭建起项目中单测的基础框架脚手架,并逐步提高单测覆盖率。此外,我们还可以使用通义灵码来解释代码,即进行代码的解释性工作。

css
代码解读
复制代码
@workspace 这个代码仓库如何引入单测?

针对具体的函数/类来生成单元测试:

图片

协助重构历史代码

当我们面对历史悠久、难以理解的代码时,通常会感到无从下手。虽然这种情况比面对一个完全陌生的代码仓库要稍好一些,但使用通义灵码可以显著减少阅读源码的量。

图片

通过将 renderRigthMenuButton 拆分成多个子函数使其变得更小和更容易阅读,注意,拆分不能改变原函数的逻辑和完整性。

图片

排查错误

解释 TypeScript 编译器错误:TS2345: Argument of type '"loading" | { [key: string]: CompletionX; }' is not assignable to parameter of type '{ [key: string]: CompletionX; }'

图片

当然,对于工程师而言,一旦熟悉了通义灵码,便能自然地将其应用于实践,例如编写浏览器扩展。然而,我今天更想强调的是关于使用技巧。

对于大部分人来说,灵码的许多方法是直觉性的,可以迅速上手。但若要最大限度地利用灵码的剩余生产力,对 Prompt 的 engineer 在工程上有所了解是必要的。

我之前看过很多的文章介绍,因为现在大家对大语言模型有一个普遍的看法,即大模型自身生成的回答往往会趋于平庸。这是因为平庸的回答方式类似于我们的大脑,如果我们要进行深入思考,需要消耗更多的脑力。对于大语言模型来说,若要进行深度思考,将需要更多的 GPU 资源和电力。因此,其回答会倾向于平庸。但要激发它的潜力,我们需要给予一些触发,引导它进行深度思考。所以在使用技巧上,有一些基本的策略。

使用技巧

why?:大模型的回答趋向平庸 70%,我们需要激发它的潜力 30%。

基本策略:专注(Focus);举例(One-Shot,Few-Shot);让模型思考(Chain-Of-Thought);角色扮演(Role Playing);

专注(Focus)

1. 使用明确、精准的语言

技巧:避免模糊、冗余含糊的表达,确保指令清晰、无歧义,尽量精准。

Bad Case:尝试创建一个程序,能处理一些数字计算任务。

Good Case:编写一个Python程序,实现对两个浮点数进行加、减、乘、除四则运算,并提供用户友好的命令行界面。

2. 明确数据类型和格式要求

技巧:详细说明输入参数、返回值以及中间结果的数据类型、结构和格式。

Bad Case:编写一个函数,处理一串数字。

Good Case:使用 TypeScript 编写一个名为sum_of_even_numbers的函数,接受一个类型为number[]的参数numbers,返回列表中所有偶数之和。返回值类型为number类型。

图片

使用例子(One-Shot,Few-Shot)

1. 提供具体的输入/输出实例

技巧:在与通义灵码交互时,务必提供实际的输入数据和预期输出结果,以帮助通义灵码直观理解你的测试用例需求,确保其生成的代码能准确覆盖所需测试场景。

Bad Case:编写一个测试用例,验证一个反转字符串函数的行为。

Good Case:编写一个测试用例,验证反转字符串函数 reverse_string 的行为:

  • 测试函数名称:test_reverse_string
  • 输入数据:待反转字符串"Hello, World!"
  • 预期输出:函数返回结果"!dlroW ,olleH"

2. 描述异常情况及处理方式

技巧:指出可能遇到的异常情况及期望的错误处理策略。

Bad Case:编写一个函数,读取指定路径下的 CSV 文件,并将其内容转换成 string[][]

Good Case:使用 TypeScript 编写一个名为read_csv_to_tabular的函数,接受一个类型为string的参数filePath,表示要读取的CSV文件路径。函数尝试打开并解析该文件,将其内容转换为二维字符串数组并返回。在处理过程中,考虑并妥善处理以下以后情况:

  • 文件不存在:当指定路径的文件不存在时,抛出 FileNotFoundError 错误,并附带提示信息
  • 无权限打开文件:如果用户没有权限访问或读取文件,抛出 PermissionError 错误,并附带提示信息
  • CSV 解析错误:在解析 CSV 文件时,如果遇到不符合CSV格式规范的情况,抛出 ParseError 错误,并附带提示信息
  • 对其他错误,抛出自定义错误 CSVReadError,并附带原始错误信息

图片

scala
代码解读
复制代码
// read_csv_to_tabular.ts import fs from 'fs'; import parse from 'csv-parse'; import { CSVReadError, FileNotFoundError, PermissionError, ParseError } from './errors'; interface CSVRow { [key: string]: string; } export async function read_csv_to_tabular(filePath: string): Promise { return new Promise((resolve, reject) => { fs.access(filePath, fs.constants.R_OK, (err) => { if (err) { if (err.code === 'ENOENT') { reject(new FileNotFoundError(`File not found: ${filePath}`)); } else if (err.code === 'EACCES') { reject(new PermissionError(`Permission denied when accessing file: ${filePath}`)); } else { reject(new CSVReadError(`Failed to open file: ${err.message}`, err)); } return; } fs.createReadStream(filePath) .pipe(parse({ delimiter: ',' })) .on('data', (row: CSVRow) => { resolve(row); }) .on('error', (parseError) => { reject(new ParseError(`Failed to parse CSV: ${parseError.message}`, parseError)); }) .on('end', () => { resolve([]); }); }); }); } // errors.ts class CSVReadError extends Error {} class FileNotFoundError extends CSVReadError {} class PermissionError extends CSVReadError {} class ParseError extends CSVReadError {}

3. 增加强调词和强调符号

技巧:使用强调词汇或突出关键指令,确保灵码充分重视并准确执行。

Bad Case:编写一个测试脚本,使用 Jest 测试框架和 React 组件进行单元测试。

Good Case:请务必编写一个详尽的测试脚本,利用业界领先的 Jest 测试框架对核心 React 组件进行全面的单元测试。遵循一下强调要点:

  • 务必覆盖所有公共方法(包括生命周期方法、自定义时间处理器)和重要的私有辅助方法,确保高代码覆盖率(至少达到95%)
  • 正确模拟组件的依赖项(如 Redux store、API 调用、第三方库等),使用合适的 Jest Mocking 工具(如jest.fn()、 jest.mock())和测试双射(Test Doubles)。
  • 严格执行React 组件的渲染输出验证,利用 Jest 的 Snapshot Testing 功能或 Enzyme/Jest-React 的快照测试,确保 UI 结构与样式的一致性。
  • 全面检查组件的交互行为,通过触发事件、模拟异步响应等方式,验证状态变更、回调触发、路由跳转等预期行为。
  • 遵循最佳实践,保持测试用例的原子性、独立性和可读性,合理组织测试文件结构,使用 describe() 和 it() 块划分测试。
  • 确保用例稳定性,避免因外部以来变化导致的测试失败,定期更新并维护测试数据及 Mock 数据。

4. 撰写模块化的Prompt

技巧:将 Prompt 分为明确的模块,如任务描述、输入数据、预期输出、约束条件等,提升代码可读性和交互效率。

Bad Case:编写一个用户登录功能的界面

Good Case:实现一个使用用邮件和密码的登录界面,登录的后端接口为/api/users/login,接受的JSON请求:

perl
代码解读
复制代码
{ "email": "[email protected]", "password": "secret" }

接口返回:

  • 成功(HTTP 200):返回 access_token
  • 失败(HTTP 401):返回错误信息

约束:

  • 验证:检查 email 格式,验证非空密码
  • token 保存:登录成功后,检查 cookie 中是否设置相同的 token

让模型思考(Chain-Of-Thought)

基于代码上下文来提问

技巧:在与通义灵码交互时,附带相关代码片段、报错堆栈或项目相关背景信息,有助于模型更好的理解任务需求,生成符合现在代码结构和项目逻辑的代码,甚至可以一键帮助你排查问题并输出相关优化代码

Bad Case:仅提供孤立的编程任务要求,如“实现一个函数,计算两个矩阵的乘法”

Good Case:在以下矩阵操作类中,添加一个名为 matrix_multiply 的方法,实现两个同类型矩阵的乘法运算。请确保与已有的 add、 substract 方法保持一致的接口风格。并解释一下你的思路。

角色扮演(Role Playing)

在文件头设定一个整体和概述的目标

Bad Case: 新建空白文件,直接使用灵码生成深入细节的函数

Good Case:在新建空白文件中,先在文件头使用注释来描述背景、整体期望完成的目标、大体逻辑伪代码等;然后再深入具体的细节来生成代码。在文件头设定一个整体的目标描述,有助于灵码在生成具体细节代码时有整体基调背景作为上下文。

总结

关于前面所提到的 zero shot 的一些 prompt 提示词,在了解了如何提高通义灵码回复质量的技巧后,大家也可以尝试对 zero shot 的内容进行修改,以获得更高质量的结果。在此 unit test 中,也欢迎大家介绍自己的背景。

例如:我是一名前端新人,基于这个背景我如何给这个代码仓库如何引入单测,也请你解释一下你的思考过程?此外,在使用这些技巧时,通义灵码也具备上下文记忆能力。这意味着你可以连续提问,这样它就能结合上下文给出更好的回答,或者说是能够根据上下文进行推演。

另外,我想提醒大家注意的是,在模型生成回答之后,还有一个“Retry”选项。许多用户可能倾向于忽略这个按钮,然而,与通义灵码的开发人员交流时,他们告诉我,通过点击“Retry”,模型能够进行升级。或者说,当前的回答可能是基于较浅层的输入。如果希望得到更深入或更慢的回答,或者调度一个参数量更大的模型,可以通过点击“Retry”来实现。尽管更大的模型并不一定总是能返回更好的结果,但它们的思维过程和开放性通常会更高,因为它们拥有更多的参数。

我使用通义灵码的过程分为三个阶段:首先确保团队所有成员都开始使用以提高渗透率,利用其代码自动生成和智能补全功能提升效率;其次,通过经验和技巧的积累,尤其是针对前端外包团队的培训,持续提升采纳率和代码生成占比;最后,利用通义灵码的 RAG 能力,结合团队特定的领域知识和文档,进一步提高开发效率。这一策略需要团队领导者进行细分领域的工作,以及对团队成员的针对性支持。

注:本文转载自juejin.cn的阿里云云原生的文章"https://juejin.cn/post/7483900235289378831"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

143
阅读
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top