📖 AI Agent 与 RAG 面试专题¶
⚠️ 时效性说明:本章涉及前沿模型/价格/榜单等信息,可能随版本快速变化;请以论文原文、官方发布页和 API 文档为准。
⚠️ 来源说明(2026-04-03):本页仍以知识结构化讲解为主;如果你想对照 2025-2026 公开面经里的真实高频追问和公司级题目清单,请配合 27-2025-2026大厂真实面经题型地图、29-2025-2026大厂公开面经题目全量索引 和 28-题目真实性与来源维护说明 一起使用。
重要性:⭐⭐⭐⭐⭐(近两年 AI 岗位高频方向之一) 难度:⭐⭐⭐⭐ 学习时间: 2-3 天 前置知识: LLM 基础、 Prompt 工程、向量数据库
📚 目录¶
- Part A : AI Agent 面试题( 10 道)
- Part B : RAG 系统面试题( 10 道)
- Part C :综合系统设计题( 3 道)
- Part D : 2025-2026 真实高频追问补充( 4 道)
Part A : AI Agent 面试题¶
Q1 :什么是 AI Agent ?它与传统 Chatbot 的本质区别是什么¶
参考答案:
AI Agent 可以理解为“以大模型为核心,并按任务需要接入工具、状态管理和执行控制”的系统形态。很多 Agent 系统会具备感知-规划-行动-反思中的一部分或全部能力,但不同实现成熟度差异很大。核心区别:
| 维度 | Chatbot | AI Agent |
|---|---|---|
| 交互模式 | 单轮/多轮对话 | 自主规划+多步执行 |
| 工具使用 | 无 | 可调用 API/数据库/代码执行器 |
| 记忆 | 上下文窗口内 | 短期+长期记忆系统 |
| 决策 | 被动响应 | 主动分解任务、自主决策 |
| 反思 | 无 | 可自我评估、纠错、迭代 |
Agent 核心组件:
追问: Agent 的"幻觉"和 Chatbot 的"幻觉"有什么不同? → Agent 幻觉更危险:会导致错误的工具调用、错误的代码执行等实际行为后果
Q2 :解释 ReAct 框架的工作原理及其优势¶
参考答案:
ReAct = Reasoning + Acting ,交替进行推理和行动:
循环:
1. Thought(推理): 分析当前状态,决定下一步
2. Action(行动): 调用工具/API执行操作
3. Observation(观察): 获取工具返回结果
4. 重复直到完成任务
# ReAct伪代码
def react_agent(query, tools, llm):
history = []
for step in range(max_steps):
# Thought: LLM推理
thought = llm.generate(f"Query: {query}\nHistory: {history}\nThought:")
# Action: 选择并执行工具
action = llm.generate(f"...Action:")
tool_name, tool_input = parse_action(action)
# Observation: 获取结果
observation = tools[tool_name].run(tool_input)
history.append((thought, action, observation))
if is_final_answer(thought):
return extract_answer(thought)
优势: - 可解释性:每步推理可见 - 纠错能力:观察结果后可调整策略 - 通用性:适用于各种工具组合
追问: ReAct 的缺点是什么?如何改进? → 缺点:推理链过长、 token 消耗大、容易陷入循环。改进: Reflexion (加反思)、 LATS (树搜索)、 Plan-and-Execute (先规划再执行)
Q3 :如何设计 Agent 的工具调用(Tool Use)系统¶
参考答案:
工具调用系统设计要点:
1. 工具描述标准化:
{
"name": "search_database",
"description": "搜索产品数据库,返回匹配的产品列表",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "搜索关键词"},
"category": {"type": "string", "enum": ["电子", "服装", "食品"]},
"max_results": {"type": "integer", "default": 10}
},
"required": ["query"]
}
}
2. 工具选择策略: - 静态选择:预定义工具集 - 动态选择:根据 query 检索相关工具(工具较多时通常更合适) - 分层选择:先选类别再选具体工具
3. 安全机制: - 权限控制(只读/读写/管理员) - 参数验证(防注入) - 调用频率限制 - 人工确认高风险操作
4. 错误处理:
def safe_tool_call(tool, params, max_retries=3):
for attempt in range(max_retries):
try: # try/except捕获异常
result = tool.execute(params)
if validate_result(result):
return result
# 结果无效,让LLM修正参数
params = llm_fix_params(tool, params, result)
except ToolError as e:
if attempt == max_retries - 1:
return f"工具调用失败: {e}"
params = llm_handle_error(tool, params, e)
追问: MCP 协议如何解决工具互操作性问题? → MCP 试图定义标准化的 Tool/Resource/Prompt 接口,让不同客户端与工具服务之间减少重复对接成本。更严谨地说,它更像一套“统一协议层”,而不是物理接口式的一键通用承诺。
Q4 : LangGraph 与 CrewAI 的设计哲学差异¶
参考答案:
| 维度 | LangGraph | CrewAI |
|---|---|---|
| 核心抽象 | 图(Graph) — 状态机 | 角色(Crew) — 团队协作 |
| 流程控制 | 显式定义 Node/Edge/条件路由 | 声明式 Task→Agent 映射 |
| 状态管理 | 强 — 内置 State + Checkpoint | 弱 — 依赖上下文传递 |
| 适用场景 | 复杂工作流/需持久化/需人工审批 | 快速搭建多角色协作 |
| 灵活性 | 极高(可定义任意图拓扑) | 中等(线性/层级流程) |
| 学习曲线 | 陡峭 | 平缓 |
| 工程成熟度 | 较适合状态复杂、需要持久化和可恢复的流程 | 较适合快速搭原型或较轻量的协作流程 |
选型建议: - LangGraph:更适合复杂分支/循环/人机交互/持久化要求较强的流程 - CrewAI:更适合快速原型/多角色模拟/简单任务编排 - AutoGen:常见于研究、实验或对话式多 Agent 原型
追问:如果让你选一个框架做生产系统,选什么?为什么?
Q5 : MCP 协议的设计理念和架构是什么¶
参考答案:
MCP (Model Context Protocol) 是由 Anthropic 首先公开推动的一条协议路线,目标是把模型客户端与外部工具/数据源之间的交互做成更统一的协议层。
核心设计理念:将工具集成从 N×M 问题简化为 N+M 问题 - 之前: N 个 Agent 框架 × M 个工具 = N×M 种集成 - 之后: N 个 Client + M 个 Server = N+M 种实现
架构:
┌─────────────┐ ┌─────────────┐
│ MCP Client │ │ MCP Server │
│ (Agent/IDE) │←───→│ (Tool/Data) │
│ │JSON │ │
│ - Desktop │RPC │ - GitHub │
│ - IDE/CLI │ │ - DB │
│ - Custom │ │ - API │
└─────────────┘ └─────────────┘
三大能力: 1. Tools: Server 暴露可调用的函数(如 search/create/delete ) 2. Resources: Server 暴露可读取的数据(如文件/数据库记录) 3. Prompts: Server 提供预设的 Prompt 模板
传输层: stdio (本地)/ SSE (远程)/ HTTP
追问: MCP 与 Function Calling 有什么区别? → Function Calling 更像模型 API 暴露结构化工具调用的一类接口形式; MCP 更像客户端与工具服务之间的协议层。两者经常一起使用,但并不是严格的上下位包含关系。
Q6 :如何处理 Agent 的幻觉和错误循环¶
参考答案:
幻觉类型: 1. 工具幻觉:调用不存在的工具/参数 2. 结果幻觉:编造工具返回结果 3. 推理幻觉:错误的逻辑推理链 4. 循环幻觉:重复相同操作不收敛
解决策略:
class AgentGuardrails:
def __init__(self, max_steps=15, max_retries=3):
self.max_steps = max_steps
self.max_retries = max_retries
self.action_history = []
def check_loop(self, action):
"""检测重复动作循环"""
recent = self.action_history[-5:]
if recent.count(action) >= 3:
return True # 循环检测
return False
def validate_tool_call(self, tool_name, params, available_tools):
"""验证工具调用合法性"""
if tool_name not in available_tools:
return False, f"工具{tool_name}不存在,可用: {list(available_tools.keys())}"
schema = available_tools[tool_name].schema
return validate_params(params, schema)
def force_reflection(self, agent, history):
"""强制反思(每N步或出错时)"""
prompt = f"回顾执行历史,评估进展:\n{history}\n\n你是否在正确的方向上?是否需要改变策略?"
return agent.llm.generate(prompt)
常见稳妥做法: 1. 限制最大步数(防止无限循环) 2. 工具白名单+参数校验(防止幻觉调用) 3. 周期性强制反思(每 3-5 步) 4. 观察值验证(工具结果后置检查) 5. 人类兜底(关键决策人工确认)
Q7 :多 Agent 系统的通信和协调策略有哪些¶
参考答案:
通信模式: 1. 中心化: Orchestrator 统一调度,各 Agent 只与中心通信 2. 去中心化: Agent 之间直接 P2P 通信 3. 广播式:消息发送到共享空间,所有 Agent 可见 4. 层级式: Manager → Team Lead → Worker 分层管理
协调策略: | 策略 | 描述 | 适用场景 | |------|------|----------| | 顺序传递 | A→B→C ,链式处理 | 流水线任务 | | 分派聚合 | Master 分派子任务→Worker 并行→汇总 | 大规模数据处理 | | 辩论共识 | 多 Agent 讨论→投票/共识 | 需要多视角决策 | | 竞争选优 | 多 Agent 独立完成→选较优结果 | 创意生成 | | 反馈循环 | Writer→Reviewer→Writer 迭代 | 内容生产 |
追问: A2A 协议和 MCP 的关系? → MCP 解决 Agent↔Tool 通信; A2A (Agent-to-Agent) 解决 Agent↔Agent 通信,两者互补
Q8 : Agent 的安全性如何保证¶
参考答案:
安全威胁矩阵: | 威胁 | 描述 | 防御 | |------|------|------| | Prompt 注入 | 用户输入覆盖系统指令 | 输入清洗/指令隔离 | | 工具滥用 | Agent 被诱导执行危险操作 | 权限最小化/审批流程 | | 数据泄露 | Agent 暴露敏感信息 | 输出过滤/数据脱敏 | | 供应链攻击 | 恶意 MCP Server | Server 认证/沙箱隔离 | | 资源耗尽 | 无限循环消耗 Token/API | 预算限制/超时机制 |
核心安全架构:
关键实践:权限最小化、沙箱执行、操作审计日志、敏感操作人工确认
Q9 :如何评估 Agent 的性能¶
参考答案:
评估维度: | 维度 | 指标 | 测量方式 | |------|------|----------| | 任务完成率 | 成功完成/总尝试 | 自动化测试集 | | 步骤效率 | 平均步数/成功步数比 | 日志分析 | | 工具使用准确率 | 正确调用/总调用 | 日志分析 | | 推理质量 | 推理链逻辑正确 | 人工评估/LLM-as-Judge | | 端到端延迟 | 从输入到最终输出 | 时间戳 | | 成本效率 | Token 消耗/成功任务 | 计费 API | | 鲁棒性 | 对抗样本表现 | 红队测试 |
常用评估基准: - SWE-Bench:代码 Agent ,在真实 GitHub Issue 上测试 - WebArena: Web 操作 Agent - AgentBench:综合 Agent 评测 - HumanEval+:代码生成+执行 Agent - GAIA:通用 AI 助手评测
追问: LLM-as-Judge 评估 Agent 有什么局限? → 评判 LLM 自身能力上限、成本高、对长推理链评估不可靠、需要结合 rule-based 指标
Q10 :设计一个企业级 AI Agent 系统(系统设计题)¶
设计要求:为一家电商公司设计智能客服 Agent 系统,日均 10 万询问。
参考答案(简要框架):
┌─────────────┐
│ API Gateway│
│ (限流/认证) │
└──────┬──────┘
│
┌──────▼──────┐
│ Router Agent│
│ (意图识别) │
└──────┬──────┘
┌────────────┼────────────┐
┌─────▼─────┐ ┌───▼────┐ ┌─────▼─────┐
│ FAQ Agent │ │Order │ │Complaint │
│(RAG检索) │ │Agent │ │Agent │
└───────────┘ │(API调用)│ │(工单系统) │
└────────┘ └───────────┘
关键设计点: 1. 分层路由:先意图分类,再分发到专业 Agent 2. RAG 知识库:商品/政策 FAQ + 历史工单 → 混合检索 3. 工具集成:订单系统/物流 API/退款 API/工单系统 4. 人工兜底:置信度<0.7 或 敏感操作自动转人工 5. 缓存策略:高频问题 LRU 缓存 + 语义缓存(Embedding 相似度) 6. 监控告警:满意度/解决率/转人工率/成本 实时 Dashboard 7. A/B 测试:不同 Agent 策略灰度对比
Part B : RAG 系统面试题¶
Q1 : RAG 系统的完整架构和各组件作用¶
参考答案:
文档 → [加载器] → [分割器] → [Embedding] → [向量库]
↓
用户Query → [Query改写] → [检索器] → [重排序] → [上下文]
↓
[Prompt模板] + [LLM] → 回答
| 组件 | 作用 | 常用工具 |
|---|---|---|
| 文档加载 | 解析 PDF/Word/HTML 等 | Unstructured/PyMuPDF |
| 文本分割 | Chunk 策略 | RecursiveCharacterSplitter/语义分割 |
| Embedding | 文本→向量 | BGE-M3 / text-embedding-3 / Jina 等候选 |
| 向量数据库 | 存储+检索 | Milvus/Qdrant/pgvector/托管向量服务等候选 |
| 检索器 | 查询匹配 | 向量检索/BM25/混合检索 |
| 重排序 | 精排 | BGE-Reranker/Cohere Rerank |
| LLM 生成 | 基于上下文回答 | 通用或领域模型(按语言、成本、时延与合规要求选) |
Q2 :如何选择 Embedding 模型和向量数据库¶
参考答案:
Embedding 选型: | 模型 | 维度 | 中文 | 多语言 | 推荐场景 | |------|------|------|--------|----------| | BGE-M3 | 1024 | ✅ | ✅ | 中文和多语言检索中的常见候选 | | text-embedding-3-large | 3072 | ✅ | ✅ | 商业 API 路线中的常见候选 | | Jina-embeddings-v3 | 1024 | ✅ | ✅ | 长文档/代码 | | GTE-Qwen2 | 1024 | ✅ | ✅ | 开源高性价比选择之一 |
向量库选型: | 数据库 | 规模 | 特点 | 推荐场景 | |--------|------|------|----------| | Chroma | <100 万 | 轻量/嵌入式 | 原型/小项目 | | Qdrant | 百万级 | Rust 实现/高性能 | 中型生产 | | Milvus | 十亿级 | 分布式/GPU 加速 | 大规模企业 | | Pinecone | 任意 | 全托管/零运维 | SaaS 优先 |
选型决策:数据规模 → 是否自托管 → 性能要求 → 预算
Q3 : Chunk 策略如何选择¶
参考答案:
| 策略 | 原理 | 优点 | 缺点 | 适用 |
|---|---|---|---|---|
| 固定长度 | 按字符数切分 | 简单快速 | 可能切断语义 | 结构化文档不多时 |
| 递归分割 | 按段落→句子→字符递归 | 通常能较好兼顾结构与实现复杂度 | 参数调优 | 通用场景的常见起点 |
| 语义分割 | 按 Embedding 相似度聚类 | 语义保持通常更好 | 计算量大 | 长文档/混合内容 |
| 按标题分割 | 按 Markdown/HTML 标题 | 保持文档结构 | 需结构化文档 | 文档/Wiki |
| 滑动窗口 | 重叠分割 | 减少信息丢失 | 存储增加 | 需要高召回 |
# 常见起点:递归分割 + 滑动窗口
from langchain_text_splitters import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=512, # 512-1024 token适合大多数场景
chunk_overlap=50, # 10%重叠
separators=["\n\n", "\n", "。", ".", " "],
length_function=len
)
追问:小 Chunk vs 大 Chunk 如何选? → 小 Chunk(256-512)检索精度高但可能缺语境;大 Chunk(1024-2048)语境完整但可能引入噪声。可以用 Parent-Document 策略:小 Chunk 检索,返回对应的大 Chunk 。
Q4 :混合检索的实现原理¶
参考答案:
def hybrid_search(query, k=10, alpha=0.7):
"""
混合检索 = 向量检索 + 关键词检索 + 重排序
alpha: 向量检索权重
"""
# 1. 向量检索(语义相似)
vector_results = vector_db.search(
embedding=embed(query), top_k=k*2
)
# 2. 关键词检索(精确匹配)
bm25_results = bm25_index.search(query, top_k=k*2)
# 3. 分数融合(RRF - Reciprocal Rank Fusion)
fused = reciprocal_rank_fusion(
[vector_results, bm25_results],
weights=[alpha, 1-alpha]
)
# 4. 重排序
reranked = reranker.rerank(query, fused[:k*2]) # 切片操作:[start:end:step]提取子序列
return reranked[:k]
def reciprocal_rank_fusion(results_lists, weights, k=60):
"""RRF融合公式:score = Σ weight / (k + rank)"""
scores = {}
for results, weight in zip(results_lists, weights): # zip并行遍历多个可迭代对象
for rank, doc in enumerate(results): # enumerate同时获取索引和值
scores[doc.id] = scores.get(doc.id, 0) + weight / (k + rank + 1)
return sorted(scores.items(), key=lambda x: -x[1]) # lambda匿名函数:简洁的单行函数
为什么常考虑混合检索: - 向量检索擅长语义匹配但可能遗漏关键词精确匹配 - BM25 擅长关键词匹配但不理解语义 - 混合后常能形成互补;是否明显提升,取决于语料、query 分布和重排序质量
Q5 : GraphRAG 的原理和优势¶
参考答案:
GraphRAG 可以理解为“知识图谱 + RAG”的一类公开路线,早期公开实现中有 Microsoft Research 的代表性工作。
核心流程: 1. 文档→知识图谱: LLM 提取实体和关系,构建图 2. 社区检测: Leiden 算法对图聚类 3. 社区摘要:为每个社区生成高层摘要 4. 查询时: - Local Search :从实体出发,遍历邻居子图 - Global Search :利用社区摘要回答全局问题
优势: | 维度 | 普通 RAG | GraphRAG | |------|---------|----------| | 全局问题 | ❌ 差(只能检索局部片段) | ✅ 强(社区摘要覆盖全局) | | 实体关系 | 隐含在文本中 | 显式建模 | | 多跳推理 | ❌ 弱 | ✅ 强(图遍历) | | 构建成本 | 低 | 高(需 LLM 提取知识图谱) | | 维护成本 | 低 | 中(图更新) |
追问:什么时候用普通 RAG 就够了,什么时候需要 GraphRAG ? → FAQ/单文档问答用普通 RAG ;需要跨文档关联推理、回答"总结所有..."类全局问题时用 GraphRAG
Q6 : RAGAS 评估框架的核心指标¶
参考答案:
| 指标 | 含义 | 评估什么 | 是否需 Ground Truth |
|---|---|---|---|
| Faithfulness | 回答是否基于检索的上下文 | 幻觉程度 | 否 |
| Answer Relevancy | 回答与问题的相关性 | 答案质量 | 否 |
| Context Precision | 检索结果中相关文档的排位 | 检索精度 | 是 |
| Context Recall | Ground Truth 是否被检索到 | 检索召回 | 是 |
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy, context_precision, context_recall
result = evaluate(
dataset=eval_dataset, # questions + contexts + answers + ground_truths
metrics=[faithfulness, answer_relevancy, context_precision, context_recall]
)
print(result) # {'faithfulness': 0.85, 'answer_relevancy': 0.92, ...}
其他常用指标: - MRR (Mean Reciprocal Rank):第一个正确结果的排名倒数 - NDCG:考虑排名位置的相关性 - Hit Rate: top-k 中是否包含正确答案 - 端到端准确率:人工标注正确/错误
Q7 :如何处理 RAG 中的幻觉问题¶
参考答案:
幻觉来源与对策:
| 来源 | 原因 | 对策 |
|---|---|---|
| 检索失败 | 相关文档未被检索到 | 混合检索/Query 扩展/HyDE |
| 上下文噪声 | 检索到不相关内容 | 重排序/上下文压缩/过滤 |
| LLM 臆造 | 模型倾向于"编造"答案 | 提示词约束/后处理验证 |
| 信息冲突 | 多个源信息矛盾 | 时间戳排序/置信度加权 |
关键技术:
# Prompt约束模板
SYSTEM_PROMPT = """
基于以下上下文回答问题。规则:
1. 只使用上下文中的信息
2. 如果上下文不包含答案,明确说"根据现有资料无法回答"
3. 引用来源:[来源: 文档名]
4. 不要推测或补充上下文中没有的信息
上下文:
{context}
"""
# 后处理:NLI验证
def verify_faithfulness(answer, context, nli_model):
"""用NLI模型验证回答是否被上下文支持"""
claims = extract_claims(answer) # 拆分为原子声明
for claim in claims:
result = nli_model.predict(premise=context, hypothesis=claim)
if result == "contradiction":
return False, claim # 发现幻觉
return True, None
Q8 :多模态 RAG 如何设计¶
参考答案:
文档(含图片/表格/公式)
↓
[多模态解析器]
├── 文本 → Text Embedding
├── 图片 → Vision Embedding (CLIP/SigLIP)
├── 表格 → 结构化解析 → Text Embedding
└── 公式 → LaTeX转文本 → Text Embedding
↓
[统一向量库] ← 带元数据(类型/页码/位置)
↓
检索 → [多模态LLM] (按任务选择的多模态模型) → 回答
关键挑战: 1. 对齐:文本和图像的 Embedding 空间对齐 2. 解析:图表/流程图的准确提取 3. 推理:需要同时理解文本和视觉信息 4. 存储:多模态数据的高效索引
Q9 : RAG vs 微调,什么场景选什么¶
参考答案:
| 维度 | RAG | 微调 |
|---|---|---|
| 知识更新 | 实时(换文档即可) | 需重新训练 |
| 成本 | 检索+推理成本 | 训练成本(一次性) |
| 幻觉 | 较少(有源可查) | 较多(知识嵌入模型) |
| 适用 | 事实性 QA/知识库/客服 | 风格适配/领域术语/格式控制 |
| 数据量 | 任意(作为检索库) | 需要高质量标注数据 |
| 可溯源 | ✅ 可引用来源 | ❌ 不可溯源 |
常见组合方案: RAG + 微调结合 - 微调:让模型学会领域术语、输出格式、推理风格 - RAG :提供外部知识与可溯源事实
Q10 :设计一个支持 10 万文档的企业 RAG 系统¶
参考架构:
┌──────────────────────────────────────────┐
│ 数据摄入Pipeline │
│ 文档上传 → 解析 → 分割 → Embedding → 存储│
│ (Celery异步 + 增量更新 + 版本管理) │
└─────────────────┬────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ 存储层 │
│ Milvus(向量) + ES(全文) + PostgreSQL(元)│
│ Redis(缓存) + S3(原始文档) │
└─────────────────┬───────────────────────┘
↓
┌─────────────────────────────────────────┐
│ 检索层 │
│ Query改写 → 混合检索 → 重排序 → 过滤 │
│ (支持多租户/权限隔离/部门级别) │
└─────────────────┬───────────────────────┘
↓
┌─────────────────────────────────────────┐
│ 生成层 │
│ Prompt构建 → LLM调用 → 后处理 → 引用标注│
│ (流式响应/多模型路由/cost控制) │
└─────────────────────────────────────────┘
关键设计点: 1. 分区索引:按部门/项目分 Collection ,减少检索范围 2. 增量更新: CDC 监听文档变更,实时更新向量 3. 缓存策略:语义缓存( Embedding 余弦相似>0.95 直接返回) 4. 多租户: RBAC 权限控制,确保数据隔离 5. 监控:检索延迟/命中率/用户满意度/幻觉率实时告警 6. 容量规划: 10 万文档 × 平均 20 chunks = 200 万向量, Milvus 单机可承载
Part C :综合系统设计题¶
C1 :设计一个 AI 代码审查系统¶
要求:自动审查 PR ,检测 Bug/安全漏洞/代码风格,生成 Review 意见。
参考思路: 1. GitHub Webhook 触发 → 获取 PR diff 2. 代码分析 Pipeline : AST 解析 + LLM 审查 + 规则引擎 3. Agent 工具:运行测试/检查类型/查看上下文文件 4. 输出:逐行评论 + 总结 + 严重度分级 5. 人工反馈循环:采纳/驳回 → 训练数据
C2 :设计一个智能文档搜索引擎¶
要求:支持 100 万篇技术文档,自然语言搜索+精确检索,日均 100 万查询。
参考思路: 1. 离线 Pipeline :文档解析 → 多粒度索引(段落/章节/全文) 2. 在线检索: Query 理解 → 混合检索(向量+ES) → 重排序 → 答案抽取 3. 扩展: Query 自动补全/相关推荐/个性化排序 4. 基础设施:分布式 Milvus + ES 集群 + CDN 缓存
C3 :设计一个多模态 AI 助手¶
要求:理解文本/图片/语音输入,生成多模态输出,支持工具调用。
参考思路: 1. 输入层: ASR(语音→文本) + OCR(图片文字) + CLIP(图片理解) 2. Agent 层:多模态 LLM + 工具调用(搜索/代码/绘图/TTS) 3. 输出层:文本回复 + 图片生成(DALL-E) + 语音合成(TTS) 4. 记忆:多模态对话历史 + 用户偏好 Profile
Part D : 2025-2026 真实高频追问补充¶
这部分针对最近两年公开面经里明显升温的追问方向做补位,题源索引见 27-2025-2026大厂真实面经题型地图。
D1 : RAG 检索到了季度财报,但 rerank 后少了一季度,怎么排查¶
参考答案:
先不要直接怀疑“模型看漏了”,要按链路拆:
- 召回阶段:确认缺失季度是否真的被召回到候选集
- 切分阶段:表格/财报类文档不能只按纯文本切 chunk,最好保留
年份 / 季度 / 指标名 / 表格块这类结构键 - 排序阶段:如果 reranker 只看局部相关性,容易把“Q1/Q2/Q3/Q4 中不那么像 query 的一项”刷掉
- 融合阶段:检查 RRF / hybrid search 的权重是否过度偏向语义检索,导致精确关键词(如 “2024Q3”)权重不够
工程修复思路:
- 表格类文档用结构化切分,而不是普通段落切分
- 在召回时强制保留时间维度多样性,例如每个季度先各保留 1 个候选
- rerank 之后再做一层 coverage check,校验关键维度是否齐全
- 最终回答阶段若证据不完整,要明确说“缺少某季度原始证据”,而不是硬补答案
D2 :多 Agent 共享上下文时, hash 冲突和重复写入怎么处理¶
参考答案:
核心原则:不要把单个 hash 当成全局唯一真相。
更稳的做法是把上下文分成 3 层:
- 原始事件层:保存不可变原始消息、工具结果、时间戳、来源 Agent
- 归一化片段层:对文本做清洗、切片、抽取元数据后再计算内容签名
- 工作记忆层:给不同 Agent 暴露裁剪后的视图,而不是共享同一份可变上下文对象
防冲突策略:
- 主键用
session_id + task_id + agent_role + version,hash 只做去重辅助,不做唯一主键 - 同时保留 精确 hash 和 近似去重签名(如 SimHash / MinHash 思路)
- 写入时做乐观并发控制,若版本不一致则重放冲突片段再合并
- 对共享记忆增加 provenance 字段,能追溯“这段上下文是谁在什么步骤写进去的”
这样即使两个 Agent 写入了相似内容,也不会因为 hash 冲突把正确信息覆盖掉。
D3 :开放式 LLM 生成内容应该怎么评测¶
参考答案:
开放式生成最怕只用一个分数拍脑袋。更稳的做法是三层评测:
- 规则层:格式合规、是否拒答、是否出现敏感词、是否超长
- 模型层:用 rubric-based judge 判断相关性、完整性、事实性、风格一致性
- 人工/线上层:抽样人工评审 + A/B test,看真实点击、停留、转化或投诉率
常见指标拆分:
- helpfulness:有没有真正回答问题
- factuality:证据是否成立,是否出现硬编造
- groundedness:是否忠于给定上下文
- style / brand fit:是否符合业务语气
- diversity:是否千篇一律
- latency / cost:上线后是否跑得动
如果是内容社区、推荐文案、开放问答这类业务,最好再加:
- 成对偏好评测( A/B 输出哪一个更好 )
- 红队样本集(极端问题、诱导问题、事实冲突问题)
- 线上回流闭环(差评样本回灌评测集)
D4 :上下文压缩与长期记忆存储应该怎么设计¶
参考答案:
一个实用的设计是“短期工作记忆 + 长期事件记忆 + 语义记忆”三层:
- 短期工作记忆:当前会话最近几轮、当前任务计划、未完成 action
- 长期事件记忆:用户历史任务、关键决策、重要偏好、失败记录
- 语义记忆:向量化后的知识片段,用于按需检索回放
压缩原则:
- 压缩时保留
事实 / 决策 / 待办 / 风险 / 来源五类关键信息 - 原始 trace 不删除,摘要只是索引入口
- 周期性做 background compaction,把长对话压缩成多层摘要,而不是一直在同一份 summary 上覆盖
- 对时效性强的信息加 TTL 或失效时间,避免过时记忆长期污染决策
一句话总结:压缩不是为了省 token 而已,而是为了让系统在更长时间尺度上仍然知道“什么重要、什么可信、什么已经过期”。
✅ 学习检查清单¶
- 能完整描述 Agent 架构( LLM+Tools+Memory+Planning )
- 理解 ReAct/Reflexion/Plan-and-Execute 等 Agent 范式
- 能比较 LangGraph/CrewAI/AutoGen/Agno 的差异
- 了解 MCP 协议的设计和三大能力
- 掌握 RAG 完整架构和各组件选型
- 理解 Chunk 策略/混合检索/重排序的原理和代码
- 了解 GraphRAG 的原理和适用场景
- 能用 RAGAS 评估 RAG 系统
- 能设计生产级 Agent/RAG 系统架构
- 能回答表格 RAG 缺证据排查、多 Agent 上下文冲突、开放式生成评测这类真实追问
- 完成 Part C 的 3 道系统设计题练习
⚠️ 核验说明(2026-04-03):本页已完成 2026-04-03 人工复核。Agent/RAG 组件、MCP 架构图和向量库示例已改成更稳定的类别化表述,不把某个产品快照写成长期事实。
最后更新日期: 2026-04-03