面灵AI→

快手 AI Agent 开发凉经:如何定义 Agent?

结果
挂
时间
2026-10
来源
牛客网

《面试题目》

  1. 请先做一下自我介绍。
  2. 项目拷打:介绍你的项目并回答针对项目的追问。
  3. 如何定义 Agent?它和普通大模型调用有什么区别?
  4. Agent 具备哪些特征?
  5. 介绍一下 ReAct 模式。
  6. 从代码实现工程视角看,ReAct 模式实现要点是什么?
  7. 除了 Loop 和 Function Calling,还有什么驱动这套循环?
  8. Loop 过程中上一轮结果怎么传递?
  9. 整个 Loop 过程中,哪些东西需要单独管理?
  10. Agent 的停止条件是什么?
  11. AI 怎样判断分析已经完成并停下来?
  12. Skill 与 workflow 的对比?
  13. 为什么把原来的 workflow 改成 Skill?
  14. workflow 有哪些优点和缺点?
  15. Skill 有哪些优点和缺点?
  16. 怎样判断一个 Skill 是不是好 Skill?
  17. 这个 Skill 具体怎样设计?
  18. 这套设计怎样达成项目目标?
  19. 项目中遇到过哪些坑?这些问题怎样解决?
  20. Agent 适配是否只是模型适配?
  21. 除了模型以外,不同 Agent 之间真正有哪些差异?
  22. 高合规场景下,模型可能不遵循 Skill 文档,怎样保证模型不会越权?
  23. 你怎样验证 Skill 是否按预期运行?
  24. 怎样降低 Skill 的评测成本?
  25. 如何在线下大规模评测?
  26. 工具调用失败怎么恢复?
  27. 任务被中断怎么恢复?
  28. 状态保存怎么做?
  29. 任务恢复怎么做?
  30. 多 Agent 之间怎么通信?
  31. 手撕:反转链表。追问:线程池怎么配置?

项目追问

  1. 你的经历主要集中在 Skill 开发,是否具备 Agent 工程落地经验?
  2. 你了解哪些主流 Agent 架构或开发框架?它们各有什么优缺点?
  3. 你是否实际使用过 LangChain 或 LangGraph?LangGraph 有哪些优点和缺点?

《参考解析》

1. 如何定义 Agent,以及它与普通大模型调用的区别。 普通大模型调用是一次无状态的函数映射:给定输入返回输出,模型不知道环境、不能行动、也不会自己再想一步。Agent 在模型外面套了一层运行时,具备五个特征:目标驱动、环境感知(读文件、看接口返回、观察命令输出)、工具行动(能改变外部状态)、状态保持(记住已做什么、还剩什么)、多轮自我修正(按反馈调整策略而不是一次成型)。所以判据是有没有自主的决策循环,而不是用没用大模型。工程上还要区分自主 Agent 与受控 Agent:真实业务里几乎都是后者——外层由代码定义状态机、预算与终止条件,模型只负责某个节点内的判断,这样成本、延迟与行为都可控。

2. ReAct 的工程实现要点。 表面是 Thought、Action、Observation 循环,工程上有六处必须显式处理。循环驱动:while not done and step < max_steps,由代码控制,模型不能自己决定继续。输出解析:优先原生 function calling,没有就用严格 JSON 加校验与修复。上轮结果传递:工具结果作为独立消息(带工具名与调用 ID)追加进消息列表,与 assistant 的调用决定成对出现。单独管理的状态:已调用过的工具与参数集合(去重、防绕圈)、任务预算与已消耗量、当前子目标与进度、失败与重试计数,由代码维护并每轮注入。停止条件:子目标都有证据支撑,或触顶步数、token、时间、重试,触顶走降级;模型说“我完成了”只是信号,最终判定由代码或校验器做。除 Loop 与 function calling,驱动循环的还有外部事件与显式状态机跳转,这也是很多团队最后用图结构把流转定义出来的原因。

3. Skill 与 workflow 的取舍。 Workflow 是代码写死的确定性编排:步骤、分支、重试、超时都由代码控制,优点是可预测、可测试、成本低、出错好定位、合规动作能强约束;缺点是僵化,需求稍变就要改代码,覆盖不了开放输入的长尾。Skill 是把做某件事的方法、资料与工具打包成模型可读的资产,由模型在运行时决定怎么用,优点是灵活、可组合、扩展只要加文档;缺点是行为不确定、成本更高、权限与评测更难。把 workflow 改成 Skill 通常是因为原流程被长尾需求撑爆了,于是把怎么做教给模型、只保留少数硬约束。判断 Skill 好不好:边界清楚(何时用、何时别用)、自包含、可验证(有成功判据或检查手段)、输入输出稳定不靠猜、粒度合适、有配套评测集与失败样例;还要能回答它降低了哪类任务的失败率。

4. 合规场景下的越权风险与 Skill 验证。 分层做法:关键动作做成代码门(写操作、付款、对外发送必须走确认或审批,模型只有申请权没有执行权);工具按身份鉴权并保持最小权限;硬约束落到 schema 校验、白名单枚举、参数范围校验上,让违规参数根本构造不出来;输出做后置校验;全部工具调用留审计日志。Skill 验证靠可判定的结果加回归集:为每个 Skill 定义输入样例与期望行为(不只输出文本,还包括调了哪些工具、有没有越界),用录制回放或沙箱执行比对。降低评测成本的手段:自动判据优先(结构校验、工具序列断言优于人工读输出);LLM 判官只用在需要主观判断的部分并与人工标注校准;失败样例自动转成回归用例;不需要重复测的部分抽成确定性单测。大规模线下评测靠并发执行、沙箱隔离与看板,并按 Skill、场景、难度分层报数。

5. 工具失败与任务中断的恢复。 恢复能力的前提是状态外置与幂等。状态保存要回答存什么、存哪、多细:存任务状态(阶段、已完成步骤、待办、失败与重试次数)、关键产物(大对象放对象存储只留引用)与上下文快照;热数据放 Redis、冷数据归档;检查点以子任务完成、工具调用前后为界。工具调用失败要分类:瞬时错误退避重试一到两次;确定性错误(参数错、权限不足、资源不存在)不重试,把结构化错误交给模型改参数或换工具;工具成功但结果不合期望则换策略。写操作必须带幂等键,恢复前先查外部状态确认是否已生效。任务被中断分两种:进程崩溃靠检查点重放并靠幂等保证安全;用户主动打断要区分暂停(保留状态可续跑)与取消(释放沙箱、清理临时产物、保留审计)。恢复后还要处理陈旧与冲突:任务有租约与心跳,失联超阈值由巡检接管并用 CAS 改状态;恢复设上限,反复失败落死信队列并告警。

6. 多 Agent 通信与主流框架的取舍。 通信按耦合度排:共享工作区(文件、对象存储、数据库)最松,适合长任务与人工介入,要处理并发写冲突;消息传递(进程内队列或跨机 MQ)是常规选择,解耦、可缓冲、可重放,代价是重复投递与顺序问题,所以每条消息带 taskId 与幂等键;共享内存只适合同机强协作。最稳的是控制面走消息、数据面走共享存储只传引用。框架层面,LangChain 的价值是生态与抽象齐全、上手快;缺点是抽象层多、版本变动频繁、出错时栈很深难定位,很多高级编排最终要绕开默认行为自己写。LangGraph 把流程显式建成图(节点、边、条件分支、循环),状态可在节点间传递并持久化,优点是流转可控、天然支持暂停恢复与人工介入、可观测性好,适合受控 Agent 与需要断点续跑的长任务;缺点是要求先想清状态模型与图结构,改造成本高于自己写循环。框架只解决编排,沙箱、权限、评测、Trace 仍得自己搭。

7. 反转链表与线程池配置。 反转链表用三指针迭代:prev=null、cur=head,循环里先保存 next,再 cur.next=prev,然后 prev=cur、cur=next,结束返回 prev;递归版基线是空节点或单节点返回自身,长链表下有栈溢出风险。线程池配置按任务画像、参数、队列、拒绝、监控来讲:CPU 密集型线程数取核数加一左右,IO 密集型按“核数 ×(1 加等待时间除以计算时间)”估算并靠压测校准;corePoolSize 决定常驻并发能力,maximumPoolSize 只是队列满后的应急扩容,所以队列必须有界,无界队列会让最大线程数形同虚设并最终 OOM;提交顺序是核心线程未满就新建、否则入队、队列满才扩到最大线程、再满走拒绝策略;拒绝策略按业务选背压或落库重试,绝不静默丢弃;线程工厂要命名线程,异常要捕获并统一处理;监控活跃线程数、队列深度、拒绝次数与任务耗时做容量规划。