# 附录 B：Agent 开发常见问题 FAQ

![Agent 开发 FAQ 问题分类](../svg/appendix_faq.svg)

---

## 基础问题

### Q1：Agent 和普通的 ChatGPT 对话有什么区别？

**A**：普通对话是"一问一答"，Agent 是"一问多步"。Agent 能自主决定使用什么工具、按什么顺序执行，最终给出综合回答。你可以把 ChatGPT 想象成一个只会说话的顾问，而 Agent 是一个能动手干活的助理。

### Q2：我应该选 OpenAI 还是开源模型？

**A**：取决于你的需求：

| 场景 | 推荐 |
|------|------|
| 快速原型验证 | GPT-4.1 / Claude Sonnet 4.5（旗舰能力） |
| 成本敏感的生产环境 | GPT-4.1-mini 或 Gemini Flash（2026 年性价比最优）|
| 需要数据隐私 | 开源模型本地部署 |
| 需要微调 | 开源模型（如 Llama 4、Qwen3）|

### 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 中：
```python
agent_executor = AgentExecutor(
    agent=agent, tools=tools, 
    max_iterations=10  # 最多执行10步
)
```

### Q6：如何让 Agent 同时使用多个工具？

**A**：使用 OpenAI 的 `parallel_tool_calls` 功能，或在 LangGraph 中设置并行节点。但要注意工具之间的依赖关系——如果工具 B 依赖工具 A 的结果，就不能并行。

---

## 记忆与上下文问题

### Q7：对话太长导致 Token 超限怎么办？

**A**：三种策略：
1. **滑动窗口**：只保留最近 N 条消息
2. **摘要压缩**：用 LLM 将早期对话压缩为摘要
3. **选择性保留**：保留系统消息 + 最近消息，中间用摘要替代

### Q8：如何让 Agent 记住用户的偏好？

**A**：实现长期记忆——将用户偏好存储在向量数据库或 KV 存储中，每次对话时检索相关偏好并注入到提示词中。

---

## 性能与成本问题

### Q9：API 调用太慢怎么办？

**A**：
1. 启用流式响应（streaming），减少用户等待感
2. 使用更快的模型（如 gpt-4.1-mini、gemini-2.0-flash）处理简单任务
3. 实现语义缓存，相似问题直接返回缓存结果
4. 并行调用独立的工具

### Q10：成本控制的最佳实践？

**A**：
1. **模型路由**：简单任务用便宜模型，复杂任务用强模型
2. **缓存**：相似问题复用结果
3. **Prompt 压缩**：精简系统提示词
4. **设置预算告警**：超过阈值时通知
5. **监控 Token 使用**：找出高消耗的环节

---

## 安全问题

### Q11：如何防止 Prompt 注入？

**A**：多层防御：
1. 输入过滤（正则匹配已知攻击模式）
2. 分层 Prompt（系统指令与用户输入物理分离）
3. 输出审核（检查回复中是否有敏感信息）
4. 最小权限（Agent 只能访问必要的工具和数据）

### Q12：Agent 如何避免执行危险操作？

**A**：
1. 使用 Human-in-the-Loop，高风险操作需人工确认
2. 定义行为边界，标记每个操作的风险等级
3. 设置操作频率限制
4. 代码执行在沙箱环境中运行

---

## 部署问题

### Q13：Agent 服务用什么框架部署？

**A**：推荐 FastAPI + Uvicorn：
- 原生异步支持
- 自动生成 API 文档
- 内置流式响应（SSE）
- 高性能

### Q14：如何处理高并发？

**A**：
1. 异步处理所有 I/O 操作
2. 使用信号量限制并发请求数
3. 请求队列削峰填谷
4. 水平扩展多个 API 实例
5. 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 之间如何传递复杂数据？

简单数据（字符串、数字）可以直接通过消息传递。复杂数据推荐以下方案：

```python
# 方案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 复杂得多，以下是实用建议：

1. **给每个 Agent 命名并标记日志**：所有 LLM 调用和工具调用都打上 Agent 名称前缀
2. **先单独测试每个 Agent**：确保每个角色独立工作正常后再组合
3. **使用 LangSmith 追踪**：可视化多 Agent 的调用链路和消息流
4. **设置最大迭代次数**：防止 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**：
1. **锁定版本**：在 `requirements.txt` 中固定主要版本号（如 `langchain>=0.3,<0.4`）
2. **使用核心包**：优先使用 `langchain-core` 和 `langchain-openai` 等稳定包
3. **关注迁移指南**：LangChain 官方在每次大版本更新时都会发布迁移文档
4. **减少框架耦合**：核心业务逻辑不要深度绑定框架 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 优化是一个系统工程，按优先级排序：
1. **改进分块策略**：按语义切分而非固定长度，保持段落完整性
2. **优化 Embedding 模型**：尝试 `text-embedding-3-large` 或领域微调的 Embedding
3. **混合检索**：向量检索 + BM25 关键词检索结合
4. **添加重排序**：检索后用 Cross-Encoder 对结果重新排序
5. **元数据过滤**：利用文档的时间、来源、类别等信息预过滤

### Q23：向量数据库选哪个？

**A**：

| 数据库 | 适合场景 | 特点 |
|--------|---------|------|
| ChromaDB | 开发/原型 | 轻量、嵌入式、零配置 |
| FAISS | 大规模离线检索 | Meta 出品、速度极快、纯内存 |
| Pinecone | 生产环境 | 全托管、自动扩缩容 |
| Weaviate | 需要混合搜索 | 向量+关键词混合、GraphQL API |
| Qdrant | 需要高级过滤 | Rust 编写、过滤性能优秀 |

---

## 🧠 上下文与 Prompt 工程

### Q24：Prompt 太长导致模型"忘记"中间内容怎么办？

**A**：这就是"Lost in the Middle"问题。解决方案：
1. **重要信息放开头和结尾**：利用 LLM 对头尾信息更敏感的特性
2. **使用结构化格式**：Markdown/XML 标签帮助模型定位信息
3. **分阶段处理**：将大任务拆解，每阶段只给必要的上下文
4. **使用上下文压缩**：先用 LLM 从长文档中提取相关片段

### Q25：System Prompt 太长会影响性能吗？

**A**：会。影响体现在：
- **延迟增加**：更多 Token = 更长的首 Token 时间
- **成本增加**：按 Token 计费
- **注意力分散**：过多的规则会降低模型对关键指令的遵循度

建议 System Prompt 控制在 500-1500 Token 以内，核心规则放在前面。

---

## 📊 评估与调试

### Q26：怎么知道我的 Agent 效果好不好？

**A**：从三个维度评估：
1. **功能正确性**：Agent 是否完成了任务？（准确率、成功率）
2. **效率**：用了多少步？消耗了多少 Token？延迟多少？
3. **安全性**：是否遵循了安全边界？是否拒绝了不合理的请求？

具体可以参考第15章介绍的 AgentBench、SWE-bench、GAIA 等基准测试。

### Q27：Agent 的输出不稳定，每次结果都不一样怎么办？

**A**：
1. 将 `temperature` 设为 0（确定性输出）
2. 使用 `seed` 参数（OpenAI 支持）
3. 添加输出格式约束（JSON Schema / Pydantic）
4. 使用多次采样 + 投票（对关键决策进行多数投票）

### Q28：怎么排查 Agent "卡住"不动的问题？

**A**：Agent 卡住通常有以下原因：
1. **无限循环**：条件路由的逻辑有 bug → 添加最大迭代次数
2. **工具超时**：外部 API 无响应 → 给工具设置 timeout
3. **模型幻觉**：LLM 调用了不存在的工具 → 检查工具名称是否正确传递
4. **Token 超限**：上下文太长导致 API 报错 → 添加对话历史修剪

---

## 🚀 进阶问题

### Q29：如何让 Agent 具备"学习"能力？

**A**：目前 Agent 的"学习"主要通过以下方式实现：
1. **长期记忆**：将成功的经验存储为记忆条目（参考第4章）
2. **Skill 系统**：将验证过的工作流封装为可复用技能（参考第9章）
3. **Prompt 自适应**：根据用户反馈动态调整 Prompt
4. **微调**：收集 Agent 的成功对话数据，用 SFT/RLHF 训练专用模型（参考第10章）

### Q30：Agent 开发最常犯的错误是什么？

**A**：根据社区经验，排名前五的常见错误：
1. **Prompt 塞太多内容**：试图在一个 Prompt 里搞定一切 → 拆分为多步
2. **不做错误处理**：工具调用失败时 Agent 直接崩溃 → 所有工具加 try/except
3. **没有成本监控**：某天收到天价账单 → 上线前设预算告警
4. **跳过评估**：凭感觉判断效果 → 建立系统化的评估流程
5. **忽视安全**：没有沙箱就让 Agent 执行代码 → 从第一天起就考虑安全

---

## 🧪 强化学习与模型训练

### Q31：如何缓解概率较小的复读机问题？

**A**：复读机问题（Repetition）在 LLM 中偶尔会出现，可以通过以下几种方式缓解：
- **调整采样参数**：适当增加 `repetition_penalty`（重复惩罚）或 `presence_penalty`，降低已生成词汇的采样概率。同时可以微调 `temperature` 和 `top_p` 增加输出的多样性。
- **强化学习惩罚**：在 RLHF 或 GRPO 阶段，设计专门的规则检测重复模式（如 N-gram 重复率），对出现严重重复的输出给予负奖励（Negative Reward）。
- **SFT 数据清洗**：检查 SFT 训练数据，确保数据中没有包含大量重复模式的低质量样本。
- **Prompt 优化**：在 System Prompt 中明确指示模型"请勿重复之前的话语"或"保持回答简洁多样"。

### Q32：如何训练大模型的情商和流畅度，这种 reward 要怎么设计？

**A**：
- **情商 (EQ) 训练与 Reward 设计**：
  - **SFT 阶段**：构建包含共情、情绪支持、礼貌用语的高质量对话数据集。
  - **Reward 设计**：通常采用 **LLM-as-a-Judge** 的方式。使用一个能力更强的模型（如 GPT-4）作为裁判，根据预设的维度（如：同理心、得体性、情绪安抚能力）对模型的输出进行打分作为 Reward。也可以训练一个专门的 Reward Model (RM) 来拟合人类对情商的偏好。
- **流畅度训练与 Reward 设计**：
  - **SFT 阶段**：确保训练语料的语法正确性和表达自然度。
  - **Reward 设计**：可以使用语言模型的**困惑度 (Perplexity, PPL)** 作为惩罚项，PPL 越高说明越不流畅，给予负奖励。也可以结合语法检查工具或 LLM 裁判来评估语言的连贯性和自然度。

### Q33：多轮对话的 SFT 数据要怎么设计？

**A**：设计高质量的多轮对话 SFT 数据需要注意以下几点：
- **角色与格式规范**：采用标准的对话格式（如 ChatML），清晰区分 `System`、`User` 和 `Assistant` 角色。
- **上下文依赖性**：确保对话的后几轮必须依赖前面的历史信息才能正确回答，训练模型处理指代消解（如"他"、"那个"）和话题延续的能力。
- **多样化的轮数与场景**：数据应包含不同长度的对话（从 2 轮到 10+ 轮不等），涵盖任务导向型（如订票、写代码）和闲聊型场景。
- **状态追踪与纠错**：包含用户在中途修改需求或纠正模型错误的对话，训练模型灵活调整和自我纠错的能力。

### Q34：大模型 GRPO 中 reward 的多目标要怎么设计，有多个 loss 怎么防止跷跷板的现象？

**A**：在 GRPO 等强化学习算法中，通常需要同时优化多个目标（如准确性、格式、安全性、流畅度）。
- **多目标 Reward 设计**：
  - 将总 Reward 定义为多个子 Reward 的加权和：$R_{total} = w_1 R_{acc} + w_2 R_{format} + w_3 R_{safety}$。
  - 针对不同目标设计不同的评估方式：规则匹配（格式）、LLM 裁判（准确性/安全性）。
- **防止跷跷板现象（Seesaw Effect）**：
  - **奖励归一化 (Reward Normalization)**：确保不同维度的 Reward 量级和方差一致，避免某个绝对值过大的 Reward 主导了梯度更新。在 GRPO 中，组内标准化（Group-relative normalization）本身就有助于稳定训练。
  - **动态权重调整**：在训练过程中，监控各项指标的收敛情况。如果某个目标下降严重，则动态提高其 Reward 权重。
  - **KL 散度惩罚**：引入与 Reference Model 的 KL 散度惩罚项，限制模型在追求某些特定 Reward 时过度偏离原始分布，从而保护模型的基础能力（如流畅度）。
  - **课程学习 (Curriculum Learning)**：分阶段引入目标。先优化容易冲突的基础目标（如格式和流畅度），稳定后再加入更复杂的认知目标（如逻辑推理）。