# Agent 面试知识手册


<!--more-->

> 本文从已有面试准备笔记中提取所有 Agent 应用开发相关的高频面试题，剔除过时信息后重新整理作答。涵盖多 Agent 架构、记忆系统、RAG、安全、评估、优化等 12 个主题。
>
> 更新日期：2026-07-20

---

# 一、多 Agent 系统设计

## Q1: 多 Agent 系统如何设计？

多 Agent 系统的核心挑战不是"让多个 Agent 跑起来"，而是**如何保证它们协作产出的质量超过单 Agent**。如果设计不当，多 Agent 反而会因为上下文割裂、信息衰减和协调开销导致质量下降。

### 1. 基于 RFC 的任务分解（DAG 化）

入口是一份 RFC/PRD 文档。由 Orchestrator Agent 读取后，将任务拆解为有向无环图（DAG）中的工作单元：

- `id` + `name`：唯一标识
- `deps`：显式依赖关系（**只有真实代码依赖才建边，不做虚假依赖**）
- `acceptance`：可验证的验收标准
- `tier`：复杂度分级（trivial / small / medium / large）

分解铁律：
- 优先产出更少但更聚合的单元（降低 merge 冲突概率）
- 最小化跨单元文件重叠（两个 Agent 不碰同一个文件）
- **测试和实现必须在同一个单元内**（绝不分拆"实现 X"+"测试 X"）

### 2. 分层编排与并行隔离

DAG 决定执行顺序——同层无依赖的单元并行执行，有依赖的等待上游完成后串行推进。每个工作单元运行在独立 worktree 中，保证文件系统级别隔离。

### 3. 按复杂度分级走质量流水线

| Tier | Pipeline |
|------|----------|
| trivial | implement → test |
| small | implement → test → code-review |
| medium | research → plan → implement → test → PRD-review + code-review → review-fix |
| large | ... → final-review（加一道终审门禁）|

### 4. 消除作者偏差——分窗 Agent

**每个阶段跑在独立的 Agent 上下文窗口中**。Research、Plan、Implement、Test、Review 各由不同的 Agent 完成，Reviewer 绝不看到 Implementer 的上下文。这从根本上消除"自己写的代码自己审"的盲区。

### 5. Agent 合并队列

1. Rebase 到 main → 有冲突？捕获完整冲突上下文，驱逐回 implementer
2. 运行全量 build + test → 失败？捕获失败日志，驱逐
3. 通过 → Fast-forward 合入

驱逐不是盲重试——每次都携带完整冲突上下文做智能修复。

### 6. 跨迭代上下文桥接

通过 `SHARED_TASK_NOTES.md` 在迭代间传递进度、已知陷阱和下一步方向。

---

## Q2: 多 Agent 协作有哪些主流架构模式？如何选型？

### 四种协作架构

| 架构 | 通信方式 | 优点 | 缺点 | 适用场景 |
|------|---------|------|------|---------|
| **中心化编排** | Orchestrator 调度子 Agent | 控制流清晰，可控性最强 | Orchestrator 是单点 | **生产系统首选** |
| 顺序流水线 | 上游输出=下游输入 | 最简单，环节独立可替换 | 不能并行/回退 | 流程固定的 Pipeline |
| 辩论对抗 | Agent 交替发言，Judge 仲裁 | 推理质量高 | 延迟×2~3，token 高昂 | 高可靠性关键决策 |
| 去中心化自治 | Agent 间直接 handoff | 灵活可扩展 | **控制流不可预测** | 仅研究原型 |

### Agent 间通信

Agent 间传递**结构化消息**（`sender/receiver/msg_type/task/payload/constraints`），不传自由文本。推荐使用**共享状态池（SharedState）**：所有 Agent 读写同一状态对象，各 Agent 只读需要的字段、只写负责的字段。

### 拆多少 Agent？

- 拆分甜区：**3~5 个**。超过 7 个要警惕通信开销 > 分工收益
- 工具 < 5 个、流程固定、同领域 → 单 Agent + 多工具足够
- 工具 > 10 个、需要交叉验证、中间结果多 → 多 Agent

---

## Q3: 多 Agent MVP 项目怎么开发？

### 四个阶段

**Phase 0：范围收敛（最关键）**
对每个 feature 问："没有这个，用户无法完成核心任务吗？" → 砍到只剩 YES。输出 `MVP_SPEC.md`。

**Phase 1：任务分解**
大模块 → 子任务（2-4 小时粒度）→ 依赖关系图。每个任务必须独立可验证。输出 `PLAN.md`。

**Phase 2：Subagent-Driven 执行循环**
```
[主控 Controller]
  └─ 读 PLAN.md → 串行执行每个任务：
       ① 实现 Agent（TDD + 自我 review + commit）
       ② Spec 检查 Agent（spec 合规，不多不少）
       ③ 质量检查 Agent（仅在 Spec ✅ 后）
       ④ 任务标记完成 → 下一任务
```

**Phase 3：收尾与验收**
最终 Code Review Agent 全局 review + 完整测试。

### 关键规则

- **绝对不并行实现任务** —— 并发写同模块必然冲突
- **实现 Agent 不读历史会话** —— Controller 精确注入，不继承脏历史
- **Spec 检查放在质量检查前** —— 顺序不能乱
- 每个子 Agent 独立超时 + 降级策略，一个挂了不拖垮全局

---

# 二、Agent 记忆系统

## Q4: Agent 知识闭环中，如何决定哪些信息进入向量数据库（长期记忆）、上下文窗口（短期记忆）、模型权重（元记忆）？

### 三层记忆的决策维度

| 维度 | 向量数据库（长期） | 上下文窗口（短期） | 模型权重（元记忆） |
|------|-------------------|-------------------|-------------------|
| 形态 | 事实与数据 | 当前任务正在使用的信息 | 逻辑、模式、技能 |
| 频率 | 偶尔访问的长尾知识 | 秒级/分钟级变化 | 高频通用基础规则 |
| 可变性 | 天/月级，可更新或遗忘 | 秒级/当前会话 | 极少改变的领域公理 |

### 短期记忆（上下文窗口）
- **准入**：当前轮直接输入 / 正在执行的 CoT 暂存 / 工具调用中间结果 / RAG 召回的 Top-K 片段
- **移出**：对话轮次超阈值或任务结束 → 交由记忆管理器提炼

### 长期记忆（向量数据库）
- **准入**：历史对话归档（经 Summarization 后向量化）/ 用户偏好与实体 / 高频事实知识点
- **工程要点**：需配合知识图谱或混合检索（向量+关键词），解决单纯向量检索的逻辑断层

### 元记忆（模型权重）
- **准入**：通用推理范式 / 工具调用语法 / 领域基座知识 / 价值观与语气
- **更新机制**：当高频调用的知识或高质量交互轨迹积累到足够量级 → 触发持续微调（如 LoRA）

### 动态流转闭环

```
上下文窗口（完成任务）
  → 异步抽取事实 + 压缩对话
  → 向量数据库（积累知识）
  → 监控检索频率：高频知识触发微调
  → 模型权重（内化为本能）
  → 释放上下文窗口空间
```

---

## Q5: Agent 记忆系统工程上如何设计？短期记忆和长期记忆各自存在哪？

### 记忆分层架构

| 层级 | 类比 | 载体 | 生命周期 | 容量 |
|------|------|------|----------|------|
| 工作记忆 | CPU 寄存器 | LLM Context Window | 单轮推理 | 取决于模型（2026年主流模型普遍支持 128K~1M+ tokens）|
| 短期记忆 | RAM | 会话状态存储（Redis/内存/SQLite）| 单次会话 | 数十到数百轮对话 |
| 长期记忆 | 硬盘 | 向量数据库 + KV 存储 | 跨会话持久化 | PB 级 |

### 工作记忆管理
- **滑动窗口**：保留最近 N 轮，最简单但会丢关键上下文
- **摘要压缩**：超过阈值时用 LLM 将旧对话压缩为摘要，压缩比约 5:1~10:1
- **分层注入**：System Prompt（常驻）+ 摘要（半常驻）+ 最近 K 轮原文（滑动）+ 检索结果（按需）
- **Attention Sink 保护**：System Prompt 的前几个 token 是注意力锚点，**绝不可被截断**。推荐策略为首尾保留 + 中间压缩（Head + Tail + Compressed Middle）

### 短期记忆（Session Memory）
- **存储位置**：简单方案用内存 `List[Message]`，工程方案用 Redis/DynamoDB/SQLite，以 `session_id` 为 key
- **Scratchpad（草稿板）**：Agent 内部推理区域，存放中间推理、子目标分解、工具调用计划
- **任务栈**：跟踪当前任务、子任务、已完成步骤，防止 Agent 迷失方向
- **压缩触发**：Token 计数 > 0.7 × context_window 或每 N 轮
- **关键坑**：压缩前必须做 fact extraction，用户硬约束单独存储不参与压缩

### 长期记忆（Persistent Memory）
- **存储选型**：PostgreSQL + pgvector（中小规模）、专用向量库（Qdrant/Milvus/Weaviate）+ KV Store
- **写入时机**：会话结束时提取摘要 + facts / 用户显式指令 / 隐式学习（检测到反复纠正 → 提取经验规则）
- **更新与清理**：覆盖更新 + 矛盾检测 + TTL 过期 + LRU 淘汰 + 语义去重（embedding 相似度 > 0.95 合并）+ LLM 定期整理
- **检索注入**：用户新消息 → 向量化 → 长期记忆检索 top-K → 注入 Context → LLM 推理

### 设计原则
- 记忆有成本——不是越多越好
- 写入要克制，检索要精准
- 压缩 ≠ 丢弃——硬约束不能丢
- 矛盾检测必须有——否则 Agent 新旧信息冲突
- Letta（前 MemGPT）将 Context Window 类比虚拟内存，Agent 自主决定记忆换入换出，这是一种值得参考的设计范式

---

# 三、Agent 安全与稳定性

## Q6: Agent 的安全护栏怎么做？安全模型如何选型？

### 分层防御架构

| 层级 | 手段 | 延迟 | 防御目标 |
|------|------|------|----------|
| L0 | 正则/关键词黑名单 | <1ms | 低成本批量攻击 |
| L1 | 轻量安全分类器 | 5~20ms | 毒性/有害意图分类 |
| L2 | System Prompt 安全指令 | 0（内嵌）| 行为边界定义 |
| L3 | 输出审查（小模型分类或主模型自审）| 20ms~2s | 有害输出/幻觉/信息泄露 |
| L4 | **工具调用审计** | 按需 | Agent 最关键层：拦截危险操作 |

### 安全模型选型原则

- **轻量分类器（<1ms，精度~85%）**：适合超高 QPS + 预算受限场景
- **专用安全模型（~20ms GPU，精度~95%）**：**推荐方案**——专为安全分类训练，推荐使用 MLCommons 标准对齐的模型
- **外部 API（~100ms）**：不想自建时使用
- **主模型自审（+500ms~2s）**：语境理解最深，适合高风险领域（医疗/金融）

### 关键设计原则

- **每一层独立防御**，不依赖其他层
- **安全模型必须和主模型异构**——同模型做审查，被 jailbreak 后审查也失效
- **输入审查 + 输出审查缺一不可**
- Agent 最大风险不是"说错话"而是**"做错事"**——工具调用审计（L4）是 Agent 区别于 chatbot 的最关键安全层
- 未知工具默认最高风险级别
- 常见踩坑：只靠 System Prompt = 裸奔；做了输入审查漏了输出审查；安全模型和主模型同源

---

## Q7: Agent 循环终止条件怎么设计？如何避免死循环？

### 根因分类
- **工具幻觉循环**：反复调用同一工具但输出不变，无限 retry
- **目标漂移循环**：每轮生成新子目标，永远无法收敛
- **自我验证循环**：修复→验证失败→再修复，陷入振荡

### 四层防御体系

1. **硬性计数器**：`MAX_STEPS` / `MAX_TOOL_CALLS` / `MAX_SAME_TOOL`，兜底红线，不可软化
2. **语义去重检测**：对 (action, observation) 做 embedding 相似度检测，连续 3 步相似度 > 0.95 → 强制打断
3. **目标收敛性验证**：每 N 步让 LLM 自评进展是否有效，stuck → **replanning**（不是 retry）
4. **时间熔断**：`asyncio.timeout`，超时返回 `partial_result` 而非空结果

### 特殊 Case：代码修复振荡

**模式**：修复 test_A → 破坏 test_B → 修复 test_B → 破坏 test_A → 无限循环

**解法**：引入**变更集去重**——检测文件版本的回滚模式（v0 → v1 → v0），一旦检测到，强制从"单点修复"升级为"全量依赖图分析"策略。

### 设计原则
- 硬限制不可协商，MAX_STEPS 是红线不是建议
- **stuck ≠ retry，stuck = replan**（换方向，不是加力推同一面墙）
- 语义层面去重比计数更有效
- 熔断时返回 partial_result，优于空手而回

---

## Q8: 工具调用失败时如何优雅降级？

### 失败类型拆分

| 失败类型 | 策略 |
|---------|------|
| **硬失败**（500/异常）| 重试 → 降级备选 → 告知用户 |
| **超时** | 取消 → 降级 → 部分结果返回 |
| **空值**（查无数据）| **不是错误，不应重试**。改查询策略或如实反馈 |
| **格式异常** | 日志 + 降级 |

### 降级方式
1. 换备选工具
2. 缩小目标：拿不到完整数据，返回已确认的部分数据
3. 改用已有信息回答：坦白"查不到"，基于上下文给出有限回答
4. 改查询策略再试一次：换参数、改关键词、改过滤条件

### 工程侧关键设计

**结构化错误返回**：
```
ToolResult {
  status: success|warning|error
  error_message: 可操作的错误描述
  fallback_hint: "建议改用 X 工具或缩小查询范围"
  retry_allowed: true|false
}
```

**分级重试策略**：按工具配置 `max_retries` + 指数退避 + fallback 工具链。

**幂等性保障**：**有副作用的操作（send_email/delete/write）绝不重试**，或引入幂等键防重复执行。

### Prompt 侧预编程降级
- 硬失败：最多重试 2 次 → 尝试备选 → 坦诚告知 + 基于已有信息回答
- 空值：不重试同参数 → 改写查询再试一次 → 仍空则如实反馈
- 部分成功：使用已有数据，标注哪些已验证/哪些是推测

### 最大坑
- 把"空值"当"失败"处理 → 无意义重试循环
- 非幂等操作重试 → 重复发邮件/重复下单

---

## Q9: Agent 系统如何实现可观测性？

### Agent 可观测性的特殊挑战

传统系统：输入/逻辑/输出确定。Agent 系统：**四重不确定**（输入 × 决策 × 工具调用 × 输出），"bug"不是代码报错而是决策质量下降。

### 可观测性体系

**Metrics（指标）**：
- 运维指标：延迟 p50/p95/p99、Token 消耗、工具调用次数和错误率、推理循环次数、单次成本
- 质量指标（Agent 专属）：幻觉率、引用准确率、工具选择正确率、回答相关性、检索空结果率

**Structured Event Log**：
- 结构化事件序列（非文本日志），每个事件为 JSON
- 关键：`decision_made` 事件记录 Agent 每个决策点的推理和备选方案

**Agent Trace（决策链追踪）**：
- 追踪完整思考和行动链：`query_understanding → retrieval → decision_point → action → answer_generation → validation`
- 推荐工具：Langfuse（轻量开源）、Phoenix/Arize（通用）、OpenTelemetry（自建）

### 稳定性五道防线
1. **输入防御**：长度限制 + Prompt Injection 检测 + 速率限制 + 意图可行性预判
2. **执行熔断**：max_steps / max_tool_calls / max_llm_calls / max_tokens_total / timeout
3. **输出校验**：安全审查 + 幻觉检测 + 引用一致性 + 置信度标注
4. **降级策略矩阵**：LLM 不可用→缓存/降级模型，检索不可用→纯结构化查询，全不可用→静态 FAQ
5. **灰度发布 + 回滚**：Prompt 版本管理，5% 流量灰度，指标异常一键回滚

### 可观测性成熟度
- L0：基础日志——"在运行吗？"
- L1：结构化事件+指标——"哪个环节慢？"
- L2：Agent Trace+决策审计——"为什么做了这个决策？"
- L3：质量指标+告警——"回答质量是否下降？"
- L4：Session Replay+根因分析——"这个 case 为什么错？同类有多少？"
- **生产至少 L2，目标 L3，L4 是竞争优势**

---

# 四、RAG 系统

## Q10: 混合检索中 BM25 与向量检索如何融合？权重怎么设定？

### 为什么要混合
BM25 擅长精确关键词/专有名词匹配，向量检索擅长同义词/语义意图理解。两者信号正交互补。

### 三种融合方式

1. **Score-level 加权融合**：`final = α × norm(bm25) + (1-α) × norm(vector)`，需要分数归一化
2. **RRF（Reciprocal Rank Fusion）**：`score = Σ 1/(k + rank_i)`，k 通常取 60。不依赖分数分布，**工业界最稳方案**
3. **Learned 融合**：BM25 top-K ∪ Vector top-K → Cross-Encoder Rerank，权重由模型隐式学习

### 权重设定方法
- 经验起点：α ∈ [0.3, 0.5]（BM25 权重），语义占主导
- 有标注数据时 Grid Search 扫 α
- 无标注数据时 RRF 是最佳选择，对超参不敏感
- Query-adaptive：按 query 类型动态调权（关键词型 → BM25 高，自然语言型 → 向量高）

### 关键结论
- RRF 是"懒人最优解"，主流向量数据库（Elasticsearch 8.x+、Qdrant、Weaviate、Milvus）都内置支持
- α 最优值高度依赖 query 分布，无万能值
- 精度要求高 + latency 允许 → Cross-Encoder Rerank 是最终答案

---

## Q11: Cross-Encoder 在 Rerank 中的作用？相比 Bi-Encoder 优劣势？

### 核心区别

- **Bi-Encoder（双塔）**：Query 和 Doc 独立编码为向量，做点积/余弦相似度。Doc 向量可离线预计算，速度极快。但所有语义压到一个向量，丢失细粒度交互。
- **Cross-Encoder（交叉编码器）**：Query 和 Doc 拼接后联合编码，每层 self-attention 都做 query-doc token 级交互。语义理解深，但每个 pair 都要完整 forward，不可预计算。

### Cross-Encoder 精度更高的根因
- Bi-Encoder 的信息瓶颈：所有语义压到一个固定维度向量
- Cross-Encoder 无瓶颈：token 级全交叉注意力，能理解**否定语义、条件约束、细粒度匹配**
- 示例：查询"室温下抗拉强度超过 500MPa 的铝合金"时，Cross-Encoder 能区分温度条件不匹配的文档，Bi-Encoder 很难做到

### 代价对比

| 指标 | Bi-Encoder | Cross-Encoder |
|------|-----------|---------------|
| 延迟 | ~5ms（ANN 检索百万文档）| ~50-100ms（重排 20-50 候选）|
| 可索引性 | 可预计算、可 ANN | 不可预计算、不可建索引 |
| 适用规模 | 全库检索（百万~十亿）| 仅候选精排（10~100 个）|

### 检索-重排 Pipeline
全库 → Stage 1 粗召回（BM25 + Bi-Encoder, top-100）→ Stage 2 精排（Cross-Encoder, top-10）→ Stage 3 业务规则/多样性过滤 → 最终 Top-K

### 选型原则
- 候选数控制在 20~50 个是甜区
- 各 pair 独立，天然可 GPU 并行 batch 推理
- Late Interaction（ColBERT 思路）是精度与速度的折中方案

---

## Q12: 召回效果怎么测试？优化优先级是什么？

### 召回测试指标
- **Recall@K**：top-K 覆盖了多少相关文档（召回阶段核心指标）
- **Hit Rate@K**：至少命中 1 个相关文档的 query 占比
- 召回阶段追求 **Recall（不漏）**，不是 Precision（不错）——漏召了 Rerank 救不回来

### 测试集构建（三类难度）
- 精确查询 → 关键词精确匹配
- 语义改写 → 同义词理解
- 跨表述 → 泛化 + 领域知识

### 召回问题诊断（逐层排查）
原始文档 → 切分 → 编码 → 索引 → 检索策略，每层有对应诊断方法。

### 优化优先级（ROI 从高到低）

1. **Chunk 切分策略（ROI 最高）**：切分是后续所有步骤的基础。推荐 512 tokens + 12.5% 重叠 + 结构感知切分（表格整表不切）
2. **Query 改写/扩展**：同义词扩展、HyDE（假想答案向量检索）、多路查询
3. **Embedding 模型升级**：领域微调用 5000~10000 对数据 + MultipleNegativesRankingLoss
4. **索引参数调优**：通常不是瓶颈，快速检查即可

### 设计原则
- Recall 是召回阶段唯一目标——漏召不可逆
- 先诊断再优化——不要上来就换模型
- **先修数据 → 再调策略 → 最后换模型**——ROI 递减
- Bad Case 驱动优化——线上真实失败 case 最有价值

---

## Q13: RAG 工程最大的坑是什么？

### 问题严重度排名

1. **幻觉**（最致命）：引用格式正确但内容失真，用户无法分辨
2. **召回沉默失败**：系统不报错但答案基于错误文档，比"我不知道"更危险
3. **上下文污染**：多文档矛盾时 LLM 随机选择或错误合并
4. **延迟不可控**：LLM 生成占 90%+ 延迟
5. **数据新鲜度**：知识库腐烂，返回过时信息

### 幻觉防御（三层）
- **Prompt 硬约束**：数值必须标注来源、不同来源数据禁止跨条件组合
- **结构化输出 + 溯源**：每个声明关联 source_id + raw_sentence，可自动比对
- **输出校验**：自动检查来源是否存在、原文是否在文档中、数值是否一致

### 召回沉默失败防御
- 检索结果整体相关性自检（max_sim < threshold → 触发"我不知道"）
- Query-Doc 关键实体对齐
- Prompt 嵌入自检指令

### RAG 工程"铁三角"
**数据质量（地基）→ 检索精度（管道）→ 生成可控性（龙头）**

优先级永远是：**数据 > 检索 > 生成**。大部分团队在生成端调 Prompt 投入过多，回头修数据和检索的 ROI 高得多。

---

## Q14: Rerank 效果怎么评估？NDCG 和 MRR 的区别？

### 核心指标对比

| 指标 | 相关性类型 | 关注重点 | RAG 适用度 |
|------|-----------|---------|-----------|
| MRR | 二值 | 仅第一个相关结果位置 | 低——RAG 需多个文档 |
| MAP | 二值 | 所有相关结果的位置 | 中——二值标注太粗 |
| **NDCG@K** | **多级** | **top-K 整体排序质量** | **高——RAG 首选** |
| Recall@K | 二值 | 相关文档是否被召回 | 高——评估召回阶段 |

### NDCG@K 详解
- `DCG@K = Σ (2^rel_i - 1) / log₂(i+1)`，位置越靠前权重越大
- `NDCG@K = DCG@K / IDCG@K`，归一化到 [0,1]
- 支持多级相关性标注（0-3 分），区分粒度远优于二值指标

### 评估数据集构建
- **人工标注**（金标准）：200~500 条 query，每条 top-50 候选，0-3 级打分
- **LLM 辅助标注**（降本）：必须人工抽检 10~20%
- **隐式反馈**（零成本）：用户点击行为，适合线上持续评估，噪声大

### Rerank 前后典型提升
- BM25 only → NDCG@10 ~0.35
- + Vector hybrid → ~0.42
- + Cross-Encoder Rerank → ~0.50

使用 paired t-test 或 Wilcoxon signed-rank test 验证显著性（p < 0.05）。

### 端到端评估
离线排序指标好 ≠ 最终回答好。需同时评估 Answer Faithfulness / Relevance（LLM-as-Judge）、Context Precision / Recall。推荐框架：ragas。

---

# 五、工具与协议

## Q15: MCP 与传统 Agent Skills 的区别？

MCP（Model Context Protocol）由 Anthropic 提出，已逐渐成为 Agent 工具交互的行业标准。核心区别：

| 维度 | 传统 Agent Skills | MCP |
|------|------------------|-----|
| 架构 | 强耦合，工具和 Agent 同进程 | C/S 架构，JSON-RPC 通信，语言无关 |
| 能力范畴 | 仅"动作"（Function）| Resources（数据）+ Tools（动作）+ Prompts（模板）|
| 安全性 | 工具在 Agent 进程内运行，Prompt Injection 风险高 | 独立沙箱，Agent 只能发请求，安全边界清晰 |
| 生命周期 | 静态：所有 Tool Schema 硬塞进 System Prompt | **动态能力发现**：`tools/list` 拉取当前可用工具清单 |
| 生态 | 框架锁定（LangChain/AutoGen 等）| 协议标准，跨框架复用 |

### 跨协议工具动态发现与注册

核心架构：**Agent Tool Registry & Gateway**

1. **适配层（Universal Tool Gateway）**：将 REST/gRPC/GraphQL 等异构协议统一转换为 MCP 或标准 Function Calling 格式
2. **注册层（Tool Registry）**：工具元数据（name/description/schema/tags）+ Embedding 向量化存入向量数据库
3. **发现层（Dynamic Discovery）**：Agent 收到复杂 Query → 向 Registry 发语义搜索 → 动态匹配相关工具 → 热加载 Schema → 调用
4. **执行与反馈层**：跨 Agent 调用可封装为黑盒 API、工具健康度监控与降级

核心思想：Agent 不预装所有工具，而是**按需发现和加载**。一个模糊的用户请求（如"预算 5000 给老婆买礼物，她在玩单机大作"）→ Agent 语义搜索 Registry → 动态发现"游戏设备推荐 + 库存查询 + 物流时效"三个工具 → 加载并执行。

---

# 六、Agent 评估与优化

## Q16: Agent 的评估流怎么设计？

遵循 **Eval-First Loop** 方法论：在写代码之前，先定义"什么叫做完"和"什么叫做对了"。

### 双层 Eval
- **Capability Eval**：针对新功能的验收用例（正常路径 + 边界条件 + 异常输入）
- **Regression Eval**：所有已有功能的测试套件（防止回退）

### 执行流程
1. 跑基线，记录失败签名（失败类型 + 根因假设 + 最小复现步骤）
2. 实现 Agent 按计划执行，每次变更后自动触发 eval 重跑
3. Delta 分析：修复了哪些 regression？引入了哪些？
4. 结构化观察：每个工具调用返回 `status + summary + next_actions + artifacts`

### 核心追踪指标
- completion rate（任务完成率）
- pass@1 / pass@3（一次/三次内通过率）
- retries per task
- cost per successful task
- failure class distribution（用于定位系统性问题）

---

## Q17: 如何优化 Agent，提高任务完成率？

优化 Agent 不是调 prompt 玄学，是按**四个维度**系统性排查：

### 维度一：Action Space（动作空间）
- **粒度调优**：高风险操作用 micro-tool，中频操作用 medium-tool，只在 round-trip 开销成为瓶颈时用 macro-tool
- **消除语义重叠**：两个名字不同但能力相似的 tool 会让 Agent 犹豫
- **输出确定性**：每个 tool 的返回 shape 必须稳定

### 维度二：Observation Quality（观察质量）
- 所有工具输出统一为 `status + summary + next_actions + artifacts`
- 错误返回必须包含**可操作的恢复信息**，不是只抛 error code
- 减少噪音：日志输出只保留对决策有用的信息

### 维度三：Error Recovery（错误恢复）——最大杠杆
- 建立**失败模式分类体系**，每个分类有预设恢复策略
- **自省调试（Introspection Debugging）**四阶段：
  1. Failure Capture：精确记录错误类型、最后成功步骤、环境假设
  2. Root-Cause Diagnosis：匹配已知失败模式
  3. Contained Recovery：用最小的可逆操作验证诊断
  4. 三次尝试仍无进展 → 止损升级，向人类报告完整诊断链
- 每种重试都有**明确的停止条件**

### 维度四：Context Budget（上下文预算）
- 系统 prompt 最小化且不变，大段指导放到按需加载的 skill
- Phase 边界做上下文压缩
- 大文件用 reference 而非 inline
- Lost-in-the-middle 效应是真实存在的，信息密度比信息量重要

### 进阶手段
- **模型路由**：按任务复杂度选择合适模型（简单分类用小模型，架构分析用强模型），不在简单任务上浪费昂贵模型
- **De-Sloppify 模式**：Implementer 充分实现 + Cleanup Agent 专门精简，两个聚焦的 Agent 胜过三个被约束的 Agent
- **Verification Loop**：每次变更后自动跑构建+lint+测试，验证结果作为下一个步骤的输入

### 实战思路
不是从"改 prompt"开始，而是先看数据：哪类任务完成率最低？失败集中在哪个阶段？工具调用错误、逻辑推理错误还是环境问题？数据定位瓶颈，再用针对性手段解决。**这是工程师的做法，不是 prompt engineer 的做法。**

---

## Q18: Critical Agent（评价 Agent）怎么设计？

### 模型选择 —— 不能省

| 角色 | 模型策略 | 原因 |
|------|---------|------|
| 实现 Agent | 中等级别可接受 | 生成能力为主 |
| Spec 检查 Agent | **必须用最强模型** | 需要精确比对和推理 |
| 质量 Review Agent | **必须用最强模型** | 需要识别反模式、安全漏洞 |

**LLM-as-Judge 的系统性偏差**：
- Sycophancy bias：较弱模型倾向于认为输出"看起来不错"而通过
- Verbosity bias：更长的输出被认为更好
- Self-enhancement bias：同模型评价自己产出时倾向于赞同

**结论：便宜 Judge = 质量门失效。实现 Agent 可以省，评价 Agent 不能省。**

### Prompt 设计原则

**核心：把判断转化为核查清单，不要开放式评价。**

- 提供 Spec + 实现 + 证据三件套，缺一不可
- 强制先推理后结论（CoT before verdict）
- 显式校准语："保守判断"、"需要证据" —— 对抗 sycophancy
- 维度分离：Spec 合规 vs 质量是两个独立评价

### 四层评价体系（层级越高越可靠）

| 层级 | 内容 | 可靠性 |
|------|------|--------|
| L1 产物存在性 | 文件存在？语法正确？| 弱，易造假 |
| L2 规格合规性 | 实现 == 规格？| 基础，需 Judge Agent |
| L3 执行证据 | 测试实际跑通？| 可靠 |
| L4 对抗性验证 | Red Team Agent 找反例 | 最强 |

### 失败分类与响应

```
SPEC_MISMATCH    → 重新澄清 spec，重派实现 Agent
INCOMPLETE       → 把缺失部分拆成新任务
QUALITY_FAILURE  → 派 fix Agent 针对性修复
PROCESS_FAILURE  → 修复流程违规
EXECUTION_FAILURE → 升级模型 or 人工介入，不盲目重试
```

---

# 七、Harness Engineering

## Q19: 给 Agent 加约束应该"多多益善"还是"只设必要边界"？

**不应该多多益善**。约束叠加边际效益递减，但复杂度成本是乘法的。

### 两种失败模式决定边界

**结构性失败**（来自架构本身，scaling 无法消除）
- Attention sink、lost-in-middle、entropy collapse
- 这类约束是合理的 —— 有明确物理意义

**能力性不足**（训练/数据不足，随模型迭代改善）
- 不会用工具、不会拆步骤、不会自我纠错
- 很多 Agent 框架填补的是这类 gap
- **模型进化后，这些 harness 就成了技术债**

### 边界判断标准

该加约束：
- 针对不会随 scaling 消失的结构性失败
- 有可观测、量化的信号驱动
- 约束是 adaptive 的，不干涉模型本身的泛化能力

不该加约束：
- 在修补症状而非根因
- 约束是静态的，不随 context 动态调整
- 多个约束互相干涉，制造新的脆弱点

### 实操原则
1. **先测基线** —— 去掉 harness 之后 delta 是否值得其复杂度？
2. **信号驱动** —— 约束触发必须有量化信号，不要凭直觉硬编码
3. **保留卸载路径** —— 每个约束加入时就想好"如何移除"
4. **最少惊喜原则** —— 约束不能比模型原生行为更不可预测

---

## Q20: Skill 开发有什么方法论？

### Skill 的本质
Skill 是**契约**（输入契约、行为契约、输出契约），不是 Prompt 堆砌。决定 Agent 上限的是边界设计，不是步骤数量。

### 五大设计原则
1. **单一触发、单一职责**：一个 Skill 做一件事
2. **触发条件可判定**：像正则一样明确
3. **显式声明 DO NOT**：不做什么比做什么更重要
4. **输出格式刚性约束**：不写死格式，下游没法可靠消费
5. **上下文最小充分**：指导精准获取，不贪婪加载

### 开发工作流
1. **用例故事先行**：写 3-5 个正例 + 反例，反例定义边界
2. **最小可用版本**：先 20 行跑一遍，别上来就写 200 行
3. **失败驱动迭代**：根据症状定位根因
4. **反测试验证**：喂不该触发的输入，验证确实不激活

### Skill 成熟度模型
- L0 原始 → L1 结构化 → L2 边界清晰 → L3 可组合 → L4 生产级
- **大多数卡在 L1→L2**：因为画边界不如加功能有成就感

### 核心认知
Skill 设计 = 微服务设计：高内聚、低耦合、显式契约、明确边界。唯一区别：微服务靠代码强制边界，Skill 靠语言描述——执行者是会自由发挥的 LLM，所以必须写得更精确。

---

## Q21: 大模型辅助开发效率提升有哪些实践？

### 使用场景 ROI 排序
- ⭐⭐⭐⭐⭐ 样板代码生成（数据类/CRUD/测试用例）5~10x
- ⭐⭐⭐⭐⭐ Debug 辅助（报错信息→修复方案）3~5x
- ⭐⭐⭐⭐ 代码理解（读陌生代码库）3~5x
- ⭐⭐⭐⭐ 文档/注释生成 3x
- ⭐⭐⭐ 架构讨论（当橡皮鸭）2x
- ⭐⭐ 复杂算法实现（框架可用但细节需审）1.5x
- ⭐ 核心业务逻辑（不理解业务上下文）1x 甚至负

### 高效使用模式
1. 给现有代码风格 + 新需求 → LLM 生成初版 → review 修改
2. 报错信息直接喂 LLM：附带上下文（代码片段 + 环境 + 已试方案）
3. 代码审查辅助：重点关注边界条件、空值处理、并发安全
4. 测试用例生成：给实现代码 → 生成覆盖 happy path + edge case 的测试
5. Meta-prompting：用 LLM 帮优化 Prompt

### 教训和红线
- **盲信 LLM 代码是最大的坑** —— 必须 100% review，尤其边界条件和并发
- LLM 做不了需要权衡的架构决策 —— 它是执行工具不是决策者
- 上下文给太少 → 输出质量差；Prompt 太长 → LLM 选择性忽略。拆成多步更好
- **红线**：安全代码、线上 DB 操作、不理解就用、替代人工审查

### 核心认知
- LLM 是**放大器**不是替代器——放大已有能力，不替代缺失知识
- ROI 最高："结构清楚但写起来无聊"的代码
- ROI 最低："需要深度领域知识和权衡判断"的工作
- LLM 生成的代码 = 初级工程师的初稿——需要 senior review

---

# 附录：本文与原文对照

本文整合自以下笔记，剔除了过时内容并重新作答：

| 来源 | 原内容 | 更新说明 |
|------|--------|---------|
| 20260323.md | 多Agent系统/评估流/优化 | 补充了完整架构细节 |
| 20260327.md | 知识闭环/Attention Sink/MCP | 泛化了模型版本号，补充了 MCP 生态演进 |
| 20260407.md | 15个话题（RAG/安全/记忆/协作等）| 修正 Context Window 数据范围，泛化具体模型引用 |
| 20260409.md | Harness边界/MVP开发/Critical Agent | 保持核心逻辑，微调了时间敏感的参考 |

**主要剔除/更新的过时内容：**
1. Context Window 上限从 "200K" 更新为反映 2026 年主流模型普遍支持 128K~1M+ tokens 的现状
2. 具体模型版本号（如 "Llama Guard 3 (1B)"、"bge-m3"、"Cohere Rerank v3"）→ 泛化为原理性选型指导
3. "MemGPT" → 更新为 Letta 的发展现状
4. 部分时间敏感的框架引用 → 替换为更稳定的架构描述


---

> 作者: [破戒僧](https://onlyblacktea.cn)  
> URL: https://onlyblacktea.cn/posts/agent-interview-handbook/  

