这道题其实是在问,怎么让大模型能真正干活,而不是只会聊天。核心就是模型怎么安全可靠地调用外部能力,以及多个调用怎么组织。
先说工具设计。我遵循三个原则。先说原子性,每个工具只做一件事,比如查订单状态就查订单状态,不要同时改价格。接着说自描述,工具的名字和描述要写得让模型一看就懂什么时候该用,参数用严格的 JSON Schema 定义。再补充防御性,每个工具都要加超时、熔断和结果校验,不能让一个慢工具把整个[[Agent]]拖死。
接着说调用范式,主流两种。一种是 [[Function Calling]],模型原生支持,一次输出结构化的调用参数,适合流程简单、工具确定的场景,比如客服填单。另一种是 [[ReAct]],模型走思考-行动-观察的循环,可以自我纠错,适合多步推理、需要反思的任务,比如生成研报。落地时我通常两者混用,高频确定的任务用Function Calling,复杂分析用ReAct。
工作流这块,分静态和动态。静态DAG是预定义好节点和边,比如先查用户信息再查订单,好处是可控、可缓存、好优化,缺点是不灵活。动态规划是模型自己决定下一步,像AutoGPT,好处是能处理开放任务,缺点是延迟高、可能死循环、难调试。我倾向混合架构:用户意图识别后,路由到预设的静态Workflow,或者交给开放的动态Agent。说白了,静态保效率,动态保灵活,一起上才是工程常态。
举个例子,在客服退款场景。高频的退款填单,用静态Workflow加Function Calling,先查订单再查物流然后退款,每一步结果校验,延迟可控。但如果是用户投诉“商品有问题,我要赔偿”,这种开放任务,就得用ReAct动态选工具,查聊天记录、查质检报告、查历史案例,模型自己规划。这里有个坑:工具结果回传容易撑爆上下文。我会对结果做摘要,只传关键信息,比如“用户近3个月退款5次,金额均低于100元”,而不是全量数据。
上线前我会特别关注两个风险。一是工具调用失败后的降级策略,比如查库存超时,是重试还是直接返回“库存未知”。二是权限控制,不是所有工具都能给模型随便调,比如改价格、发优惠券必须走人工审核。
其实还有一个延伸点,就是工具之间怎么共享状态。比如先查了用户信用分,后面改价格时要不要复用这个结果?这就涉及到Agent的短期记忆和长期记忆的设计,以及状态管理的粒度。
所以整体上,我会把工具和工作流看成Agent的“手”和“骨架”,手要稳,骨架要灵活,但两者都得有兜底。