Menu

用 AI 解释代码:逐行讲解的提示词

让 AI 按你的水平逐行解释代码,并用一张表格展示代码运行时各个值的变化。说明你已经知道什么,让解释从你所在的地方开始。

下面的每条提示词都可以编辑:改好后,在 ChatGPT、Claude 或其他 AI 应用中打开。

想让 AI 给出有用的代码解释,就要说明你已经掌握了多少,要求逐行解释,并要求给出一份跟踪:一张表格,列出代码运行时每个变量的值。只说一句“解释这段代码”,得到的是为一个想象中的普通读者写的概述,对你来说通常要么太浅,要么太快。

逐行解释,并跟踪变量的值

两个标签页问的是同一个简短的函数。比较一下每条回复能让你检查什么。

解释这段代码: def running_max(nums): result = [] best = None for n in nums: if best is None or n > best: best = n result.append(best) return result print(running_max([3, 1, 4, 1, 5]))
Try it
Example replyReplies vary between models and runs.

这个函数计算列表的累计最大值。它遍历这些数字,用 best 记录到目前为止见过的最大值,并在每一步把这个值追加到 result 中。best is None 这个判断用来处理第一个元素。这次调用会打印 [3, 3, 4, 4, 5]。

这个函数的时间复杂度是 O(n),因为它只访问每个元素一次。

第一条回复是准确的,但只有在你已经知道累计最大值是什么时才有帮助。它还加了一段没人问的时间复杂度说明,当模型不知道读者是谁时,就会多出这类内容。第二条回复把每句话都对应到你能指出来的某一行,而表格把概述中一笔带过的内容变得具体:result.append(best) 在每次循环中都会运行,包括 best 没有变化的那几次。这就是 3 出现两次的原因,你可以在第 2 行直接看到,而不用从“在每一步”这几个字中去推断。

跟踪表也是对解释本身的一种检查。你可以在循环里加一行 print(n, best, result) 运行代码,来核对每一行。如果某一行和真实的输出不一致,说明解释有地方错了,而现在你知道错在哪里了。

按你的水平解释

解释类提示词中最有用的一句话,就是说明你已经知道什么。它告诉模型哪些行可以跳过、哪些行要放慢讲。一句角色设定也有帮助(“你是一位老师,面向刚开始学编程第一个月的人”),但它的作用机制是一样的:告诉模型读者是谁。角色提示介绍了角色能改变什么、不能改变什么。

下面这个代码块是一个可复用的版本。改变水平、困惑的部分或代码,解释也会随之改变。

按我的水平解释
Fill in
Parts
给我解释下面的代码。
我的水平:我懂循环、列表和字典,但不懂 lambda,也不懂带 key 参数的 sorted。 让我困惑的部分:最后两行。
text = "the cat and the hat" counts = {} for word in text.split(): counts[word] = counts.get(word, 0) + 1 top = sorted(counts.items(), key=lambda kv: kv[1], reverse=True)[:2] print(top)
我已经懂的那些行,总共用一句话解释。其余篇幅都用来逐个讲解困惑的部分,并展示每一部分针对这个输入得出的值。
不超过 180 字。只使用我的水平范围内的概念,以及你正在讲解的概念。
Try it
Example replyReplies vary between models and runs.

循环统计每个单词出现的次数:counts 最后是 {'the': 2, 'cat': 1, 'and': 1, 'hat': 1}。

现在从里到外看最后两行:

  • counts.items() 给出这些键值对:('the', 2)、('cat', 1)、('and', 1)、('hat', 1)。
  • lambda kv: kv[1] 是一个没有名字的小函数。它接收一个键值对,返回其中的第二项,也就是次数。对于 ('the', 2),它返回 2。
  • sorted(..., key=...) 按这个函数的返回值对键值对排序,也就是按次数排序。reverse=True 把最大的放在最前面。次数相同的单词保持原来的顺序。
  • [:2] 保留前两个键值对。

所以 top 是 [('the', 2), ('cat', 1)],打印出来的就是它。

“次数相同的单词保持原来的顺序”正是快速解释会漏掉的细节,也正是 cat 拿到第二名、而不是 and 或 hat 的原因。Python 的 sorted 是稳定排序,而 reverse=True 会保持这种稳定性。你不会想到要问这一点,是“展示每一部分针对这个输入得出的值”这个要求,让它浮出了水面。

问一个部分,而不是整个文件

粘贴一个 500 行的文件,问“这是做什么的”,得到的是对文件结构的一番导览。当你卡在某个函数上时,就粘贴这个函数以及调用它的那几行,然后直接问它:“为什么列表为空时这个函数会提前返回?”或者“第 12 行的 yield 是做什么的?如果换成 return 会有什么变化?”具体的问题得到的是关于你的代码的回答;宽泛的问题得到的是关于类似代码的回答。

面对一个庞大而陌生的代码库,换一种方式:先要一张地图(“列出主要的模块,以及每个模块负责什么,每个一行”),再去问你需要的那个模块。这就是一个小小的提示词链,每一步都让模型的回答短到足以核实。

借助你会的语言来解释

用一门不熟悉的语言写的代码,在解释以你会的语言为参照时会更容易读懂。在提示词里说明这一点:“我会 Python。请解释这个 Go 函数,并指出每一处和 Python 程序员的预期不同的地方。”误解就藏在这些差异里:整数除法、零值而不是 None、与来源数组共享内存的切片。对这段 Go 代码的普通解释,会正确地描述这些行,却永远不会告诉你,你对它们的直觉是错的。

检查你是否真的理解了

一个你读过、也认同的解释,仍然可能让你没法自己写出这段代码。有两个提示词可以弥补这个差距:

  • 先预测。 在运行代码或要求解释之前,先写下你认为它会打印什么。然后让模型只解释你预测错了的那些行。
  • 讲回去。 写下你自己的解释,让模型指出其中错误或遗漏的地方,但不要重写它。
就这段代码给我出题
Fill in
我刚读完对这段 Python 代码的解释: def running_max(nums): result = [] best = None for n in nums: if best is None or n > best: best = n result.append(best) return result 问我 3 个问题,检查我是否真的理解了它,一次问一个。其中要有一道题让我预测一个新输入的输出。等我回答之后再问下一题,并告诉我答得对不对、为什么。
Try it
Example replyReplies vary between models and runs.

第 1 题,共 3 题:running_max([2, 7, 5, 9]) 会返回什么?先自己算出来,再运行代码。

同样的方法也适用于程序出了问题的时候,不过那时你想要的是原因,而不是一堂课:见用于调试的提示词。当你面前的代码是 AI 写的时,逐行解释是在保留它之前快速审查一遍的好办法;用于写代码的提示词列出了其他需要做的检查。

常见问题

怎么让 ChatGPT 或 Claude 解释代码?

粘贴代码,然后说明三件事:你已经知道什么、哪一部分让你困惑,以及你希望解释是什么形式。“用一句话解释每一行,然后用表格列出每次循环后各个变量的值”得到的回答,远比“解释这段代码”有用得多。

跟踪表是什么?

跟踪表记录程序运行的过程:每一步(通常是每次循环)一行,每个变量一列,填上该变量在那一刻的值。要求给出跟踪表,能把抽象的描述变成可以对照代码检查的具体数值。它就是你用调试器单步执行程序时所看到内容的书面记录。

AI 能解释我不会的编程语言写的代码吗?

能,而且这是最值得让它做的事情之一。说出一门你会的语言,让模型做对比:“我会 Python,请解释这段 Rust 代码,并指出它和 Python 行为不同的地方。”关于语言行为的说法,要通过运行小例子来核实,因为解释可能会在细节上错得理直气壮。

用 AI 解释代码对学习有坏处吗?

这取决于你接下来做什么。读完解释就继续往下走,学不到多少东西。在运行代码之前先预测输出、让模型给你出题,或者把代码讲给模型听并问它你哪里讲错了,这些都需要你自己动脑思考,而学习正是在这里发生的。

Coddy 编程语言插图

和 Coddy 一起学编程

开始