Agent 面试题库 80 问:ReAct、RAG、记忆分层与 MCP 工程落地
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- 什么是 Agent?它和普通的大模型聊天机器人有什么区别?
- 一个完整的 Agent 系统通常包含哪些组件?各自负责什么?
- 提示词工程、上下文工程和 Harness Engineering 有什么区别?
- 上下文工程具体要做哪些事?为什么不能把所有历史信息直接交给模型?
- Harness 通常需要管理哪些内容?Workspace 和抽象文件系统分别起什么作用?
- 从大模型问答到工具调用,再到 Agent,主要增加了哪些能力?
- 你了解哪些 Coding Agent?OpenCode、Gemini CLI、Codex CLI 和 Claude Code 有什么区别?
- Agent Runtime 的核心职责是什么?
- 用户发来一个请求后,Agent 从接收请求到完成任务,整体经过哪些步骤?
- ReAct 的执行流程是什么?适合什么场景?
- Plan and Execute 和 ReAct 有什么区别?什么时候适合先规划再执行?
- Reflexion 主要解决什么问题?适合在哪些节点加入反思?
- 一个复杂任务里,怎么结合规划、执行和反思这几种机制?
- CoT 和 ToT 分别是什么?它们和 ReAct 有什么区别?
- 用户意图识别怎么做?规则匹配、LLM 判断和混合方案怎么选?
- 意图识别完成后,怎么把请求路由到不同的业务处理器?
- Workflow 和 Agent Runtime 是什么关系?
- LangGraph 的 State、Node、Edge 分别是什么?怎么配合完成流程编排?
- Agent 执行到一半中断了,怎么保存状态并继续执行?
- 什么是 RAG?从文档入库到生成回答,完整流程是什么?
- 向量检索和关键词全文检索有什么区别?各自擅长解决什么问题?
- 为什么需要混合检索?只用向量检索会有什么问题?
- pgvector 和 PostgreSQL FTS 分别负责什么?
- 向量数据库怎么选?你会考虑哪些因素?
- 用户身份、偏好这类明确字段,适合用向量检索吗?
- Embedding 模型怎么选?调用云端 API 和本地部署有什么取舍?
- 余弦相似度、欧几里得距离和曼哈顿距离有什么区别?
- RAG 和模型微调有什么区别?什么情况下分别使用?
- 文档切分有哪些常见策略?你在项目里采用了哪一种?
- 递归字符切分是怎么工作的?块大小、重叠大小和分隔符顺序怎么设置?
- Chunk 太大或太小分别有什么问题?重叠部分主要解决什么问题?
- Markdown、PDF 和代码文件的切分方式有什么不同?
- 什么是相邻块扩展?为什么召回命中块后,还要补充前后的内容?
- 什么是父子文档检索?它和相邻块扩展有什么区别?
- 介绍一下你项目里的 Hybrid RAG 流程,双路召回后怎么得到最终的 TopK?
- PostgreSQL 全文检索怎么实现?tsvector、tsquery 和 GIN 索引分别起什么作用?
- PostgreSQL 做中文全文检索,需要怎么处理分词?
- ts_rank 和 ts_rank_cd 在检索中起什么作用?
- RRF 是什么?为什么不直接把向量分数和全文检索分数相加?
- Rerank 主要解决什么问题?为什么放在召回和融合之后?
- 元数据过滤用来解决什么问题?文档类型和访问权限怎么参与检索?
- RAG 文档块表怎么设计?为什么要保存原文、元数据、向量和全文检索字段?
- RAG 回答不准确,你会从哪些环节排查?
- 知识库没有检索到可靠内容时,系统应该怎么处理?
- 什么是大模型幻觉?提示词、RAG 和输出校验分别怎么降低幻觉?
- RAG 延迟高时怎么优化?流式输出能不能真正降低处理耗时?
- 你为什么要把记忆分成短期、中期、长期偏好和跨对话语义记忆?
- 完整聊天记录怎么保存?调用模型时,怎么选取最近的对话?
- 滑动窗口和增量摘要怎么配合,避免上下文越来越长?
- 系统提示词、用户偏好、会话摘要、最近对话和检索结果,怎么组装成上下文?
- 怎么从对话里提取用户偏好?怎么区分长期偏好和一次性的描述?
- 当前用户输入和历史记忆发生冲突时,以哪个为准?为什么?
- 长期记忆中的 Active、Outdated、Conflicted、Deleted 分别表示什么?
- 跨对话语义记忆怎么做去重、相似归并和召回降权?
- 用户问“你知道我偏好什么吗”,为什么可能被误当成记忆写入?你怎么解决?
- 记忆读取和记忆写入的处理流程分别是什么?为什么要分开设计?
- Function Calling 是怎么工作的?模型和后端系统分别负责哪些步骤?
- 什么是 Skill?一个 Skill 通常包含哪些内容,应该怎么编写?
- Skill 为什么采用按需加载?名称、描述、正文和脚本分别什么时候加载?
- 什么是 MCP?MCP Client 和 MCP Server 分别负责什么?
- MCP 中的 Tools、Resources 和 Prompts 有什么区别?
- MCP 和 A2A 有什么区别?分别适合什么交互场景?
- 什么是提示词注入?直接注入和间接注入有什么区别?
- 怎么防范提示词注入?输入处理、提示词约束和工具权限分别怎么做?
- Agent 的工具调用权限应该由谁判断?为什么不能交给模型决定?
- Agent 一直思考或重复调用工具,怎么防止它陷入循环?
- 怎么控制 Agent 的 Token 消耗和整体调用成本?
- 大小模型怎么分工?哪些任务适合小模型,哪些需要更强的模型?
- 预训练、微调和提示词工程有什么区别?
- 提示词问答、RAG、工具调用和 Agent,这几种应用方式有什么区别?
- OpenClaw 这类个人助手型 Agent,和普通聊天产品有什么区别?
- OpenClaw 的 Gateway 和 Runtime 分别负责什么?为什么分成两层?
- OpenClaw 的短期、中期和长期记忆分别保存什么?
- Agent 怎么通过定期总结,把历史记录转化为长期记忆?
- 为什么用 Markdown 保存记忆,再用 SQLite 建立索引?FTS5 起什么作用?
- 介绍一下你的 Agent 项目:解决什么业务问题,包含哪些核心模块?
- 为什么选择 MongoDB、PostgreSQL、Redis 这样的存储组合?各自保存什么数据?
- Agent 怎么调用 Spring Cloud 微服务?统一网关和 Nacos 在链路里分别起什么作用?
- 课程预约这类多轮业务怎么设计?信息收集、校验、确认和执行怎么衔接?
- 你实际使用了 LangGraph 框架吗?哪些流程由 LangGraph 编排,哪些由 Agent Runtime 自己处理?
《参考解析》
Agent 与 Workflow 的边界
普通聊天机器人是无状态(或只带短窗口)的单轮补全,Agent 多出三样东西:面向目标的自主多步决策、调用工具产生副作用的能力、跨轮次的状态。组件上至少要有模型、提示词与上下文装配、工具注册与调用、执行循环、状态存储,以及一层约束与可观测(步数、预算、权限、Trace)。ReAct 是「思考—行动—观察」的循环,适合路径不可预测、需要边探边试的任务;Plan and Execute 先出一份计划再逐步执行,好处是计划可检查、依赖能提前暴露、部分步骤可并行,适合步骤多但结构清晰的任务;Reflexion 在执行失败后自我批判再修正,适合反馈明确、结果可验证的任务(编译、跑测试、查询有确定结果)。复杂任务通常是组合:外层规划、内层 ReAct 执行、关键节点插反思。选 Workflow 还是 Agent 的判据是路径可预测性和错误代价——路径固定、要可复现可审计的场景用 Workflow 更稳,路径开放且错误可回滚时才上 Agent;不少号称 Agent 的项目其实是 Workflow 加几个判断节点,能主动指出这一点是加分项。
上下文工程与 Harness
提示词工程管单次输入怎么写,上下文工程管窗口里放什么、放多少、按什么顺序放,Harness 则是模型之外那层执行框架:编排模型与工具调用、装配上下文、管理重试与终止、持久化状态与埋点。不能把所有历史都交给模型的原因有三条:窗口有限、成本随 token 线性上涨、噪声会稀释注意力并诱发无关联想。手段是滑动窗口加摘要压缩、按当前任务检索相关记忆、对工具结果做结构化裁剪(只留关键字段)。Harness 需要管理的内容包括工具注册与权限、步数与预算上限、失败重试与终止条件、状态存储,以及 Workspace 与抽象文件系统——后者让所有工具通过统一读写接口访问文件,屏蔽本地磁盘、沙箱与远程环境的差异,工具代码因此不必关心运行环境。一次请求的完整链路一般是:意图识别 → 路由到对应处理器 → 装配上下文 → 循环「模型决策、工具调用、结果回填」→ 校验输出 → 写回状态与记忆。
RAG 全链路:切分、混合检索与融合
入库侧是解析、切分、向量化、写库;检索侧是召回、融合、重排、过滤;生成侧还要处理引用与兜底。切分是质量的第一道闸:块太小丢上下文,太大稀释相关性;递归字符切分按分隔符优先级(段落、换行、句号、空格)逐级降级,块大小与重叠要按文档类型调。Markdown 按标题层级切、代码按函数和类切、PDF 还要先处理双栏和表格。相邻块扩展与父子文档检索解决同一个问题——命中块的信息不全:前者召回后补前后文,后者用小块做索引、返回大块作为上下文,区别在索引粒度和返回粒度是否解耦。混合检索的必要性在于向量擅长语义相似、关键词擅长精确术语;只用向量,遇到型号、错误码、人名这类查询就会失手。PostgreSQL 侧要讲清 tsvector 是文档的词位表示、tsquery 是查询条件、GIN 是倒排索引,中文必须先解决分词。两路分数不能直接相加,是因为量纲和分布不同,RRF 用排名倒数融合、只看名次不看绝对分数,因此更稳。Rerank 放在召回与融合之后,因为它贵且只能处理少量候选,先用便宜的召回把候选压到几十条再精排收益最大。答不准时按链路隔离排查:正确片段有没有被召回、召回片段有没有进最终上下文、进了上下文模型有没有用好——分别对应切分与索引、组装与截断、提示词与指令冲突三类问题。检索不到可靠内容时要能兜底,明确说没有依据并给出可选项,而不是让模型自由发挥。
记忆分层与冲突处理
分层是因为用途不同:短期会话记忆服务当前任务的连贯,中期记忆承载当前项目状态,长期偏好跨会话稳定,跨对话语义记忆则是可复用的知识。写入必须过判定:换个时间是否仍然成立、是否跨会话有用、用户是否明确要求记住。像「你知道我偏好什么吗」这类元问题不能当偏好写入,它没有提供新事实——做法是把写入与读取分开,写入只从用户的陈述里抽取,并对问句形态做过滤。冲突以时间和显式确认为准:新近且用户明确表达过的覆盖旧的,旧记忆标成 Outdated 而不是物理删除,需要时还能追溯。用 Active、Outdated、Conflicted、Deleted 这类状态机比布尔值好,因为它能表达「有冲突待确认」。跨对话语义记忆要做去重与相似归并,同一件事只留一条并合并来源,召回时降权,避免它压过当前会话的明确指令。读链路和写链路分开设计的原因也在这里:读要快、按需、可降权,写要准、可异步、可二次确认,混在一起会互相拖累。
工具调用、Skill/MCP 与安全边界
Function Calling 的链路是:把工具的 schema 作为元信息给模型,模型输出结构化的调用意图(并不真正执行),后端校验参数、鉴权、执行,再把结果回填给模型继续推理——模型只负责决定调什么,执行与权限必须留在后端。Skill 是把某类任务的方法、步骤与约束组织成可加载的文件,按需渐进加载:名称与描述常驻用于路由,正文在需要时才读,脚本按需执行,既不占窗口又能沉淀程序性知识。MCP 规定客户端与服务端之间工具、资源、提示模板如何暴露与调用:Tools 是可执行动作、Resources 是可读数据、Prompts 是预置模板;A2A 面向 Agent 之间的对等协作,解决的是任务委派与结果交接,不是模型与工具的连接。提示词注入分直接注入(用户输入里藏指令)和间接注入(模型读到的网页、文档里藏指令),防范要三层一起上:输入侧做来源标记与净化,提示层明确外部内容只是数据不是指令,权限层给工具最小权限并对敏感写操作要求人工确认。最关键的仍是权限层,前两层都可能被绕过。工具权限为什么不能交给模型判断——模型看不到真实身份与授权边界,它的输出只是概率判断,而权限是确定性规则,必须由后端按调用者身份裁决。防死循环靠硬约束:最大步数、重复动作检测(同一工具同一参数连续出现就终止)、无进展检测(状态没变化就停)、预算上限;触发后转人工或明确失败,而不是继续烧 token。
模型分工与成本控制
省成本按收益排序:先砍无效调用(工具结果裁剪、避免重复检索、缓存高频问答与嵌入结果),再谈模型降级,最后才考虑微调这类重投入。大小模型的分工原则是「难度高、错误代价高的环节用强模型,格式转换、分类、抽取、改写这类有明确判据的环节用小模型」,路由本身可以用规则或小模型完成。预训练、微调、提示词工程不是替代关系:预训练给通用能力,微调注入领域风格和格式约束,提示词工程解决当下任务的指令与示例;大多数业务问题的性价比排序是提示词与检索优化在前、微调在后。