让AI替代50%的工作 ——利用AI速读代码,精读代码
chinese AI
本文以及本专栏正在参加豆包 Marscode 专栏征文活动,如何喜欢欢迎投票支持,这将对我们意义非凡
投票链接
以下实战案例均使用豆包 MarsCode AI 工具,欢迎大家尝试!
想要提升编程效率,释放创造力?快来体验 豆包 MarsCode 编程助手!作为一款由豆包打造的智能编程工具,MarsCode 提供智能代码补全、单测生成、代码解释等强大功能,全面覆盖编程的各个环节,让你从写代码到调试的每一步都更加高效。
无论是快速生成代码片段、优化注释、发现并修复代码问题,还是通过 AI 问答解决开发中的疑惑,MarsCode 都能帮你轻松搞定!支持 Python、JavaScript、TypeScript 等超过 100 种语言,兼容主流 IDE,如 VSCode 和 JetBrains,让开发无缝衔接。
数据安全更是无忧:Marscode 采用加密传输,严格保护用户隐私,确保数据不被用于二次训练。
立即安装 MarsCode,登录即可享受 AI 助力编程的全新体验!
开启效率新篇章,从 MarsCode 开始!
https://www.marscode.cn/
虽然上一章我们说代码主要是用来读的,但读代码确实非常痛苦,特别是接手一个巨大的代码库或者阅读开源项目时,上手需要花费很长的时间。
根据不同的需求,阅读代码有几种方式:
- 速读代码:只需要在代码中找到合适的修改项,并不需要完整理解所有代码。
- 精读代码:需要深入理解代码,从而能够接手和进一步完善项目。
应用内置指令
针对阅读代码这种场景,常见的 AI 助手都会有内置的指令,例如 MarsCode 中内置了 /explain
命令。一般这种内置的指令会集成从用户选中区域获取代码、官方调整过的提示、其他优化项等功能,会有效地提高 AI 输出的质量。
所以,在使用 AI 助手时,优先检查内置的指令,看看哪些命令是自己日常场景可能会用到的,并尝试应用。
如果是解读当前文件的代码,AI 会自动获取用户当前打开的文件作为上下文。但我一般会习惯手动选中来确保 AI 上下文的准确性,甚至有时会手动复制一部分代码到聊天窗口来保证 AI 上下文的正确性。
这里的技巧是,即使你只需要解读整个文件中的一个函数,也最好选中整个文件。原因是,AI 的思考是廉价的,尽可能提供更多的上下文能够增强回复质量。
如上图所示,我会全选文件,可以从 AI 引用信息中看到已经读取了代码中的所有内容。然后我们在提示中指定解析 saveWordRecord
这个函数,AI 就可以在足够的上下文中去解读内容。
引入合适的上下文
几乎在所有应用 AI 的场景下,上下文都是至关重要的。
在实战中,代码中会引用来自其他文件定义的类型、函数等。如果这个函数对理解代码非常重要,那最好将其作为提示放入 AI 的输入中:
这样,AI 在解析时有更丰富的上下文进行参考。 对于更加复杂的问题,我们可以在引入上下文的基础上,使用 COT(思维链)技巧来引导:
请按照以下步骤详细解读 saveChapterRecord 函数:
1. 理解函数目的,分析其主要功能和设计意图,以及在整个应用程序中的角色。
2. 分析输入参数,列出函数所有输入参数,并解析每个参数的类型和作用。
3. 内部逻辑分析,逐步描述函数内部的逻辑流程,解释关键步骤和算法。
4. 类型和数据结构关联,说明函数如何创建和操作实例,并指出这个函数与其他类型或接口的交互方式和逻辑。
5. 解释函数的输出和副作用。描述函数的返回值,以及函数对系统状态和外部产生的影响。
6. 函数内部使用了哪些错误处理和边界条件,指出函数如何处理可能的错误和异常情况,以及函数在特殊情况下的行为。
7. 概括函数的核心作用,并提供可能的安全性风险和潜在的改进点。
你可以根据自己的理解,不限于上述步骤,提供针对此函数有价值的信息。
这种具有复用价值的提示可以整理下来,在适合的场景,根据当时的问题进行针对性的细节修改,然后提示 AI。
可以看到,AI 根据我们提供的信息主动去检索了相关的文件作为上下文进行回复。 很多 AI 辅助编程助手具有类似的功能,相比我们手动嵌入一些上下文会更方便。
对于常见的第三方库,一般会出现在 AI 的训练数据中,AI 可以直接解读这些库的相关代码。但对于一些比较小众的库和版本变化较快的库,AI 可能会使用旧的知识来理解,就会产生偏差,这时候就需要我们手动引入上下文。
例如,我们解读 Dexie 这个库:
可以看到,我直接全选了 Dexie 创建数据库 的文档。因为 AI 具有跨语言理解和提取信息的能力,所以我不用在意语言和格式,一般直接 Ctrl+A 全选即可,然后要求 AI 根据参考文档进行解读。
速读项目
当我们接手一个新的大规模项目或者阅读开源项目时,可以利用 AI 来解读整个代码的架构。 这里利用的是 AI 在经过大规模代码数据训练后,抽象地学到了人类的架构和编码习惯,所以可以将项目的文件目录输入,利用 AI 理解项目的文件结构和主要模块,确定项目的核心部分。
首先,我们获取项目的树状文件结构。你问我如何获得?
我们将树状结构输入给 AI,让其进行分析。这里我们以 开源项目 Qwerty-Learner 为例:
然后,我们就获得了对这个项目的基础理解。如果项目的依赖对理解整个项目很重要,可以将其作为信息传入给 AI,例如 package.json 或者 requirements.txt:
接着,我们找到核心想要关注的部分,让 AI 进行进一步的解读:
或者,我们选中 index.ts
代码,然后将 Switcher
组件代码添加到上下文中,让 AI 解读两个组件之间的联系。这对于我们了解两个文件之间的关系,或者如何进行数据交互非常有意义,在前端领域下,就是两个组件之间的状态交互:
其返回:
在面向对象的编程中,理解各种类是理解整个项目的关键切入点,当然用 AI 去解读和理解也是方便的。
这里,我们首先告诉 AI 我们正在入门项目,要求其从高层次分析整个类,帮助我们理解类的意义和目的,然后再要求其从细节讲解每个类的方法。
同样,我们会选中整个文件,而不仅仅是 ChapterRecord
,从而给 AI 提供更多上下文。
或者,我们换一个思路,当我们需要对一个已有的项目进行修改时,我们可以通过提要求让 AI 在一个巨大的项目架构中,查找可能的修改位置。
AI 回复:
因为我是这个项目的 Owner,我可以说答案几乎完美。参照这个答案去阅读提到的文件,基本能搞清楚添加一个新的发音的任务。这个任务并不是简单地修改几处代码即可,而且涉及多个文件的调整,AI 基本找到了绝大多数修改点。 这里体现了 AI 极强的泛化和联想能力,AI 并不需要了解每个代码文件的详细内容,其从海量的人类代码数据中,抽象地学到了文件/架构和功能/代码的微妙联系,从而仅靠文件架构就能给出高质量的建议。
这里我们也利用了 AI 思考廉价这个技巧,我们会让 AI 尽可能说出可能的修改项和理由。我们的任务就从“从几百个文件中找到合适的修改项”变成了“阅读 AI 提供的文件和理由,筛选出值得关注的文件,阅读这些文件”,这里对值得关注文件的阅读,又可以使用 AI 来完成。
进一步,当我们找到文件中值得关注的函数时,依旧可以让 AI 解读函数实现的逻辑,这个就比较基础了,也在上文中提到过。 一边看 AI 输出的解释一边看代码会比较困难,我们也可以让 AI 直接生成函数注释,阅读起来更方便。
这里,我们首先使用了内置的 /doc
命令,来获得更好的效果。其次,即使我们只针对一个函数要求生成注释,我们也会全选整个文件,来给 AI 提供更丰富的上下文。
在生成之后,我们可以选中对应的函数,然后利用 AI 工具自带的插入功能,替换代码:
更进一步,在我们深入阅读一个函数时,经常需要深入地分析函数的各种状态。这当然也可以用 AI 来帮助,例如询问函数的特殊情况、解读异常值的原因(在调试时)、或者询问函数内部某个变量在什么情况下为 true
等细节,例如:
小结
在这一节中,我们带大家完整地走了用 AI 由浅入深地阅读一个项目的全过程。 AI 并不是万能的,只是一个高效率的辅助工具,所以在整个过程中,我们是一直在思考的,就像:
- “开始入门项目,我们需要理解整个项目的架构” => “获取整个项目的架构,让 AI 去分析,介绍给我”
- “我大概理解了架构,发现了一些值得关注的地方” => “让 AI 解读这些地方的实现细节”
- “我发现了一个不理解的函数” => “用各种技巧,让 AI 辅助我阅读”
- “我想……” => “让 AI……来辅助我思考”
在上述过程中,人是驱动力,AI 是辅助工具,这很重要。AI 的出现不是让所有问题迎刃而解,而是让人类的思考更加方便。这也意味着,当工具越来越趁手和高效,更高维度的独立思考价值也就越高。
所以,AI 解决的是人类低效的重复性工作,人类的思考价值会被放大。这也是我经常说的,当“我写业务代码贼快”、“我 API 贼熟悉”这些能力的价值被 AI 取代后,程序员之间的能力差距可能会变成“独立思考能力强”、“对技术和产品有自己的想法”、“对 AI 的优势和边界理解深、用得巧妙”。
共勉。