# 做 Agent 踩了一年坑，这几件事最值得说

> 最近在做 Agent 相关项目，Demo 能跑，但一接真实业务就各种问题：该调工具的时候不调、RAG 检索不准、工具失败不知道咋兜底、上下文一长就乱、成本也不好控。为避免持续踩坑，求大佬分享一些经验。

---

## 该调工具的时候不调

八成是工具描述写得太技术。模型看的是自然语言，不是函数签名。`search_knowledge_base(query: str)` 远不如「当你需要查找文档、查询历史记录、或者不确定某件事的答案时，调用这个工具」。描述里要说清楚**什么情况下该用**，不只是说能做什么。

另一个坑是工具太多。一次给模型 30 个工具，它会乱。核心工具列表控制在 10 个以内，其余的按需加载——用的时候才注入上下文。Peri 的做法是把工具分核心层和延迟层，LLM 先看到 `SearchExtraTools` / `ExecuteExtraTool` 两个元工具，需要的时候自己查。

## RAG 检索不准

检索不准一般不是向量模型的问题，是 chunk 切得太差。段落跨 chunk、标题和正文分离、表格被截断——这些都会让语义丢失。检索准不准，先看 chunk，不要上来就换 embedding 模型。

另一个常见原因是 query 和文档的语言风格不匹配。用户问「这个功能怎么用」，文档写的是「该接口的调用方式为……」。解法是 query 改写——让模型先把用户问题扩写成文档风格，再去检索。

## 工具失败的兜底

工具失败不是异常，是正常状态，必须设计进去：

1. **错误信息要有意义**——返回「文件不存在：/tmp/foo.txt」而不是「操作失败」，模型能自己决定下一步
2. **retry 要有上限**——重试 3 次失败后，让模型明确告知用户，不要无限循环
3. **降级路径要预设**——主工具失败后有没有备用工具？备用工具失败后是放弃还是让用户介入？这个决策树要在设计阶段定下来，不能靠模型临场发挥

## 上下文一长就乱

超过 80% 上下文窗口之后，模型的注意力会漂移，早期的指令和约束开始失效。不是模型变笨了——是超长上下文下注意力机制的结构性限制。

解法是主动压缩，不要等到撑爆再处理。Peri 的策略是 70% 触发 micro-compact（压缩工具调用历史，保留关键结论），85% 触发 full compact（全量摘要重注入）。压缩后 Agent 能接着跑几个小时不中断。自己实现的话，最简单的版本是每隔 N 轮让模型总结一次对话，用摘要替换原始消息。

## 成本控制

成本高通常来自两个地方——系统提示词每轮重复计算、工具结果太冗长。

系统提示词能缓存就缓存。Anthropic 的 Prompt Cache 按前缀匹配，系统提示词必须跨请求完全一致才能命中——动态内容（日期、路径）放最后，静态内容放最前。缓存命中之后，系统提示词的 token 费用直接打到零头。

工具结果要截断。搜索返回 20 条结果，模型实际用 3 条——多余的 17 条全是浪费。在工具层做截断，不要把原始结果全塞进上下文。

项目地址：[github.com/konghayao/peri](https://github.com/konghayao/peri)
