快手 AI Agent 开发凉经:如何定义 Agent?
- 结果
- 挂
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- 请先做一下自我介绍。
- 项目拷打:介绍你的项目并回答针对项目的追问。
- 如何定义 Agent?它和普通大模型调用有什么区别?
- Agent 具备哪些特征?
- 介绍一下 ReAct 模式。
- 从代码实现工程视角看,ReAct 模式实现要点是什么?
- 除了 Loop 和 Function Calling,还有什么驱动这套循环?
- Loop 过程中上一轮结果怎么传递?
- 整个 Loop 过程中,哪些东西需要单独管理?
- Agent 的停止条件是什么?
- AI 怎样判断分析已经完成并停下来?
- Skill 与 workflow 的对比?
- 为什么把原来的 workflow 改成 Skill?
- workflow 有哪些优点和缺点?
- Skill 有哪些优点和缺点?
- 怎样判断一个 Skill 是不是好 Skill?
- 这个 Skill 具体怎样设计?
- 这套设计怎样达成项目目标?
- 项目中遇到过哪些坑?这些问题怎样解决?
- Agent 适配是否只是模型适配?
- 除了模型以外,不同 Agent 之间真正有哪些差异?
- 高合规场景下,模型可能不遵循 Skill 文档,怎样保证模型不会越权?
- 你怎样验证 Skill 是否按预期运行?
- 怎样降低 Skill 的评测成本?
- 如何在线下大规模评测?
- 工具调用失败怎么恢复?
- 任务被中断怎么恢复?
- 状态保存怎么做?
- 任务恢复怎么做?
- 多 Agent 之间怎么通信?
- 手撕:反转链表。追问:线程池怎么配置?
项目追问
- 你的经历主要集中在 Skill 开发,是否具备 Agent 工程落地经验?
- 你了解哪些主流 Agent 架构或开发框架?它们各有什么优缺点?
- 你是否实际使用过 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;提交顺序是核心线程未满就新建、否则入队、队列满才扩到最大线程、再满走拒绝策略;拒绝策略按业务选背压或落库重试,绝不静默丢弃;线程工厂要命名线程,异常要捕获并统一处理;监控活跃线程数、队列深度、拒绝次数与任务耗时做容量规划。