
资深大牛踩坑总结!构建生产级Agent系统的六项原则:认真打磨你的系统提示词!精心设计你的工具集!
作者 | Arseni Kravchenko
编译 | 云昭
出品 | 51CTO技术栈(微信号:blog51cto)
有时候,总有人会问我:
“我刚接触 agentic development,正在做一个项目,但总觉得好像少了点‘圈内人’才知道的经验。你能不能帮我补补课?”
我常常想推荐一些硬核的课程,比如 HuggingFace 或伯克利的多周训练营,但也理解不是每个人都想那么深入。
于是我决定写下这篇文章,分享六条我在开发 app.build 过程中总结出来的实用经验。这篇更通用,也更适合作为 Agentic 工程入门者的快速参考。
原则一:认真打磨你的 System Prompt
我曾经对 Prompt Engineering 很怀疑,总觉得那像是某种巫术:什么“我会给你 $100 小费”、"我奶奶命悬一线需要这份答案”、"请务必100%准确否则后果严重"……这些技巧偶尔能奏效,本质上是在利用模型的小瑕疵,但从来不是长期解法。
直到我意识到一件事,我才改变了对 Prompt 和 Context Engineering 的看法:
现代大模型其实并不需要什么套路,它们只需要明确、具体、不含矛盾的信息。
没错,就是这么简单。不用操控、也不用博感情。它们擅长执行指令,真正的问题往往是:你的指令本身就不清晰。
现在,各大 LLM 厂商(比如 Anthropic 和 Google)都有一些 prompt 编写的最佳实践文档。你只需要照着做:保持清晰具体,不要玩“聪明人把戏”。比如我们给 Claude 生成 ast-grep 规则的系统提示里,没有用任何花招,只是非常详尽地解释工具的使用方式而已。
我们有个小技巧:可以用像 Deep Research 这种风格的 LLM 来生成系统 prompt 初稿,再由人类润色。这种方式虽然不是最终答案,但是一个非常不错的起点。
同时,把一些上下文内容长期固化在 prompt 里,有利于 prompt 缓存机制的命中率。技术上当然可以缓存用户输入,但我们发现把系统部分设为大而稳定、用户部分保持小而动态,是一种很有效的结构。
原则二:把上下文拆分开来
你已经有了一个不错的 system prompt。但为什么现在“上下文工程”比“提示词工程”更火?因为现实中,管理上下文是一个很有取舍的工程活。
缺少上下文,模型容易胡说八道、偏离主题,甚至直接拒绝回答;上下文太大,又会出现注意力衰减(attention attrition)的问题 —— 模型很难聚焦到真正重要的中间细节,还会带来算力开销和响应延迟。
我们发现一个非常实用的原则是:
一开始只提供最小必要的信息,后续需要的话可以通过工具再拉取更多上下文。
比如在我们的项目中,我们会在提示中列出所有项目文件,并给模型一个“读取文件”的工具,这样它只需要在必要时调用就好。如果我们明确知道某个文件对当前请求至关重要,也可以提前把它的内容放进上下文里。
但也要小心:日志和反馈环节的其他产物很容易让上下文“肿胀”。定期做上下文压缩非常有帮助。
一句话总结就是:封装很重要 —— 把不同的上下文职责分开,只给每个子任务分配它绝对需要的上下文。
原则三:精心设计工具集
AI Agent 的核心能力就是调用工具:一个 LLM + 工具接口 + 控制流操作符,构成了最基本的 agent。
给 Agent 设计工具集其实有点像设计 API,但更复杂。人类开发者可以“意会”,能看懂复杂文档,甚至能绕过 bug;但 Agent 不行。工具太多容易污染上下文,接口不清晰就会用错。
给 Agent 设计工具时,请记住:
工具要接口直接、功能清晰、逻辑干净,就像你要交给一个聪明但容易分神的新手程序员。
好工具的特点:
- 粒度相似
- 参数数量少而明确(最好是强类型)
- 功能单一但可靠
- 尽量幂等,避免状态混乱
在多数软件工程场景里,agent 工具不超过 10 个,典型的有 read_file
, write_file
, edit_file
, execute
等,每个 1-3 个参数即可。
有时候,让 agent 写一段 DSL(领域专用语言)来表示动作,比一个个工具调用更优雅。这种做法被 smolagents 带火了。但前提是:你要先设计好这套 DSL 的语义和函数,不能只做表面功夫。
原则四:设计反馈闭环(Feedback Loop)
一个真正有生产力的 Agent 系统,往往融合了传统软件工程和 LLM 的优势。
我们借鉴了“Actor-Critic”结构:Actor 负责做动作,Critic 负责评估结果。
在 app.build 中,我们让 Actor 生成文件或修改文件,让 Critic 检查它们是否符合我们的预期。这个预期是根据编译成功、测试通过、类型检查、代码格式等硬性标准来的。
不同领域的 agent,都需要类似的“验证机制”。这其实是引入“归纳偏置”(inductive bias)的一种方式 —— 即不管 agent 怎么操作,结果必须满足某些永远不变的规则。
比如,旅行类 Agent 规划多段航班时,要验证这些航班真的存在;财务类 Agent 要满足复式记账原则,否则结果就不成立。
Feedback loop 和“guardrails(护栏)”关系密切。Agent 有一定的恢复能力,如果结果不好,可以尝试提示“你的答案错在 X”,引导其修复。但如果连续几轮都修不好,那就该放弃这个路径,重新开始。
这就像蒙特卡洛树搜索:有些分支值得继续,有些该尽早砍掉。
原则五:用 LLM 做错误分析
当你已经有了 agent + feedback loop,下一步就是持续优化。
AI/ML 工程中,错误分析一直是最核心的环节,agent 也一样。
问题是:agent 太能干了。你一旦开跑几十个 agent 并发任务、产出大量日志,几乎不可能手动读懂它们。
这个时候就该用 “meta-agentic” 的方式:
- 选定一个 baseline 版本;
- 跑出一些轨迹 / 日志;
- 用 LLM 分析这些日志(尤其是像 Gemini 这种大上下文模型);
- 根据 insight 调整系统设计。
大多数情况下,这个流程会揭示出上下文管理或工具设计的盲区。
原则六:让你抓狂的行为,往往是系统问题
现在的大模型已经很强了,所以当 agent 做出明显愚蠢的事时,你会本能地感到沮丧。但现实是:
agent 出错不一定是 LLM 不行,往往是系统没设计好 —— 缺工具、提示不清晰、上下文没给够。
有次我快气疯了:agent 为什么不调用我准备好的数据接口,非要生成一些随机数据?我明明写了“不准用模拟数据”啊!
结果我一看日志,发现锅在我:我忘了给 agent 提供 API Key。它其实尝试调过接口,失败了几次后才换了备选方案。
类似的还有:agent 写文件失败,是因为没开文件系统权限。
总结:agent 出错时,先别怪模型,先查查系统。
结语
构建高效 agent,不是靠一个神奇提示词或酷炫框架,而是:
扎实的系统设计 + 可靠的软件工程方法。
关注清晰的指令、简洁的上下文管理、稳健的工具接口和自动化验证闭环。遇到奇怪的行为,先从系统层排查:是不是少了工具?prompt 有歧义?上下文不够?
最重要的:把错误分析当作一等公民。在迭代中用 LLM 找出失败原因,一步步修正。
目标不是完美的 Agent,而是一个能可靠运行、出错后能优雅恢复、可以不断优化的系统。
参考链接:https://www.app.build/blog/six-principles-production-ai-agents
本文转载自51CTO技术栈,编译:云昭
