附录 B:Agent 开发常见问题 FAQ
基础问题
Q1:Agent 和普通的 ChatGPT 对话有什么区别?
A:普通对话是"一问一答",Agent 是"一问多步"。Agent 能自主决定使用什么工具、按什么顺序执行,最终给出综合回答。你可以把 ChatGPT 想象成一个只会说话的顾问,而 Agent 是一个能动手干活的助理。
Q2:我应该选 OpenAI 还是开源模型?
A:取决于你的需求:
| 场景 | 推荐 |
|---|---|
| 快速原型验证 | OpenAI GPT-4o(最强能力) |
| 成本敏感的生产环境 | GPT-4o-mini 或开源模型 |
| 需要数据隐私 | 开源模型本地部署 |
| 需要微调 | 开源模型(如 Llama 3) |
Q3:Agent 需要多少 Token 才能工作?
A:一个典型的 Agent 请求包含:
- 系统提示词:500-2000 tokens
- 对话历史:变长,通常限制在 2000-4000 tokens
- 工具描述:每个工具约 100-200 tokens
- 工具调用结果:变长
建议模型至少支持 8K 上下文窗口,复杂任务建议 32K+。
工具调用问题
Q4:Agent 一直不调用工具,直接编造答案怎么办?
A:在系统提示词中明确要求:
当用户问到需要实时数据的问题时(如天气、价格、库存),
你必须先使用对应的工具查询,不要依赖记忆。
Q5:Agent 陷入了工具调用的无限循环怎么办?
A:设置 max_iterations 或 max_steps 参数限制最大迭代次数。在 LangChain 中:
agent_executor = AgentExecutor(
agent=agent, tools=tools,
max_iterations=10 # 最多执行10步
)
Q6:如何让 Agent 同时使用多个工具?
A:使用 OpenAI 的 parallel_tool_calls 功能,或在 LangGraph 中设置并行节点。但要注意工具之间的依赖关系——如果工具 B 依赖工具 A 的结果,就不能并行。
记忆与上下文问题
Q7:对话太长导致 Token 超限怎么办?
A:三种策略:
- 滑动窗口:只保留最近 N 条消息
- 摘要压缩:用 LLM 将早期对话压缩为摘要
- 选择性保留:保留系统消息 + 最近消息,中间用摘要替代
Q8:如何让 Agent 记住用户的偏好?
A:实现长期记忆——将用户偏好存储在向量数据库或 KV 存储中,每次对话时检索相关偏好并注入到提示词中。
性能与成本问题
Q9:API 调用太慢怎么办?
A:
- 启用流式响应(streaming),减少用户等待感
- 使用更快的模型(如 GPT-4o-mini)处理简单任务
- 实现语义缓存,相似问题直接返回缓存结果
- 并行调用独立的工具
Q10:成本控制的最佳实践?
A:
- 模型路由:简单任务用便宜模型,复杂任务用强模型
- 缓存:相似问题复用结果
- Prompt 压缩:精简系统提示词
- 设置预算告警:超过阈值时通知
- 监控 Token 使用:找出高消耗的环节
安全问题
Q11:如何防止 Prompt 注入?
A:多层防御:
- 输入过滤(正则匹配已知攻击模式)
- 分层 Prompt(系统指令与用户输入物理分离)
- 输出审核(检查回复中是否有敏感信息)
- 最小权限(Agent 只能访问必要的工具和数据)
Q12:Agent 如何避免执行危险操作?
A:
- 使用 Human-in-the-Loop,高风险操作需人工确认
- 定义行为边界,标记每个操作的风险等级
- 设置操作频率限制
- 代码执行在沙箱环境中运行
部署问题
Q13:Agent 服务用什么框架部署?
A:推荐 FastAPI + Uvicorn:
- 原生异步支持
- 自动生成 API 文档
- 内置流式响应(SSE)
- 高性能
Q14:如何处理高并发?
A:
- 异步处理所有 I/O 操作
- 使用信号量限制并发请求数
- 请求队列削峰填谷
- 水平扩展多个 API 实例
- Redis 管理会话状态(无状态 API 层)
Q15:推荐的项目结构是什么?
A:
agent-project/
├── app/
│ ├── main.py # FastAPI 入口
│ ├── agent.py # Agent 核心逻辑
│ ├── tools/ # 工具定义
│ ├── config.py # 配置管理
│ └── middleware.py # 中间件
├── tests/
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
└── .env.example
🤝 多 Agent 协作
Q16:多 Agent 系统中,Agent 之间如何传递复杂数据?
简单数据(字符串、数字)可以直接通过消息传递。复杂数据推荐以下方案:
# 方案1:通过共享状态(适合 LangGraph)
class TeamState(TypedDict):
shared_context: dict # 共享上下文
code: str # 代码产物
review_comments: list # 审查意见
# 方案2:通过文件系统(适合跨进程 Agent)
# Agent A 将结果写入文件,Agent B 从文件读取
Q17:Supervisor 模式和去中心化模式哪个更好?
没有绝对的优劣,取决于你的场景:
| 场景 | 推荐模式 | 原因 |
|---|---|---|
| 流程明确、可预测 | Supervisor | 中心协调更高效 |
| 需要灵活协商、角色对等 | 去中心化 | Agent 之间直接对话更灵活 |
| 需要严格审批 | Supervisor | 监督者可以做质量把关 |
| Agent 数量多(>5) | 分层 Supervisor | 避免单一 Supervisor 成为瓶颈 |
Q18:多 Agent 系统如何调试?
多 Agent 系统的调试比单 Agent 复杂得多,以下是实用建议:
- 给每个 Agent 命名并标记日志:所有 LLM 调用和工具调用都打上 Agent 名称前缀
- 先单独测试每个 Agent:确保每个角色独立工作正常后再组合
- 使用 LangSmith 追踪:可视化多 Agent 的调用链路和消息流
- 设置最大迭代次数:防止 Agent 间无限循环对话
🔧 框架选择问题
Q19:LangChain、LangGraph、CrewAI、AutoGen 应该选哪个?
A:根据项目需求选择:
| 需求 | 推荐框架 |
|---|---|
| 快速原型/简单 Chain | LangChain |
| 复杂有状态的 Agent 工作流 | LangGraph |
| 多角色协作(团队模拟) | CrewAI |
| 多 Agent 对话研究 | AutoGen |
| 不想依赖框架 | OpenAI Agents SDK + 原生 API |
| 企业级低代码 | Dify / Coze |
💡 建议:先用 LangChain 快速验证想法,需要复杂流程控制时迁移到 LangGraph。不要为了用框架而用框架。
Q20:LangChain 版本更新太快,代码总是过期怎么办?
A:
- 锁定版本:在
requirements.txt中固定主要版本号(如langchain>=0.3,<0.4) - 使用核心包:优先使用
langchain-core和langchain-openai等稳定包 - 关注迁移指南:LangChain 官方在每次大版本更新时都会发布迁移文档
- 减少框架耦合:核心业务逻辑不要深度绑定框架 API
Q21:MCP 和 Function Calling 有什么关系?
A:Function Calling 是 LLM 输出结构化工具调用的能力,MCP(Model Context Protocol)是工具发现和连接的标准协议。打个比方:
- Function Calling = "我知道怎么使用工具"
- MCP = "我能找到并连接到任何工具"
两者是互补关系。Agent 通过 MCP 发现可用工具,通过 Function Calling 调用这些工具。
📚 RAG 与知识管理
Q22:RAG 检索质量不好怎么优化?
A:RAG 优化是一个系统工程,按优先级排序:
- 改进分块策略:按语义切分而非固定长度,保持段落完整性
- 优化 Embedding 模型:尝试
text-embedding-3-large或领域微调的 Embedding - 混合检索:向量检索 + BM25 关键词检索结合
- 添加重排序:检索后用 Cross-Encoder 对结果重新排序
- 元数据过滤:利用文档的时间、来源、类别等信息预过滤
Q23:向量数据库选哪个?
A:
| 数据库 | 适合场景 | 特点 |
|---|---|---|
| ChromaDB | 开发/原型 | 轻量、嵌入式、零配置 |
| FAISS | 大规模离线检索 | Meta 出品、速度极快、纯内存 |
| Pinecone | 生产环境 | 全托管、自动扩缩容 |
| Weaviate | 需要混合搜索 | 向量+关键词混合、GraphQL API |
| Qdrant | 需要高级过滤 | Rust 编写、过滤性能优秀 |
🧠 上下文与 Prompt 工程
Q24:Prompt 太长导致模型"忘记"中间内容怎么办?
A:这就是"Lost in the Middle"问题。解决方案:
- 重要信息放开头和结尾:利用 LLM 对头尾信息更敏感的特性
- 使用结构化格式:Markdown/XML 标签帮助模型定位信息
- 分阶段处理:将大任务拆解,每阶段只给必要的上下文
- 使用上下文压缩:先用 LLM 从长文档中提取相关片段
Q25:System Prompt 太长会影响性能吗?
A:会。影响体现在:
- 延迟增加:更多 Token = 更长的首 Token 时间
- 成本增加:按 Token 计费
- 注意力分散:过多的规则会降低模型对关键指令的遵循度
建议 System Prompt 控制在 500-1500 Token 以内,核心规则放在前面。
📊 评估与调试
Q26:怎么知道我的 Agent 效果好不好?
A:从三个维度评估:
- 功能正确性:Agent 是否完成了任务?(准确率、成功率)
- 效率:用了多少步?消耗了多少 Token?延迟多少?
- 安全性:是否遵循了安全边界?是否拒绝了不合理的请求?
具体可以参考第16章介绍的 AgentBench、SWE-bench、GAIA 等基准测试。
Q27:Agent 的输出不稳定,每次结果都不一样怎么办?
A:
- 将
temperature设为 0(确定性输出) - 使用
seed参数(OpenAI 支持) - 添加输出格式约束(JSON Schema / Pydantic)
- 使用多次采样 + 投票(对关键决策进行多数投票)
Q28:怎么排查 Agent "卡住"不动的问题?
A:Agent 卡住通常有以下原因:
- 无限循环:条件路由的逻辑有 bug → 添加最大迭代次数
- 工具超时:外部 API 无响应 → 给工具设置 timeout
- 模型幻觉:LLM 调用了不存在的工具 → 检查工具名称是否正确传递
- Token 超限:上下文太长导致 API 报错 → 添加对话历史修剪
🚀 进阶问题
Q29:如何让 Agent 具备"学习"能力?
A:目前 Agent 的"学习"主要通过以下方式实现:
- 长期记忆:将成功的经验存储为记忆条目(参考第5章)
- Skill 系统:将验证过的工作流封装为可复用技能(参考第9章)
- Prompt 自适应:根据用户反馈动态调整 Prompt
- 微调:收集 Agent 的成功对话数据,用 SFT/RLHF 训练专用模型(参考第10章)
Q30:Agent 开发最常犯的错误是什么?
A:根据社区经验,排名前五的常见错误:
- Prompt 塞太多内容:试图在一个 Prompt 里搞定一切 → 拆分为多步
- 不做错误处理:工具调用失败时 Agent 直接崩溃 → 所有工具加 try/except
- 没有成本监控:某天收到天价账单 → 上线前设预算告警
- 跳过评估:凭感觉判断效果 → 建立系统化的评估流程
- 忽视安全:没有沙箱就让 Agent 执行代码 → 从第一天起就考虑安全