东方财富 AI 应用一面:Skill 路由评测与上下文分层
- 轮次
- 一面
- 时间
- 2026-09
- 来源
- 牛客网
《面试题目》
- 自我介绍。
- 最近的实习 Agent 项目背景、团队职责、你个人做什么?
- 为什么做 Skill 路由评测?正反例怎样构造?
- 除描述外误路由还有什么原因?Skill 数量影响吗?做过大规模优化吗?
- 路由如何量化、什么阈值放行?方案上线了吗?
- 历史消息膨胀与错/漏召回怎样处理?Context 怎么分层?
- 金融场景工具返回五六千只 A 股、用户要求全量输出,压缩的信息损失怎么办?
- 从大上下文模型切到小上下文模型,历史 Context 怎么处理?
- 第二个实习多数据源并发召回为什么用专用线程池?不共享会防住什么问题?
- Guava/Tair 两级缓存如何处理一致性?
- 历史访问预热若热点变化,有什么副作用?怎样识别新热点?
- 你提到的近似统计结构怎样工作,能不能找出 Top K 热点 Key?
- 平时使用什么 AI Coding 工具与模型?
- 让 AI 写代码有哪些经验?怎样保证符合业务和历史逻辑?
- 模型生成的代码会全部人工 Review 吗?如何控制改动范围?
- 工具之间有依赖,怎么并行执行并处理错误?
- 手撕:拓扑排序场景题。
《参考解析》
Skill 路由评测的必要性:Skill 通常以”元数据常驻、正文按需加载”的方式工作,路由错了有两种代价——该加载的没加载,模型缺能力只能瞎答;不该加载的加载了,白占上下文还可能误导。所以要建评测集,用正例(请求 → 应当加载 A)和反例(相似请求 → 应当加载 B,或不应加载任何 Skill)算准确率与混淆矩阵,重点看误路由的方向分布。
误路由的原因不止描述:除 description 写得含糊外,还有——Skill 之间功能重叠(触发条件相近)、Skill 名称过于宽泛、元数据缺少”不适用场景”、用户请求本身歧义(需要澄清而不是硬路由)、以及上下文里已有信息让模型误判(比如上文提到过 A,模型就倾向继续用 A)。Skill 数量增加会显著恶化路由准确率,因为候选变多、区分度下降。大规模优化手段是两级路由(先按业务域粗分,再在域内精选 2-3 个候选)加上”负面示例”(明确写清什么情况下不要用这个 Skill)。
路由怎么量化与放行:定义指标——路由准确率、误加载率(不该加载却加载)、漏加载率,按业务重要性分别设阈值。方案是否上线的判据不能只看总体准确率,而是”高风险请求(涉及资金、权限、不可逆操作)必须零漏加载、误加载率低于 X%“。上线通常走灰度 + 线上采样人工复核。
历史膨胀与错漏召回:处理思路是分层——最近几轮保留原文(保证细节),中期做摘要(保留结论与关键证据),更早的只保留索引 + 关键结论,原文落外部存储并留可按需回查的 ID。错召回的修复是”上下文里标注来源与时间”,让模型能判断新旧;漏召回的修复是保证压缩时保留”与当前任务相关的证据”,而不是按时间一刀切。关键原则:压缩只作用于送入模型的上下文,不改变可回查的原始数据。
全量输出的信息损失:金融场景里用户要求”把 5000 多只股票都列出来”,这本质是生成侧的限制,不能靠上下文压缩解决——压缩了就没法全量输出。正确做法是识别出「用户要的是一份完整数据」而不是「要模型复述数据」,把任务转成工具/查询链路:由程序生成完整结果文件或分页返回,模型只负责组织与解释。如果必须由模型输出,则分段生成 + 程序拼接,避免一次性塞进上下文。回答这题的关键是不要把”压缩”当成万能解,要区分”要模型理解”和”要模型完整搬运”。
从小上下文模型切到大/小模型:切换窗口时要重新做上下文装载策略——按新窗口大小重算预算(系统指令 + 工具定义 + 历史 + 检索内容各占多少)、把超出部分提前摘要或丢弃、并保持前缀稳定以命中缓存。降级到小窗口时要明确”哪些信息是必须保留的”(当前任务目标、关键证据、未完成的步骤),宁可丢掉闲聊式历史,也不能丢任务状态。
专用线程池的选择:为了隔离。共享线程池时,一个慢下游会把池里线程占满,导致其他数据源也排队超时——局部故障扩散成整体雪崩。专用池把爆炸半径限制在该数据源内,也便于单独设参数(线程数、队列长度、超时)和观测。代价是线程总量增加、资源占用变多,所以要给每个池设明确上限。
两级缓存一致性:Guava(进程内)+ Tair/Redis(跨实例)。一致性手段组合使用:短 TTL(兜底,保证最终收敛)、更新时删缓存(Cache-Aside,先更新 DB 再删缓存)、发布订阅广播失效(加速收敛但不可靠)、版本号校验(读到旧版本就丢弃并回源)。切忌把广播当作唯一手段——消息丢失和实例离线都会导致长期不一致。
热点变化与预热的副作用:预热基于历史访问,如果热点发生迁移(如新活动上线、突发新闻),预热的内容就成了无用占用,还可能把缓存空间挤掉真正需要的数据。识别新热点靠实时统计——滑动窗口的访问计数、或用 Redis 的 LFU、Count-Min Sketch 这类近似结构。副作用还包括:预热可能放大缓存不一致的窗口(旧数据被大量实例缓存)、以及冷启动时的回源压力。
近似统计结构找 Top K:Count-Min Sketch 用 d 行 w 列的计数器 + d 个哈希函数,插入时对每行的对应位置加一,查询时取最小值,用固定内存估算频率(可能高估,不会低估)。找 Top K 的标准组合是「Sketch 估算频率 + 最小堆维护候选」:对每个元素查 Sketch 得到估计频率,堆里保留最大的 K 个。要注意它无法枚举所有 key(不知道有哪些 key 出现过),所以通常与”采样记录 + 堆”结合;另外有衰减需求的场景要用滑动窗口版(如时间衰减的 Sketch 或 Space-Saving 算法)。
AI 写代码的经验:核心三点——① 给足上下文:目录结构、数据模型、既有代码风格、内部工具类的用法,以及明确的边界(不要新增依赖、不要改公共接口、不要动 x 目录);② 让它先给计划再落地,改动范围限定在必要文件;③ 用确定性检查兜底(编译、类型检查、lint、测试),人只 review 机器看不出的部分。不必要求逐行人工 review,但要按风险分级——公共模块、数据迁移、权限相关必须人审。
工具依赖怎么并行:先构建依赖图(DAG),没有依赖关系的节点并行执行,有依赖的按拓扑序执行。错误处理分三类:可重试的(网络抖动)带退避重试;不可重试的(参数错误、权限拒绝)立即终止该分支;部分失败的(多个独立分支里一个失败)要么降级返回已有结果并标注缺失,要么整体失败——取决于业务能接受哪种。并行时要注意共享状态与限流,避免并行把下游打爆。
拓扑排序:Kahn 算法(BFS)——统计每个节点的入度,把入度为 0 的入队;出队时把它加入结果,并将所有后继节点入度减一,减到 0 的入队。若最终结果节点数少于总数说明存在环。DFS 版本用三色标记(未访问/访问中/已访问),遇到”访问中”的邻居即判定有环。场景题常见变体是最长路径(DAG 上的 DP)、任务调度最短时间(关键路径)、以及课程表类的可行性判断。