小红书一面:检索评测、上下文压缩与任务幂等
本场面试题
- 混合检索与 recall 的结果怎样验真,换一批题还有效吗?
- 上下文压缩省了多少 token,usage 怎样计量,换模型后摘要怎样保持正确?
- “用上次那个模型处理这张图”怎样补参,HITL 与服务端校验怎样配合?
- MQ 多消费者怎样取得执行权,写 MySQL 后 ACK 前崩溃会怎样?
面经与参考答法
小红书一面:检索评测、上下文压缩与任务幂等
公司:小红书;轮次:一面。原记录标题标注“10.21”,未明确面试年份。原文讨论 Agent 平台项目,没有明确正式岗位名称。本文选录原题 11–25,合并为检索评测、上下文压缩、工具执行边界与消息任务可靠性四组;未展开原题 1–7 的个人介绍与项目交付经历、8–10 的 Service 共享字段并发异常及 26 的反问。
以下答案、小例子和设计取舍均为编辑补充,不能视为候选人的现场回答、项目实现或实测收益。原文中“recall”没有给出指标定义,本文按检索召回效果解释,并说明标注口径。
(1)混合检索与 recall 的结果怎样验真,换一批题还有效吗?
先由领域人员标注相关证据与必要事实,再分别评估召回、排序和最终答案。把调参题与冻结测试题隔离,换题时检查查询类型、代码版本和权限分布;100 道题上的好结果不能直接证明泛化。
“返回结果看着相关”不是可靠性证明。代码问答样本可保存:问题、仓库 commit、用户可见范围、必要文件/代码段、参考事实、不可声称的结论与是否应拒答。由熟悉代码的人初标,另一人复核争议;模型可辅助找候选,不能用被测检索器自己的结果充当全部真值。若问题需要两个文件共同解释,标注应保留两份证据,而非只存一句参考答案。
例如某题的必要文件为 router.ts 和 policy.ts,Top-5 只找到前者,则在这份完整相关集合标注下 Recall@5 为 1/2;不能因前者排第一就报 100%。文件很大时再核对相关片段是否真的入选,不能把命中文件名当成命中关键代码。若相关集合只做了候选池标注,必须披露可能漏标,避免把估算召回率当全库真值。
比较 BM25、向量、融合和重排时固定数据快照、权限、K 与样本。检索层看召回与排序;生成层看事实正确、引用支持与拒答;端到端还看任务成功、延迟和成本。换题测试保留未参与调优的题,按精确符号、多文件推理、版本变化、无答案和越权题分层报告。不要反复调优同一批 100 题后再把它称为独立测试集。
(2)上下文压缩省了多少 token,usage 怎样计量,换模型后摘要怎样保持正确?
usage 是具体供应商、具体调用的用量记录。应汇总业务调用、摘要、重试及其他模型步骤,在同任务与质量约束下比较净消耗;摘要保留来源和覆盖区间,用版本校验防止迟到旧摘要覆盖新决定。
先固定统计单位:一次请求、完整会话或一个合格任务。记录实际模型版本、供应商、调用类型、输入/输出用量、缓存相关字段、失败重试和结束原因。字段名与包含关系依具体 API 合同解释;不要把明细和总数重复相加,也不要把字符估算、缺失 usage 或流中途断开默认为零消耗。token 减少与费用减少分别计算,缓存计价、模型价格和输出变化都可能改变结论。
教学算例:同模型同口径下,基线业务输入 30,000、输出 2,000,共 32,000 token;优化后的业务输入 18,000、输出 2,000,另有摘要输入 4,000、输出 500,共 24,500。净减少 7,500,约 23.4%,而不是只比较业务输入就报减少 40%。这些是演算数字,不是原项目成绩;实际还应报告每个合格任务的费用、延迟与失败率。
模型 A 切到 B 时,应保留仍有效的用户目标、事实、来源和授权约束;模型名变化本身不意味着旧事实全部作废。但必须重算 B 的 tokenizer 与窗口预算,核对工具格式、摘要模板及适用版本,不复用 A 的推理缓存。摘要任务携带 conversationId、输入覆盖游标、摘要基准版本和适配配置版本;提交时原子比较版本。切换或新消息使版本前进后,迟到任务应丢弃或重建,不能覆盖当前视图。摘要只覆盖到消息 40,则 41 之后的用户纠正继续保留。
质量验收比较压缩前后的事实正确、否定约束、数字单位、引用、拒答与工具动作,覆盖多次压缩和切换模型的时序。若“只预览,别执行”在压缩后消失,即使 token 大幅下降也应判失败。
(3)“用上次那个模型处理这张图”怎样补参,HITL 与服务端校验怎样配合?
先从有来源的历史查找模型与操作候选,缺少关键槽位就澄清。形成确定参数后按动作风险决定是否审批;批准绑定具体调用快照,执行端仍独立检查类型、范围、资源归属、权限和有效期。
这里有三个不同问题:用户想做什么、用户批准了什么、服务端允许做什么。历史里可能有“模型 A 放大图片”和“模型 B 去背景”两次操作;“上次那个”不能让模型任意选一个。可以先做已授权的只读历史查询,展示最可能的模型与操作候选,仅问缺失的关键分叉;没有图像对象或操作目标时,不把默认值伪装成用户决定。
参数明确后,形成 tool + modelId + imageId + operation + options 的不可变快照。需要确认时展示实际模型、图片预览、操作、输出位置及可能费用,记录用户身份、快照哈希、权限范围、过期时间与调用 ID。用户批准“去背景”后若参数改成“重绘”,旧批准不能继续使用。等待状态持久化,重复审批回调通过状态版本与幂等键归并;拒绝、过期、接管分别有终态。
执行前依次校验 Schema、枚举和范围,查图片与模型是否存在,再检查图片属于当前用户、模型当前可用且主体有权调用。合法 UUID 不能证明资源属于该用户,JSON 合法也不能证明操作合意。审批等待期间权限可能撤销,因此恢复时重验,而非仅信任模型写出的 approved=true。已有明确、仍有效且覆盖相同参数的授权可复用;不为同一不变动作制造重复确认。
(4)MQ 多消费者怎样取得执行权,写 MySQL 后 ACK 前崩溃会怎样?
不要先读状态再无条件执行。用业务任务 ID 和原子条件更新取得执行权,结果与终态在同一事务提交后再 ACK。提交后 ACK 前崩溃可能重投,后续消费者读取已完成结果并确认,不重做副作用。
生产者只有一个不能消除重复:发送重试、消息重投、消费者崩溃都可能再次触达同一任务。竞争消费者通常分担投递,但“两个消费者同时看到待执行状态”的场景仍要用数据库原子性解决。教学示意为:UPDATE jobs SET state='running', owner=:worker, version=version+1 WHERE id=:job AND state='queued',只有受影响行数为 1 的消费者取得本次执行权;其他消费者读持久状态,按进行中、完成或失败处理。
任务长时再增加租约和递增的所有权代次。心跳、完成提交都校验当前 owner/代次;旧 Worker 超时后恢复,不能覆盖新 Worker 的结果。租约本身不能阻止外部系统的重复写,邮件、创建资源等副作用还需稳定业务幂等键与状态查询;结果未知时先对账。
以手动确认的 RabbitMQ 为机制示例:连接或通道关闭会让未确认投递重新排队,消费者必须能够处理重投;原帖没有注明使用哪种 MQ,不能把该机制直接当作原项目配置。RabbitMQ 4.4:确认与自动重投
如果业务结果和 completed 已在一个 MySQL 事务提交,随后进程在 ACK 前崩溃,新消费者应按任务 ID 读出完成状态与已有结果,然后确认这次投递。若业务写库、状态更新分成两步,或副作用在外部服务,则存在“效果发生、状态未记录”的窗口,需业务唯一约束、贯穿下游的操作 ID 或对账协议;不能宣称 MQ + 状态字段就实现跨系统严格只执行一次。也不能在发现 running 后直接丢掉唯一通知而没有可靠租约恢复扫描器。