这是系列的第 26 篇。整个系列写给零基础、想入行 AI 的朋友,每天一篇,30 天后你会做出 3 个能写进简历的项目。
这篇解决什么问题
昨天项目三跑通了,有几个朋友说规划步骤挺像样,也有人报告了各种奇怪的状况:跑着跑着不结束、同一个工具连调三次、账单比预期高。
这些都是 Agent 调试的典型问题。Agent 这种程序有个特点:跑通和稳定之间,隔着一段很真实的路。因为它的执行路径是运行时决定的,你没法像普通程序那样预判所有情况。
今天我把调试 Agent 时最容易踩的坑集中讲一遍,每个都给你可落地的解法。这些经验你自己摸索会花掉好几个晚上,今天直接拿走。
一、先把四道护栏装上
调试 Agent 的第一原则:先装护栏,再谈效果。
护栏一:最大步数。
昨天已经加了 MAX_STEPS,但要注意它的位置:应该同时限制规划阶段和执行阶段,别只限制执行。
护栏二:无进展检测。
这是最容易被忽略、也最实用的一个。判断标准:连续两轮调用同一个工具、参数也相同,就判定卡住,强制停止。
defhas_no_progress(history,window=2):"""检查最近几轮是不是在原地打转"""iflen(history)<window:returnFalserecent=history[-window:]# 工具名和参数都一样,说明在重复劳动returnlen(set(recent))==1在循环里记下每轮的“工具名+参数”作为指纹,检测到重复就跳出,并给用户一句人话提示。
护栏三:成本上限。
累计 token 超过阈值就停。这个阈值怎么定?我的建议是按你愿意为一次任务花多少钱倒推。比如一次任务预算 5 分钱,换算成 token 就是几千的量级。
total_tokens=0# ……每轮循环里累计……total_tokens+=response.usage.total_tokensiftotal_tokens>20000:returnf"任务中断:本次已消耗{total_tokens}token,超过预算上限"护栏四:单步超时。
某个工具卡住不返回(比如读了一个超大文件),整个程序就僵住了。给工具调用加超时保护,或者把大文件读取改成流式分块。
二、四个最常见的坑与解法
坑一:它自己发明了不存在的工具。
表现是报错说 name 不在工具清单里。原因通常是对话记录里混进了奇怪的上下文,比如你之前让它列举过工具名,它就照着编了一个。
解法:执行工具前先校验名字,不在名单里就返回“没有这个工具,可用的工具是……”让它重新选。别让程序直接崩。
坑二:工具返回太长,把上下文撑爆了。
表现是跑了几步就报 context length 超限。解法有三个:所有工具都加返回长度上限;用 Day 10 的滑动窗口裁剪历史;把工具结果做摘要再放进上下文(比如读取长文件后先让 AI 总结一句再往下走)。
第三条是进阶做法,效果最好。用户问“这个文件讲了什么”,不需要把全文放进后续所有轮次,一句摘要就够了。
坑三:规划很漂亮,执行完全走样。
表现是计划里写得好好的,执行时它跳步或者乱来。解法是在每轮循环的开头告诉它进度:
progress=f"已完成步骤:{done_steps}\n当前应执行:{current_step}"把它当成上下文的一部分发过去,效果立竿见影。这也说明一个道理:Agent 的稳定性很大程度上靠你把状态显式告诉它,别指望它自己记住。
坑四:同样的输入,每次结果不一样。
这不是 bug,是 Agent 的固有特性。大模型有随机性,加上它自己规划路径,同样的任务走法可能不同。
想让结果稳定一些,可以调低温度参数(temperature 设成 0 到 0.3),代价是回答会更死板。面试时被问到这个问题,你可以这样答:Agent 的不确定性是本质特性,工程上的做法是用固定流程约束主干、只在判断环节交给模型,以及用护栏限制最坏情况。
三、调试 Agent 的三个实用习惯
习惯一:把每一步都打印出来。
调试 Agent 时,日志比什么都重要。每次调用前打印工具名和参数,调用后打印返回结果的前 200 字。出问题时翻日志,一眼就能看出它是在哪一步跑偏的。等你稳定了,再把日志关掉或者降级。
习惯二:用简单任务先跑通链路。
别一上来就测复杂任务。先用“今天是几号”这种一步就能完成的任务,确认链路通;再加两步的任务,再加多工具的任务。逐级递增,出问题好定位。
习惯三:给任务设定“成功的样子”。
调试时你心里要清楚什么样算成功。比如昨天那个“查日期写学习计划存笔记”的任务,成功的样子是:调了 get_date、产出了计划、调了 save_note。三个动作都出现才算过。否则你会被“看起来回答了”迷惑。
四、项目三完工:整理成简历的样子
到这里三个项目全部完成。项目三的简历描述:
个人助理 Agent(个人项目)
- 背景:日常整理资料需要多步骤操作(查信息、汇总、落盘),希望用 Agent 实现自动完成
- 架构:采用 Plan-and-Execute 模式,先由大模型规划 3~5 步执行计划并展示给用户确认,再进入执行循环;执行层基于 Function Calling 实现工具调度
- 工具设计:实现笔记读写、列表查询、日期获取等工具,统一遵循"职责单一、描述明确、返回截断、失败不抛异常"的设计原则,使模型可在工具失败后自主调整策略
- 稳定性:设计四重护栏(最大步数、无进展检测、token 预算上限、单步超时),解决 Agent 死循环与成本失控问题
- 技术栈:Python、Function Calling、Agent 循环、大模型 API
重点说“稳定性”那一条。很多人的 Agent 项目只写了功能,没写护栏。你写了四重护栏,面试官就知道你真正跑过、被坑过。这种细节比功能列表有说服力。
五、三个项目放在一起看
现在你的简历上有了三个层次递进的项目,这个组合的说服力在于它展示了完整的成长曲线:
| 项目 | 能力体现 | 核心关键词 |
|---|---|---|
| 项目一 | 用 AI 自动化处理具体事务 | API 调用、结构化输出、批量优化 |
| 项目二 | 让 AI 掌握私有知识 | RAG、向量检索、幻觉抑制 |
| 项目三 | 让 AI 自主完成任务 | Function Calling、Agent 循环、护栏设计 |
从“调 API 干活”到“管理知识”到“自主决策”,正好覆盖了 AI 应用开发的主要能力面。
常见报错排查
报错一:无进展检测误判,正常任务被中断。
窗口设大一点(比如连续 3 轮),或者只在参数完全相同时才判定。
报错二:加了护栏之后任务老是做不完。
说明 MAX_STEPS 设得太小,或者工具效率太低。先看日志确认它每步在干什么,别盲目加大上限,那是在掩盖问题。
报错三:日志里发现它反复读同一个文件。
典型的规划不合理,把“读取文件”这件事拆成了好几步。在规划提示词里加一句“同一个步骤不要重复执行”。
报错四:任务完成后程序不退出。
检查循环的退出条件,是不是只在有最终答案时才 return。工具调用完成后也要允许进入下一步判断,别把两种情况的处理顺序写反了。
今天的作业
给你的 Agent 加上无进展检测,然后故意设置一个会失败的任务(比如让它读一个不存在的文件、再写笔记),观察它有没有卡住,护栏有没有生效。把日志贴到评论区。
能观察到护栏生效,说明你写的 Agent 真的到了可交付的水准。
明天预告
Day 27:《用 Streamlit 给三个项目统一穿上界面》。现在三个项目都是命令行程序,明天给它们做界面。Streamlit 是 Python 里做界面最快的工具,不用写一行前端代码,几十行就能做出可交互的网页。做完之后,你的项目第一次有了“产品”的样子。
————————————————
*系列目录:30天从零开始学AI应用开发