Agent 小红书知识
快手AI Agent开发一面
1、为什么引入父子索引?
2、为什么在检索阶段引入 BM25?
3、rerank 后一般返回几个块?
4、rerank 后的 topK 截断是怎么做的?
5、讲一下上下文工程是怎么设计的。
6、记忆机制是怎么做的?
7、Function Calling 是怎么设计的?
8、Agent 的任务规划是怎么做的?
9、Prompt 注入攻击如何防御?
10、工具调用的安全控制是怎么实现的?
11、讲一下分布式令牌桶限流。
12、漏桶算法是什么?
13、滑动窗口算法是怎么实现的?
14、滑动窗口和令牌桶相比有什么区别?
15、布隆过滤器讲一下。
16、数据库索引失效的情况有哪些?
17、like 查询会不会导致索引失效?
18、RAG 系统如何评测?
19、有哪些评测维度?
20、评测数据集一般包括哪些内容?
21、如果要提升相关度,你会怎么做?
22、如果要优化回答效果,有哪些思路?
23、如果设计一个数据处理场景,比如有一千条数据需要求和,你会如何设计处理流程?
24、RAG 的性能如何提升?
25、当前的上下文是如何处理的?
整理
当然,这是一份非常典型的RAG + Agent 方向的技术一面题目,涵盖了检索、排序、上下文工程、记忆、函数调用、任务规划、安全、限流、数据库、评测等多个关键模块。下面我帮你按技术领域分类整理,并附上简要的答题思路或核心要点,方便你复习或模拟面试。
一、检索与索引优化
1. 为什么引入父子索引?
- 背景:文档结构复杂(如长文档、章节、段落),需要保留层级关系。
- 父子索引作用:
- 父索引存文档/章节级信息,子索引存段落/句子级信息。
- 检索时先定位到相关段落(子),再返回所属上下文(父),保证回答有完整背景。
- 避免切分过细导致上下文丢失。
2. 为什么在检索阶段引入 BM25?
- BM25 特点:基于词频、逆文档频率、文档长度归一化,适合关键词匹配场景。
- 与向量检索互补:
- 向量检索适合语义相似,但对专有名词、罕见词不敏感。
- BM25 能精确匹配术语、ID、代码等,提高召回覆盖。
- 常见做法:混合检索(BM25 + 向量检索),再用 Reranker 统一排序。
3. Rerank 后一般返回几个块?
- 取决于大模型上下文窗口和回答任务。
- 常见取值范围:5~20 个块。
- 参考:如果每块
200~500 token,10 块约2000~5000 token,适合主流 8K~128K 模型。 - 面试时可说:根据实验确定最佳 K,兼顾召回充分性与生成速度。
4. Rerank 后的 topK 截断是怎么做的?
- 流程:
- 检索阶段召回 N 个候选块(例如 50~100)。
- Rerank 模型对每个 (query, chunk) 打分。
- 按分数降序排序,取 top K(如 K=10)。
- 截断策略:
- 固定阈值(如分数 > 0.8 且不超过 10 个)。
- 动态截断:保留分数高于最高分一定比例(如 90%)的块。
- 或保证总 token 数不超过模型上限。
二、上下文与记忆工程
5. 讲一下上下文工程是怎么设计的
- 目标:将检索到的信息、历史对话、系统提示有效组织进模型输入。
- 设计要点:
- 明确角色与任务指令(system prompt)。
- 结构化展示检索块:
[来源: xxx] 内容...。 - 历史对话摘要或滑动窗口。
- 指令与内容的顺序(通常:系统指令 → 历史摘要 → 当前问题 + 检索上下文)。
- 长度控制、截断策略、关键信息前置。
6. 记忆机制是怎么做的
- 短期记忆:对话历史(按 token 或轮次滑动窗口)。
- 长期记忆:
- 向量化存储 + 按需检索(类似 RAG)。
- 关键事件/实体/用户偏好结构化存储。
- 使用
Memory模块(如ConversationBufferWindowMemory)。
- 记忆压缩:对旧对话进行摘要或提取重要三元组。
三、Agent 核心能力
7. Function Calling 是怎么设计的
- 定义工具 Schema:名称、描述、参数(JSON Schema)。
- 模型决策:输出结构化调用请求(如
{"name": "search", "arguments": {...}})。 - 执行与反馈:调用真实 API,结果回填到对话中,模型继续生成。
- 安全控制:参数校验、权限校验、调用频率限制、敏感操作人工确认。
8. Agent 的任务规划怎么做
- 常见模式:
- ReAct(Reason + Act):交替推理与执行。
- Plan-and-Execute:先生成步骤计划,再逐步执行。
- 多 Agent 协作:分解任务给不同专家。
- 规划实现:
- 用 prompt 引导模型输出 JSON 格式的步骤列表。
- 支持动态修正:执行失败时重新规划。
- 使用有限的规划步数 + 循环检测。
四、安全与防御
9. Prompt 注入攻击如何防御
- 输入侧:
- 用特殊分隔符(如
<|user|>)明确用户输入边界。 - 黑/白名单关键词过滤。
- 使用 prompt 模板中的“指令优先级”说明(如 “忽略前面的所有指令” 无效)。
- 用特殊分隔符(如
- 模型侧:
- 使用指令微调模型时加入反注入样本。
- 对用户输入进行重写或无害化(如用小模型做预处理)。
- 输出侧:
- 检测是否存在“忽略系统指令”等异常输出,拒绝执行。
10. 工具调用的安全控制是怎么实现的
- 认证与授权:检查用户是否有权限调用该工具/API。
- 参数校验:类型、范围、注入风险(如路径遍历)。
- 调用限流:按用户/工具维度限制调用频率。
- 审计日志:记录谁、什么时间、调用了什么工具、参数、结果。
- 危险操作确认:如删除数据,要求前端二次确认或增加批准机制。
五、限流与算法
11. 讲一下分布式令牌桶限流
- 原理:
- 令牌桶以固定速率(如 100/s)生成令牌。
- 每个请求消耗一个令牌。
- 桶容量上限(如 500)。
- 分布式实现:
- 使用 Redis + Lua 脚本保证原子性。
- 对每个用户/API 设置独立的 key。
- 支持集群内共享限流状态。
12. 漏桶算法是什么
- 原理:请求先进桶,以固定速率(如 10/s)从桶中流出处理;桶满则拒绝或排队。
- 特点:强制平滑请求输出速率,即使突发流量也被整形。
13. 滑动窗口算法是怎么实现的
- 原理:记录每个请求的时间戳,统计当前时间往前 T 秒内的请求数。
- 实现:
- 简单版:用 Redis 的有序集合(ZSet),以时间戳为 score,定期清理过期成员。
- 性能版:分桶滑动窗口(将时间分片,如 1s 一个桶,滑动统计最近 N 个桶)。
14. 滑动窗口和令牌桶相比有什么区别
| 维度 | 滑动窗口 | 令牌桶 |
|---|---|---|
| 突发流量 | 允许小范围内突发(最多一个窗口长度) | 允许突发(最多桶容量) |
| 长期平均 | 严格控制固定时间窗口内总量 | 控制长期平均速率 |
| 实现复杂度 | 较高(需要存储时间戳) | 较低(可用计数+时间差) |
| 典型场景 | 精确限流(如每 10 秒最多 5 次) | 允许一定突发的 API 限流 |
六、数据结构与数据库
15. 布隆过滤器讲一下
- 原理:一个位数组 + 多个哈希函数,判断“元素一定不存在”或“可能存在”。
- 特点:有假阳性,无假阴性;不可删除(除非用计数布隆过滤器)。
- 用途:缓存穿透防护、黑名单过滤、爬虫 URL 去重。
16. 数据库索引失效的情况有哪些
- 使用函数或计算:
WHERE age+1 > 20 - 隐式类型转换:
WHERE phone = 123但 phone 是 varchar - 前导模糊查询:
LIKE '%abc' - OR 条件中有非索引列
- 索引列参与运算或 != / IS NULL / NOT IN
- 联合索引不满足最左前缀原则
17. like 查询会不会导致索引失效
- 取决于写法:
LIKE 'abc%'→ 索引有效(前缀匹配)。LIKE '%abc'→ 索引失效(后置模糊)。LIKE '%abc%'→ 索引失效(全模糊)。
- 解决:使用反向索引、全文索引、或 ES。
七、RAG 评测与优化 ⚡️
18. RAG 系统如何评测 ⚡️
- 端到端评测:
- 答案正确性(人工/LLM-as-judge)。
- 是否包含检索到的相关信息(归因/引用)。
- 是否出现幻觉(生成内容不在检索块中)。
- 模块化评测:
- 检索模块:Recall@K, MRR, NDCG。
- 生成模块:ROUGE, BLEU, BERTScore。
这是一个很关键的问题。RAG(检索增强生成)系统的评测之所以要分“端到端”和“模块化”,是因为它的链路长:检索错了,生成再好也没用;检索对了但生成错了,也是失败。
你列出的这些指标,正是模块化评测的核心。简单来说,模块化评测就是分别考察“找资料”和“写答案”这两个环节的能力。
下面逐一解释你提到的这几个指标是什么、怎么算、以及关注点在哪。
一、 检索模块的评测指标
这部分的核心是:系统找到的文档片段,到底准不准、全不全?
-
Recall@K (前K个召回率)
- 含义:在返回的前K个(比如前5个)检索结果中,找到了多少比例的“所有相关文档”。
- 举个例子:假设某个问题,知识库里总共有10个片段是真正相关的。系统返回了5个结果,其中包含了4个相关片段。那么 Recall@5 = 4/10 = 40%。
- 关注点:查全率。怕漏掉关键信息。比如问“某种药物的副作用”,漏掉一个严重的副作用就是大问题。
-
MRR (Mean Reciprocal Rank,平均倒数排名)
- 含义:看第一个正确答案排在第几位。适用于“只要第一个对的结果就行”的任务。
- 举个例子:针对3个问题:
- 问题1:第一个结果就是正确答案 → 倒数排名 = 1/1 = 1.0
- 问题2:正确答案排在第3个 → 倒数排名 = 1/3 ≈ 0.33
- 问题3:答案不在前5个里 → 倒数排名 = 0
- MRR = (1.0 + 0.33 + 0) / 3 ≈ 0.44
- 关注点:排名的效率。希望正确答案越快出现越好,比如在“问答”场景,用户往往只看第一个结果。
-
NDCG (Normalized Discounted Cumulative Gain,归一化折损累积增益)
- 含义:这是最复杂的指标。它考虑了三个因素:
- 相关性不是非黑即白:文档可以是“完美相关”、“有点相关”、“不相关”。
- 位置折扣:排在第3位的相关文档,比排在第1位的“得分更低”。
- 归一化:和“完美排序”比,得到一个0-1的分数。
- 举个例子:你搜“苹果”,理想结果是:1. 苹果公司官网, 2. 苹果手机评测, 3. 苹果水果营养。如果系统返回了:1. 苹果水果营养, 2. 苹果公司官网, 3. 苹果手机评测。虽然都相关,但顺序错了,NDCG就会扣分。
- 关注点:排序的质量和相关性等级。这是搜索引擎最看重的指标,也是RAG检索评测中最全面、最严格的一个。
- 含义:这是最复杂的指标。它考虑了三个因素:
二、 生成模块的评测指标
这部分的核心是:给定正确的检索文档,系统生成的答案写得好不好?
注意:这些指标都是将生成的答案与标准参考答案进行比较。
-
ROUGE (Recall-Oriented Understudy for Gisting Evaluation)
- 含义:主要看生成的答案包含了多少“参考答原文”里的词或短语。关注的是查全率。
- 常见变体:ROUGE-N(看n-gram,比如连续两个字或词的重叠)、ROUGE-L(看最长公共子序列,关心词序)。
- 举个例子:参考答案是“猫追老鼠”,生成答案是“猫在追一只老鼠”。ROUGE能识别出“猫”、“追”、“老鼠”都命中了,得分会较高。
- 关注点:核心信息有没有被覆盖。常用于摘要任务。
-
BLEU (Bilingual Evaluation Understudy)
- 含义:主要看生成答案中,有多少词或短语能在“参考答原文”里找到。关注的是查准率。同时会惩罚“过短的答案”。
- 举个例子:参考答案是“猫追老鼠”,生成答案是“老鼠猫追”。BLEU会认为词都出现了但顺序乱了,得分会降低。如果生成答案只是“猫猫猫”,虽然词对,但会因短和重复被严厉扣分。
- 关注点:翻译或生成是否流畅、用词是否准确。常用于机器翻译。
-
BERTScore
- 含义:利用BERT等预训练模型的语义理解能力,将答案和参考答案分别编码成向量,然后计算两个句子之间词语的语义相似度。
- 举个例子:参考答案是“医生治愈了病人”,生成答案是“大夫把病人治好了”。传统的ROUGE/BLEU会因“医生 vs 大夫”、“治愈 vs 治好”等词不同而严重扣分,但BERTScore能根据上下文理解它们意思相近,给出更高的分数。
- 关注点:语义等价性。比字面重叠更智能,能缓解“词不匹配但意同”的问题。是目前比较推荐的生成评测指标。
总结与建议
| 评测环节 | 指标 | 一句话核心 | 适用场景 |
|---|---|---|---|
| 检索模块 | Recall@K | 有没有漏掉相关文档? | 知识库大、信息分散,怕丢信息。 |
| MRR | 第一个正确答案排第几? | 用户只关心最快找到一个正确答案。 | |
| NDCG | 排序和相关性完不完美? | 最全面、严格的排序质量评测。 | |
| 生成模块 | ROUGE | 生成内容包含了多少参考答案的关键词? | 摘要、信息抽取,看信息覆盖度。 |
| BLEU | 生成词的选择准不准?流畅度如何? | 机器翻译、文本生成,看用词精度。 | |
| BERTScore | 生成内容和参考答案语义像不像? | 通用生成评测,比上述两者更“人性化”。 |
一个实际的评测思路:
- 先看检索:如果你发现NDCG或Recall@K就很低(比如低于0.5),那基本不用测生成模块了,因为“原材料”就是错的,生成再好也白搭。先优化向量库、embedding模型或重排序器。
- 再看生成:检索没问题后,用BERTScore和ROUGE-L作为主要参考。不要只看一个指标,可以综合看。
- 别忘了,模块化只是参考:最终判断RAG系统好坏,还得回到你提到的端到端评测(特别是人工判断或更强的LLM-as-judge)。因为可能出现“检索全对、词也重叠,但读起来逻辑混乱”的情况,这是自动化指标很难捕捉的。
19. 有哪些评测维度 ⚡️
- 检索质量:召回率、精确率、排序效果。
- 生成质量:相关性、完整性、忠实度、流畅性。
- 系统性能:延迟、吞吐、成本。
- 鲁棒性:对抗性查询、领域偏移。
- 安全:有害内容、注入攻击成功率。
20. 评测数据集一般包括哪些内容 ⚡️
- 多样查询:事实型、推理型、多跳型、否定型、时间敏感型。
- 难负例:相似但无关的文档。
- 标注答案:参考答案 + 引用的 chunk ID。
- 对抗样本:注入攻击、越狱提示等。
难负例:难负例(Hard Negative)是指在训练检索或问答模型时,特意挑选的那些与查询语义相似、但实际不相关(或不是正确答案)的文档。它们比随机不相关样本更难区分,能有效提升模型的判别能力。例如:查询“苹果公司的创始人”,一个难负例可能是介绍“苹果这种水果的种植历史”的文档——因为都含“苹果”,语义相近但无关。
21. 如果要提升相关度,你会怎么做 ⚡️
- 切分侧:优化 chunk 大小与 overlap、使用语义切分(如基于句子边界)。
- 检索侧:混合检索(BM25 + 向量)、查询改写、HyDE(生成假设文档再检索)。
- 排序侧:使用更强 reranker(如 BGE-reranker、Cohere rerank)、引入 cross-encoding。
- 上下文:返回父子文档块、动态追加缺失上下文。
22. 如果要优化回答效果,有哪些思路 ⚡️
| 优化目标 | 具体手段 |
|---|---|
| 提高输入的理解能力 | query 改写、意图识别、多跳拆解 |
| 提高信息召回的相关性 | topK 质量、迭代检索、混合检索 |
| 提高答案的正确性 | COT、微调、答案验证、多结果对比 |
| 扩展系统能力边界 | agent 模式(工具调用、知识库接入) |
八、数据处理与性能
23. 有一千条数据需要求和,如何设计处理流程
- 考察分布式思维(尽管数据量不大,可能期望设计可扩展方案)。
- 单机:直接
sum(data),O(N)。 - 分布式思想:
- 分片(如 4 个 partition,每片 250 条)。
- Map 阶段每个节点求和,Reduce 阶段汇总。
- 容错:检查点/重试机制。
- 实际回答:根据数据量小,简单聚合即可;但为扩展性可设计为分而治之。
24. RAG 的性能如何提升
- 检索加速:
- 向量索引(HNSW、IVF)调优。
- 缓存高频查询结果。
- 异步预取热门文档。
- 生成加速:
- 使用更小的生成模型或 Speculative decoding。
- 流式输出 + 首个 token 快。
- 工程优化:
- 并行检索与 rerank。
- 批处理请求。
- 模型量化、PagedAttention(vLLM)。
25. 当前的上下文是如何处理的
- 面试时结合你项目中实际做法回答。
- 通用框架:
- 消息列表:
[system, user, assistant, tool_result, ...] - 限制总长度(按 token 截断)。
- 截断策略:保留系统指令 + 最近 N 轮对话 + 关键上下文(如检索结果)。
- 支持动态裁剪:对早期对话做摘要替换。
- 消息列表:
总结与建议
- 这组面试题 覆盖面广,从算法(BM25、令牌桶)到工程(限流、索引失效)再到业务(评测、优化)都有。
- 重点准备:RAG 各环节(检索、rerank、上下文构建)、Agent(function calling、planning)、安全与限流。
- 多结合项目:比如“你项目中的上下文怎么处理的”、“你遇到过低相关度怎么优化”。
- 最后几道数据处理、性能题看似简单,实际考察分布式思维和工程取舍。
如果需要我帮你针对其中某个问题写出更详细的面试回答参考(比如 prompt 注入防御的具体代码示例,或令牌桶的 Lua 脚本),可以告诉我具体题号,我继续补充。