学 AI 产品 · 专业 AI 产品经理播客第 1 章 · T1 工程师补课:进阶 · 算法 · 数据结构 · EP 03
第 1 章 · EP 03

BFS 与 DFS:Agent 在代码库里找文件 · 把 AI 写的代码「验收」一遍

时长 16:13音色 云健 · 男声

同步字幕

章节导航(点击跳转)

0:00开场1:07
1:07广度优先与深度优先 · 智能体怎么找东西2:04
3:12贪心与采样 · 温度旋钮的算法学1:51
5:04束搜索 · 多看几步再落笔1:49
6:53五类思想 · 一张对照表1:02
7:55树 · 智能体为什么能指哪打哪1:59
9:54图 · 从知识图谱到多智能体工作流1:46
11:41八种收纳方式 · 验收的抓手3:04
14:45可带走的原则1:26
解读全文

ep03 解读稿 · 搜索与决策、树与图:验收 AI 代码的第二副眼镜

对应音频:base03-播客.mp3 | 集页:https://xueai-podcast.pages.dev/t/base03/
取材:小山学堂《学 AI 产品,从入门到精通》编程基础篇(algo-8 ~ algo-10、algo-summary、algo-build、ds-7、ds-8、ds-summary、ds-build)
定位:面向工程师与重度玩家。你不必自己写得出这些代码,但你要看得穿 AI 交出来的代码是「能跑通」还是「能上线」。

一、本集能力地图

听完之后,你应该能在四类场景里立刻做出判断。这张表就是本集的能力地图,也是后面所有审查动作的索引。

你看到的现象该动用哪副眼镜你要追问的那句话
AI 在几百个文件里找 Bug、找定义、找引用图搜索(BFS / DFS)它是先扫一层还是一路钻到底?能不能直接跳跃?
同样的提示词,两次生成结果不一样贪心 / 采样(Temperature)这个任务该不该要随机性?温度定在多少、为什么?
生成结果「每个词都对、连起来别扭」Beam Search(束宽)它是一次定死还是多留了几条路?束宽多大、算力花在哪?
AI 改代码改得准 / 改错了一大片树(AST)它是在树上做手术,还是在做文本替换?
多个 AI 步骤卡住不动、互相等待图(DAG,查环)这张依赖图查过环吗?哪些步骤本来可以并行?
数据结构选型看不出好坏八种收纳方式数据放哪、怎么找、怎么进出、翻一千倍会怎样?

一句话概括:搜索策略决定它「怎么想」,数据结构决定它「怎么存」,复杂度决定它「撑不撑得住」。三问下来,验收结论就有了。


二、搜索与决策:一条从「贪心」到「穷举」的滑杆

2.1 BFS 与 DFS:两种性格,一本账

同一个迷宫,两种走法,四个数字讲完全部理论。

策略访问格子数最终路径长内存保证
BFS(广度优先)7723高(泡着一大片)撞到终点的路径必然最短
DFS(深度优先)4437低(只记当前一条路)不保证短,还可能回溯

工程含义很直接:

  • 要「最短 / 最近 / 最相关」→ BFS,接受内存开销。网络爬虫从首页开始逐层抓,就是为了保证离首页近的重要页面先入库。
  • 要「先找到一个能用的解、内存紧张」→ DFS,接受路径可能绕。Coding Agent 锁定某个可疑目录后逐层深挖,就是 DFS。
  • 真实系统几乎都是混合策略:先 ls 扫一层建立全局感(BFS),锁定目标后钻进去深挖(DFS),必要时用 grep 直接跳跃——跳跃是比两者都便宜的第三条路。

2.2 贪心与采样:Temperature 的算法学名字

  • 贪心解码:每步取概率最大的 token。Temperature = 0 时就是这个模式,跑一万次一字不差。快、稳、可复现。
  • 采样解码:按概率加权掷骰子。Temperature 越高,softmax 分布越平坦,冷门词越敢冒头。

盲点在于:每步的局部最优,加起来不一定是整体最优。自助餐那个比喻就是这个意思——每一轮都拿当下最贵的菜,最后吃不到真正的主打。

选型规则:

任务类型建议理由
复现实验、写代码、抽取结构化数据Temperature = 0要的是确定性,不要惊喜
头脑风暴、文案、创意发散Temperature 调高要的是多样性,可接受抖动

2.3 Beam Search:算力换质量的滑杆

词格实验的三个累计分:0.072 < 0.098 < 0.101,对应的计算量:12 → 21 → 30 个候选。

  • k = 1 退化为贪心;k → ∞ 等于穷举。Beam Search 是两者之间的滑杆。
  • 工程共识:翻译类任务常用 k = 4 ~ 10。再往上,质量提升越来越少,账单却线性上涨。
  • 现代关联:推理模型「先想再答」是同一哲学——用自然语言探路,灵活得多,但本质仍是「算力换质量」。

三、树与图:AI 读你的项目时到底看到了什么

3.1 树:一层套一层

只要有「层级 + 包含」关系,它就是树。文件目录、JSON、网页 DOM、代码语法树(AST),形状完全一致。三个术语够用一辈子:根、父节点、叶子。

关键认知:AI 改代码精准,是因为它看的不是文字,是 AST。你说「把乘号右边的变量改成 quantity」,它先找到 * 节点,再取右孩子,改完把树打印回文字。重命名、抽取函数、批量重构,全是在树上做手术,不是文本替换。

推论:你调大模型 API 发的 message list、RAG 检索回来的资料、Agent 之间传的任务——几乎全部打包成 JSON,因为 JSON 就是一棵用文字写出来的树。

3.2 图:把「只能有一个爹」这条规矩撕掉

图 = 节点 + 关系,就这一个公式。社交网络、地图导航、知识图谱、Agent 工作流,全都是图。

两个主场:

  1. 知识图谱 / GraphRAG:多跳检索。问「某位企业家母校的知名校友还有谁」,没有任何一段资料直接写着答案,但沿着图走两跳(人物 → 大学 → 另一校友)就拼出来了。
  2. 多 Agent 工作流必须是 DAG:箭头有方向,且不能绕成圈。一旦有环,就是「你等我、我等他、他等你」的三角债,集体卡死。所有编排框架在提交工作流时都会先查环,查出来直接拒绝运行。

顺带一提:并行提速就藏在这张图里——没有依赖关系的任务可以同时开工。所以验收时要问的不仅是「有没有环」,还有「哪些步骤本来可以并行却被串行了」。


四、验收审查清单(拿到交付就照着问)

  • 它把数据放在哪? 数组 / 哈希 / 树 / 图 / 向量,能不能报出结构名。
  • 为什么选它而不是别的? 必须说出至少一个被放弃的备选方案和放弃理由。说不出 = 没做过选型,只是默认输出。
  • 怎么找? 按位置 → 数组;按 key → 哈希;按层级 → 树;按关系 → 图;按相似 → 向量。
  • 怎么进出? 先进先出 → 队列;后进先出 → 栈;算过的别再算 → 缓存。
  • 数据翻一千倍会怎样? 哪一行最先扛不住,是自报还是实测过。
  • 复杂度自报和实测吻合吗? 三档数据量(一千 / 十万 / 一千万)跑基准测试,纸面推演可能吹牛。
  • 优化方案谈代价了吗? 不谈可读性和内存的提速方案,都要多问一句;若用了「空间换时间」,指出是哪一行。
  • 多步决策是一次定死还是多路并行? 束宽多大,对应多少额外算力。
  • 多步骤工作流查过环吗? 哪些步骤在并行,有没有被误串行的。
  • 结论是我下的,还是它替我下的? 说不出「因为我的数据量是 X、最频繁的操作是 Y,所以选它」,判断权就还在它手上。

三面红旗

  1. 循环里套循环挨个比对 → 追问「换成 Set / 哈希表会不会更快」。
  2. 只在小数据上演示 → 永远追问「数据翻一千倍会怎样」。
  3. 只会夸当前选择、举不出被放弃的选项 → 说明它没做过选型。

四之二、八种收纳方式决策表

遇到任何数据场景,只问两个问题,再配一条横切心法,就能定位到结构。

结构口诀强项弱项AI 里的真身
数组排排坐,按号找按位置直达、末尾追加快中间插入/删除要全体挪位message list:你和 AI 的每句对话都躺在里面
栈后进先出撤销、回溯、原路返回只能动最上面那一个撤销栈、函数调用、Agent 子任务;递归失控就爆栈
队列先进先出排队公平、削峰兜底不能插队,中间取不到任务队列、消息队列:Agent 的活是排着队干的
哈希表算出位置,一步直达查找/去重快到不讲理没有顺序,还要多花内存Set / 字典、session 查找、缓存键、语料去重
缓存算过的别再算省时间也省钱何时作废最难拿捏KV Cache、语义缓存、CDN——账单的隐形折扣
树(含 Trie)层层分叉,按层级找天然表达嵌套与从属只认父子关系,平级互连表达不了文件目录、JSON、AST;Trie 是分词器的秘密
图万物皆可连表达任意多对多关系容易绕圈,遍历成本高知识图谱、社交网络、多 Agent 协作的 DAG
向量语义变坐标,相似即邻近按「像不像」找东西结果是近似的,还得配专门索引Embedding + RAG 检索;HNSW 让亿级瞬答

决策心法两问一横切:怎么找(位置→数组,key→哈希,层级→树,关系→图,相似→向量);怎么进出(先进先出→队列,后进先出→栈);横切(算过的别再算→缓存)。

复杂度那一栏别忘了最后补一刀:注意力是 O(n²),上下文越长计算量按平方涨,账单也按平方涨。所以「翻一千倍会怎样」永远值得问——它是区分演示级和生产级的分水岭。


五、约束说明(这份清单的适用边界)

  • 只覆盖「看得懂」这一层:本集讲的是验收者的眼力,不保证你获得手写实现的能力,也不替代单元测试、集成测试与线上监控。
  • 数字来自课程中的交互演示:迷宫的 77 / 23 与 44 / 37、词格的 0.072 / 0.098 / 0.101 与 12 / 21 / 30,都是特定构造下的演示数据,用于说明趋势关系,不代表任何真实系统的实测值。
  • Beam Search 的取值是经验区间而非定律:k = 4 ~ 10 是翻译类任务的常见区间,你的场景要按账单重新算。
  • 温度建议按任务分,不是全局开关:同一个产品里,抽取模块和创意模块可以、也应该用不同温度。
  • 查环只是编排的最低要求:无环不等于高效,还要看关键路径长度和可并行度。
  • 不替代人工终审:AI 自报复杂度大部分时候是对的,但「大部分」不等于「每次」。跑过一次基准测试的人,从此对「它说 O(n) 就是 O(n)」保持职业性怀疑。

提示1 · 半小时档:不看代码,先审口供

拿一段 AI 刚写的代码(没有就让它现写一个「通讯录去重」小工具)。把这段话甩过去:

针对你刚才写的这段代码,请回答三个问题,用大白话:
1. 你用了什么数据结构来存这些数据?
2. 为什么选它而不是别的?说出至少一个被你放弃的备选方案和放弃理由。
3. 如果数据量翻一千倍,这段代码会变慢多少?哪一行最先扛不住?
如果你发现自己刚才的选择不是最优的,请诚实说出来并给出更好的版本。

完成标准:你能用自己的话向别人转述「它用了什么结构、为什么、数据变多会怎样」这三个答案。转述不出来就再追问一轮。

提示2 · 半天档:换一种收纳,结论自己下

请把刚才这个功能用另一种数据结构重新实现一遍,然后:
1. 两个版本的完整代码都贴出来,关键行加注释;
2. 列一张优劣对照表,至少比较四个维度:查询速度、插入速度、内存占用、代码可读性;
3. 分别说明什么场景下版本 A 更好、版本 B 更好,各举一个具体例子;
4. 不要替我下结论,把判断留给我。
我的场景是:(例如「个人工具,数据最多几百条」或「要上线给几万人用」)

完成标准:你能说出「因为我的数据量是 X、最频繁的操作是 Y,所以选它」。说不出这句话,说明判断还是 AI 替你做的。

提示3 · 一周档:先自己选,再和 AI 对答案

先过一遍选型前自查清单:数据会涨到多大/最频繁的操作是查还是插/要不要保持顺序/要不要去重/值不值得上缓存。

我有一个真实需求要做数据结构选型,我已经自己选好了,先别给答案:
我的需求:(一句话)我的场景参数:数据量约 X 条、最频繁的操作是 X、是否需要顺序 X、是否需要去重 X、同样的查询是否反复出现 X。
请你:1. 独立给出选型方案和理由;2. 给出在我的数据量下的性能预估;3. 说明数据量涨 10 倍后方案要不要变、怎么变。
你答完后我会公布我自己的选择,我们对答案。

完成标准:一致就互相验证,不一致就辩论。怕的是从头到尾没自己选过——反过来的话,AI 的答案会瞬间覆盖你的思考。

提示4 · 复杂度体检:让纸面推演接受实测

针对你刚写的这个函数,做一次复杂度自查:
1. 逐行标注时间复杂度,每处一句话解释为什么;
2. 明确指出瓶颈行在哪、为什么是它;
3. 汇总整体时间与空间复杂度;
4. 翻译成人话:数据从 1 千涨到 100 万,会慢多少倍?用户体感是「无感」「卡一下」还是「转圈转到怀疑人生」?

进阶:让它写一个基准测试脚本,生成三档随机数据(1 千 / 10 万 / 1000 万 条,跑不动允许降到 100 万并说明原因),新旧两版各跑 3 次取平均,输出 数据量 | 旧版耗时 | 新版耗时 | 倍数差 对比表,最后回答「实测曲线和自报复杂度吻合吗」。


六、一句话收尾

数据结构管收纳,算法管处理,复杂度管上限,三件事合成一副眼镜。戴上它,AI 交出来的代码你不用会写,但你看得穿——而看不看得穿,就是「能跑通」和「能上线」之间那段距离。


*来源:xueai.miyang.cn(小山学堂 · 洛小山《学 AI 产品,从入门到精通》)。本集为二次演绎的解读与配音版本,素材取自该课程编程基础篇的算法与数据结构章节。*