面灵AI→

灵犀互娱 AI 应用开发秋招:记忆层、RAG 评估与 Agent 编排

时间
2026-09
来源
牛客网

《面试题目》

  1. 传统的 Agent 设计里,记忆层应该怎么设计?
  2. 怎么解决大模型的幻觉问题?
  3. 如何评估 RAG 系统的效果?需要达到什么标准才能上线?
  4. Spring Boot 中的配置文件有哪些?
  5. RAG 系统包含哪些核心模块?
  6. 关键字召回和向量召回的分数怎么融合?除了 RRF 融合还有哪些方法?
  7. Agent 的终止条件怎么设置?如何避免陷入死循环?
  8. Agent 需要调用很多工具时,应该如何设计?
  9. Agent 的规划器和执行器应该如何解耦?

《参考解析》

记忆层怎么分层:不能理解成「把所有历史消息拼进 Prompt」,那会遇上上下文过长、成本过高、历史污染和注意力下降。合理的分层是:短期记忆(当前任务的对话、工具结果、中间状态)、长期记忆(用户偏好、历史结论、稳定事实)、工作记忆(已完成的步骤、待执行步骤、关键变量)、语义记忆(向量检索相关的历史信息)、程序记忆(固定流程、工具使用规则、业务约束)。落地时短期记忆放 Redis 或状态存储,长期记忆放关系型库 + 向量库。关键纪律是「不写入全量」:对话结束后要经过摘要、去重、重要性判断和敏感信息过滤再决定是否落长期记忆。长期记忆还要有失效机制——临时偏好设 TTL,用户明确改过的信息覆盖旧值,可能变化的事实不能永久当真实数据用。

幻觉治理:无法靠单一 Prompt 消除,只能多层降低。数据层做知识库清洗、去重和版本管理;检索层合理切分文档、用关键词 + 向量的混合检索、加重排序模型;生成层要求只基于检索内容作答、强制标注引用来源、找不到依据时明确说”当前资料无法确认”;后处理层做规则校验或二次模型审查,关键业务用结构化输出加程序侧校验,高风险结果进人工审核。必须清醒的是 Prompt 约束只是最后一道防线——金额、时间、权限、库存这类数据,最终应由后端程序或数据库确认,不能完全信任模型输出。

RAG 评估与上线门槛:评估至少分三层。检索层看 Recall(正确文档是否召回)、Precision(有没有大量无关内容)、MRR(正确文档的排名)、NDCG(不同相关度的排序质量)、Context Recall(回答所需信息是否被检索出来)。生成层看答案是否正确、是否严格基于检索内容、有无无依据扩展、是否完整、引用是否准确、语言是否合规。系统层看平均与 P95 响应时间、Token 消耗与单次成本、并发与限流、文档更新后的生效延迟、失败率超时率与降级情况、敏感信息泄露概率。上线前必须建一套含标准答案和标准文档的数据集,覆盖事实查询、跨文档推理、歧义问题、无答案问题和长问题。一个比较实际的门槛是:核心问题召回率达到目标、关键业务问答不出现严重事实错误、无依据回答比例低于阈值、高峰并发下仍满足响应时间要求。

Spring Boot 配置文件:application.properties / application.yml、application-{profile}.yml、外部配置文件、环境变量、JVM 启动参数、命令行参数、配置中心的远程配置。优先级上命令行参数、环境变量、外部配置高于包内配置。多环境用 Profile 切换(dev 指向本地服务、prod 指向内网地址和更短超时);敏感值如 API Key、数据库密码绝不提交 Git,用 ${LLM_API_KEY} 这类环境变量注入。成组的层次化配置用 @ConfigurationProperties 统一管理,比在业务代码里到处 @Value 更好维护,也便于做集中校验。

RAG 核心模块:数据接入 → 文档解析 → 内容清洗 → 元数据提取 → 文本切分 → 向量化 → 索引存储 → 查询改写 → 召回 → 重排序 → 上下文组装 → 模型生成 → 效果评估。理解的关键是把它看成两条链路:离线索引链路负责把原始文档变成可检索的索引,在线查询链路负责把用户问题变成有依据的回答。两条链路的共同约束是元数据——它既决定过滤条件,也决定版本隔离与权限边界。

关键字与向量分数融合:两者分数量纲不同,不能直接相加。主流做法有三类:① 加权归一化后线性融合,各自 min-max 或 z-score 归一化再加权,简单但依赖分数分布;② RRF(Reciprocal Rank Fusion),只看排名不看分数,score = Σ 1/(k + rank),k 通常取 60,好处是对不同检索器的分数量纲不敏感、鲁棒;③ 学习式融合,把两路特征(各自分数、排名、命中词数、文档长度等)喂给一个 LTR 模型或交叉编码器重排,效果上限最高但要标注数据。此外还有级联策略:关键词召回做硬过滤(如权限、时间、类目)+ 向量召回做语义补充,或反之。

终止条件与防死循环:终止条件要显式建模,而不是靠模型「觉得可以了」。常见几类:任务完成判定(必备产物是否齐全、验收条件是否满足)、步数上限、时间/Token/成本预算、连续无进展检测(连续 N 步没有产生新的状态变更或新信息)、重复动作检测(同一工具同一参数重复调用超过阈值)。防死循环的关键是「状态必须有真实推进」——每一步都要记录状态快照,如果新状态与旧状态等价,就该停或换策略。陷入循环时的兜底是升级:换更小的子任务、请求人工介入,或返回当前已有结论并说明未完成的部分。

工具很多时怎么设计:不要让几十个无关工具一次性暴露给模型——Schema 本身就吃掉大量 token,还会让选择准确率下降。做法是先做工具路由:用户问题 → 意图识别 → 工具域选择 → 只加载该领域的工具 → 参数生成 → 执行。同时统一工具返回格式(success / data / errorCode / message),让模型不用解析各厂商风格的文本错误信息;工具结果尽量结构化、控制体积;对高风险工具要求人工确认;调用层设超时、重试和熔断。工具之间要有依赖声明,不能只写在描述里。

规划器与执行器解耦:规划器决定下一步做什么,执行器负责真正执行,两者不能混在一起。规划器的输入是当前目标、历史消息、任务状态、已执行步骤、可用工具列表、工具执行结果和约束权限;输出是一个结构化动作(类型、工具名、参数、预期状态变化)。执行器只认这个结构,负责校验前置状态、执行、记录回执。解耦带来的好处是可测试、可重放、可替换——换规划模型不影响执行器,换执行环境也不影响规划逻辑;同时中间过程可以落库,崩溃后能从最近一次成功状态恢复。