AI 写出一个看起来合理的函数,你却还说不清它如何兜底、什么时候会失败。在 Yenpo 中选中它,用自己选择的模型提问,再把回答里的每个判断与源码对上。
你需要 Yenpo、本地项目,以及支持相应 API 的模型服务。解释代码的模型可以与写代码的模型不同。
1. 连接自己的模型
打开设置中的“模型”,点击加号添加服务,并将它设为“当前服务”。填写接口类型、“接口地址”、“登录方式”,以及服务实际支持的模型 ID。
Yenpo 提供三类接口:“OpenAI Compatible”(即 OpenAI Chat Completions)、“OpenAI Responses”和“Anthropic Messages”。接口类型要与服务一致,不能只靠模型名判断协议。“获取列表”不是必需步骤;服务不提供列表时,直接填写模型 ID 即可。
API key 只填在设置里。先选一段允许发送给该服务的代码试用。请求可能包含 AI Reader 在选区之外找到的相关代码,具体见数据与权限说明。接口路径和连接错误可查模型连接帮助。
2. 附上要解释的代码
打开文件,选中一个函数或较小的代码块。新建 AI Reader 对话,选择“解释选中”。检查附件中的文件和行范围,再修改准备好的问题并发送。这次阅读保持“允许修改”关闭。
可以这样提问:
按执行顺序解释这段选区。对每个分支,说明触发它的输入或状态、返回值及副作用,并给出对应源码行的引用。需要时读取调用者或测试,区分代码已经说明的事实和对运行时输入的假设。不要修改文件。
选区是阅读起点。需要理解历史改动时,打开对应的 Git 比较,针对那次比较提问,不要默认当前文件仍与它一致。
3. 逐条打开源码引用
点击回答中的引用,在“快速查看”里阅读对应行。需要看前置条件或调用者时,点击“打开文件”。一次核对一个判断:
- 确认路径、行范围和代码版本。
- 读被引用操作之前的条件。
- 回答涉及用户看到的结果时,继续跟踪值如何传到调用者。
- 缺少代码或运行信息的判断,标记为尚未确认。
要支持“这个结果一定最终生效”,还要看哪些路径会走到被引用的赋值,以及之后是否还有其他写入。
4. 用一个小例子练习逐行核对
假设 AI 在教学项目里写了这个 JavaScript 函数:
function displayName(user) {
if (!user) return 'Guest';
const name = user.name?.trim();
return name || 'Guest';
}
以下行号从代码块第一行开始计算;在自己的项目里,应按实际文件行号定位。
| 要核对的说法 | 查看位置 | 代码能说明什么 |
|---|---|---|
| 缺少用户时使用默认值 | 第 2 行 | 用户为 null、undefined 等假值时,读取姓名之前就返回 "Guest" |
| 姓名全是空格时使用默认值 | 第 3–4 行 | 去除空格得到 "",随后返回默认值 |
| 所有格式不正确的输入都安全 | 第 3 行 | 姓名为 42 这类非字符串值时,没有 trim 方法,会抛出 TypeError |
最后一种说法需要纠正。这里的可选链处理了姓名为 null 或 undefined 的情况,并没有校验所有类型。继续读调用者或输入校验,确定数字是否可能传到这个函数。
5. 追问薄弱结论,再执行检查
回答把能力说得太满时,可以继续问:
重新检查“所有格式不正确的输入都安全”这一判断。姓名是数字时会发生什么?引用会失败的操作,再查调用者或校验逻辑是否阻止了这种输入。找不到依据就保留为未确认。
对这个例子,分别检查缺少用户、全空格姓名、两端带空格的普通姓名和数字姓名。在项目测试入口中运行最小的相关测试,并读一遍结果。
核对期间尽量保持文件不变。文件更新后重新选中代码并提问,避免用旧解释去对新的行号。
6. 记下真正理解了什么
简要记录输入假设、分支行为、核对过的源码位置,以及实际跑过的测试。输入校验到底在哪里这类未解问题也要留下,方便下次接着读。
在审查 Claude Code 一轮改动或 Codex 分支时,遇到需要细读的代码块,也可以使用同样的方法。