快手 Agent 开发二面:Harness、多 Agent 编排与上下文压缩
- 轮次
- 二面
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- 请介绍一下你的技术背景,重点谈谈你参与过的 Agent 相关工作。
- 选一个你最熟悉的 Agent 项目,讲讲它解决了什么业务问题、整体方案如何设计,以及上线后的实际效果。
- 你怎么理解 Agent Harness?在项目中会怎样搭建它?和直接使用托管式 Agent 服务相比,各自的差异是什么?
- 设计一个多 Agent 系统时,你会怎样划分角色和协作边界?它相比单一 Workflow,适合解决哪些问题?
- 中心调度 Agent 如何把复杂目标拆成子任务、分配给不同 Agent,并判断结果是否完整、如何汇总?
- Agent 的记忆为什么有人选择用 Markdown 文件维护?它和 RAG 在用途、检索方式及更新成本上有什么区别?
- 如果要为 Agent 建设知识库,你会怎样处理数据接入、切分、检索、更新和效果评估?
- Agent 沙箱需要隔离哪些资源和操作?你会怎样设计权限控制,避免 Agent 越权或造成不可逆影响?
- 在没有人工审核的自动执行场景中,你会如何控制 Agent 的错误率和影响范围?怎样设计验证、回滚、限额与监控?
- 大模型的工具调用大致经历哪些步骤?选择或设计工具时,你会如何权衡能力边界、调用成本、可靠性和安全性?
- MCP 解决了什么问题?如果 MCP 工具调用超时、失败或返回异常,你会怎样设计重试、降级和错误反馈?
- Skill 和 MCP 在加载及调用方式上有什么不同?当配置文本长度相近时,Token 开销会受哪些因素影响?你会用什么标准判断一个 Skill 是否有效?
- 请解释 KV Cache 在大模型推理中的作用,以及它对生成速度、显存占用和长上下文有什么影响。
- 如果要用 AI Coding 构建一个支持多个实例并发工作的系统,你会怎样设计任务隔离与协作流程?如何编写首轮提示词,让 Agent 先产出可评审的 Spec?
- 你平时怎样把 AI Coding 用在开发中?遇到 Agent 生成的代码有问题时,通常如何定位和修正?在整个流程里你最重视哪个阶段?
《参考解析》
Harness 是「模型之外的工程」。它指包在模型外面那一层:工具定义与执行、权限与沙箱、上下文装配与压缩、循环控制与终止条件、日志与可观测、失败重试与降级。区分自建 Harness 和托管 Agent 服务的判据是控制权——自建能改循环策略、能自己决定上下文怎么塞、能把工具直接接到内网系统,代价是要自己解决并发、超时、观测这一整套;托管服务省掉这些,但工具能力受平台限制、排查问题时看不到中间态。回答时最好给一个具体的取舍例子,比如「我们需要在工具执行前做路径沙箱校验,托管服务的工具层插不进去,所以自建」。
多 Agent 的划分依据是上下文而非职责名。常见错误是按「产品经理 Agent、开发 Agent、测试 Agent」这种人类组织架构切,结果每个 Agent 都要拿到几乎全部的上下文,协作成本反而高于单 Agent。合理的切法是让每个 Agent 有独立、可压缩的上下文边界,并且产物是可校验的(一份 spec、一个 diff、一份测试报告)。单 Workflow 适合步骤固定、分支少的流程;多 Agent 的价值出现在「任务的成功路径不可预知、需要动态探索」的场景,代价是可预测性和调试难度都会下降。
中心调度的三个动作要能分别说清:拆解(把目标拆成有依赖关系的子任务,最好产出结构化清单而不是自然语言)、分派(决定给谁、给多少上下文、要不要并行)、验收(拿什么判据说这一步完成了)。验收是最容易糊弄的一环——如果只是让模型自己说「我完成了」,那失败会被一路传递到最终产物。可行的做法是每个子任务都带一个程序可判的完成条件(测试通过、schema 校验通过、diff 能 apply)。
记忆用 Markdown 而不是向量检索,本质是「可读、可改、可 diff」。RAG 面向的是「大量、静态、按语义检索」的知识,更新成本在重建索引;Markdown 记忆面向的是「少量、会演进、需要人也能看懂」的状态,更新就是改文件、能进 git 看 diff。两者不是替代关系:项目约定、用户的长期偏好、当前任务进展这类东西适合写文件;产品文档、代码库这类大体量知识适合 RAG。判断标准是更新频率和是否需要人参与编辑。
知识库建设是一条流水线:接入(去重、脱敏、保留出处)→ 切分(按语义边界而不是固定字数,标题层级、代码块、表格都要特殊处理)→ 索引(关键词 + 向量混合,单纯向量对专有名词和编号不友好)→ 检索(召回后重排,多路结果合并)→ 评估(准备带标注的问答题集,分开算召回率和最终答案正确率,否则分不清是检索没召回还是模型没答好)。更新策略上要能增量,全量重建在数据量上来之后是不可接受的。
沙箱的隔离维度要能列举:文件系统(限定可写目录、路径穿越防护)、网络(出站白名单)、进程(资源限额、禁止 fork 炸弹)、凭据(工具侧持有,不暴露给模型)、不可逆操作(删除、发消息、付款要二次确认或直接禁掉)。权限检查必须由程序执行——写进提示词只是引导,不能当安全边界。判断是否越权的逻辑要在工具调用层而不是模型层。
无人审核场景控制错误率靠四件事:可验证的产物(让每一步都有程序能判的通过标准)、限额(单次任务的最大步数、最大花费、最大影响面)、回滚(改动前留快照、外部写操作设计成可撤销)、监控(异常率、失败模式分布、人工抽检)。核心思路是把「模型不出错」换成「出错能被发现且代价可控」。
MCP 与 Skill 的差别在加载时机。MCP 是协议:模型通过标准的工具描述发现可用能力、发起调用、拿回结构化结果,解决的是「工具接进来」的互操作问题,工具列表通常常驻在上下文里,工具一多就吃 token。Skill 更像按需加载的知识包:平时只有一行描述占位,命中时才把完整说明读进上下文,所以同样的篇幅,Skill 的常态开销更低,但多了一次读取的往返。判断一个 Skill 是否有效,看的是「加载后模型的输出有没有变好」,可以用同一批任务做对照——有 Skill 和无 Skill 各跑一遍,比对比对通过率。
KV Cache 的作用与代价:自回归生成时每一步都要对历史 token 做 attention,把已经算过的 K、V 缓存起来可以避免重复计算,把每步复杂度从与序列长度平方相关降到线性相关。代价是显存:占用与层数 × 头数 × 头维度 × 序列长度 × batch 成正比,长上下文时它会成为显存的主要占用者。这也是 PagedAttention 这类分页管理、以及 prefix caching 复用相同前缀的原因——省的不是算力就是显存,两者在长上下文场景下是同一条账。
并发实例的任务隔离,第一件事是把共享状态收干净。多个 Agent 同时改同一个仓库时,冲突来源是工作目录、git 分支、端口、临时文件、数据库。可行做法是一实例一工作树(git worktree)、一实例一分支、端口和资源名带实例前缀。首轮提示词的目标是产出可评审的 Spec 而不是直接写代码:明确要求先输出方案与影响面(改哪些文件、加什么接口、怎么验证),人看过再放行执行,这一步能把返工成本压到最低。
AI Coding 的定位是加速而不是免责。流程上最值得重视的是验证环节:能自动跑的测试、类型检查、lint 一定要跑,改动范围要能看懂(看 diff 而不是看生成的行数)。代码改坏了其他模块这类问题,靠的是「改之前先找到调用方、改之后跑全量测试」,而不是靠模型自己保证。