在 AI 代理系统快速发展的今天,企业构建内部 AI 代理时面临一个关键架构决策:采用 LLM 驱动的工作流,还是回归传统的代码驱动模式?Will Larson 在 Imprint 公司的实践经验揭示了这一决策背后的深层技术考量。本文将从技术实现、适用场景和工程权衡三个维度,系统分析两种工作流模式的差异,并提供可落地的决策框架。
确定性需求:从理想主义到工程现实
Larson 最初坚信 "LLM + 工具使用可以解决任意复杂工作流",这一假设在许多场景下确实成立。他构建的 Slack PR 合并检测工作流就是一个典型例子:通过 LLM 分析 Slack 频道中的消息,提取 GitHub PR 链接,检查状态,并为已合并的 PR 添加:merged:表情。从概念上看,这个工作流完美无缺 —— 智能的工具使用,优雅的自动化。
然而,现实很快给出了不同的答案。系统有时会错误地为未合并的 PR 添加:merged:表情,导致团队成员无法依赖这个信号来判断哪些 PR 需要关注。正如 Larson 所言:"它实际上没有解决我试图解决的问题:错误添加 reacji 意味着人们无法根据 reacji 的存在来评估是否查看某个拉取请求。"
这个案例揭示了 LLM 驱动工作流的核心挑战:非确定性。即使是最先进的 LLM,在处理需要 100% 准确性的任务时,仍然可能产生不可预测的偏差。这种偏差在简单的 PR 状态检测中可能只是小问题,但在财务计算、安全审计或合规检查等场景中,可能带来严重后果。
技术架构对比:共享基础设施,不同控制模式
LLM 驱动工作流架构
LLM 驱动工作流通过一个软件处理器(handler)协调,其工作流程如下:
- 触发识别:外部事件触发工作流,处理器匹配对应的配置
- 资源准备:加载关联的提示词、批准的工具列表,生成虚拟文件(如 Jira 附件、Slack 消息文件)
- LLM 协调:将提示词和可用工具发送给 LLM,协调工具调用,管理虚拟文件访问
- 终止控制:设置工具使用限制,防止无限循环或过度调用
- 结果处理:根据配置决定是否将 LLM 的最终响应输出到目标系统(如 Slack)
配置示例:
# 默认行为(可省略)
coordinator: llm
代码驱动工作流架构
代码驱动工作流采用相同的触发机制和资源访问层,但控制权转移到自定义代码:
coordinator: script
coordinator_script: scripts/pr_merged.py
关键设计要点:
- 相同权限模型:Python 脚本拥有与 LLM 相同的工具访问权限、触发数据和虚拟文件访问能力
- 按需 LLM 调用:代码可以通过
subagent工具在需要时调用 LLM,实现混合控制 - 工程化流程:脚本作为常规代码提交,经过代码审查、测试和版本控制
架构共性设计
两种模式共享的核心基础设施包括:
- 工具抽象层:统一的工具注册、授权和调用接口
- 虚拟文件系统:跨平台文件访问抽象(Slack 附件、Jira 问题文件等)
- 触发机制:统一的事件监听和路由系统
- 配置管理:中心化的工作流配置存储
这种共享设计确保了两种模式可以无缝切换,也为渐进式迁移提供了技术基础。
适用场景分析:何时选择哪种工作流
优先选择 LLM 驱动工作流的场景
- 探索性任务:需求不明确,需要 AI 协助探索解决方案空间
- 自然语言处理:文本分析、情感识别、内容摘要等 LLM 原生优势领域
- 创意生成:文档起草、代码构思、设计建议等创造性工作
- 低风险决策:错误成本可接受的非关键业务逻辑
- 快速原型:需要快速验证概念,时间紧迫的场景
Larson 团队的经验是:"我们仍然从 LLM 开始所有工作流,这在许多情况下都有效。"
优先选择代码驱动工作流的场景
- 确定性要求高:财务计算、状态检测、合规检查等需要 100% 准确性的任务
- 性能敏感:需要低延迟、高吞吐量的生产工作流
- 复杂业务逻辑:涉及多系统集成、状态管理和错误处理的复杂流程
- 长期维护:需要稳定运行、可测试、可调试的生产系统
- 成本控制:避免不必要的 LLM 调用,降低运营成本
混合模式的最佳实践
最有效的策略往往是混合使用两种模式:
- LLM 作为入口:用 LLM 处理自然语言输入,解析意图,然后路由到专门的代码模块
- 代码控制流程:用代码管理工作流状态、错误处理和系统集成
- LLM 处理异常:在代码无法处理的边缘情况下,调用 LLM 进行智能决策
- 渐进式迁移:从 LLM 驱动开始,随着需求明确和可靠性要求提高,逐步迁移到代码驱动
工程化决策框架
决策矩阵:四个关键维度
基于 Larson 的实践,我们提出以下决策框架:
| 维度 | LLM 驱动优势 | 代码驱动优势 | 决策阈值 |
|---|---|---|---|
| 确定性 | 低(70-95%) | 高(>99.9%) | 当准确性要求 > 95% 时选择代码驱动 |
| 开发速度 | 快(小时级) | 慢(天级) | 原型阶段用 LLM,生产阶段评估迁移 |
| 维护成本 | 高(提示工程、模型更新) | 中(代码维护、测试) | 长期运行的工作流倾向代码驱动 |
| 灵活性 | 高(适应新场景) | 低(需要代码修改) | 需求频繁变化时保留 LLM 选项 |
技术选型检查清单
在构建内部 AI 代理时,使用以下检查清单指导技术决策:
-
准确性要求评估
- 任务失败的业务影响是什么?
- 可接受的错误率是多少?
- 是否有验证和纠正机制?
-
性能需求分析
- 延迟要求(实时、近实时、批量)?
- 吞吐量需求(QPS、并发数)?
- 成本预算(LLM 调用费用)?
-
维护性考量
- 工作流变更频率?
- 团队技能组合(提示工程 vs 软件开发)?
- 监控和调试需求?
-
演进路径规划
- 是否需要从 LLM 驱动迁移到代码驱动?
- 架构是否支持渐进式迁移?
- 是否有回滚机制?
实施路线图
基于 Larson 团队的实践经验,推荐以下实施路径:
阶段 1:LLM 优先探索
- 所有新工作流从 LLM 驱动开始
- 建立统一的工具抽象和配置管理
- 收集性能、准确性和可靠性数据
阶段 2:识别迁移候选
- 监控工作流的错误率和业务影响
- 识别高价值、高可靠性的候选工作流
- 评估迁移到代码驱动的成本和收益
阶段 3:渐进式迁移
- 使用 Claude Code 等工具将提示词转换为代码
- 保持向后兼容性,支持两种模式并行运行
- 逐步将流量从 LLM 迁移到代码版本
阶段 4:混合架构优化
- 建立代码驱动工作流的标准模板
- 优化 LLM 调用模式(批量、缓存、降级)
- 完善监控、告警和自愈机制
技术实现细节与最佳实践
配置管理策略
Larson 团队采用的配置模式提供了良好的灵活性:
# 工作流基础配置
workflow:
name: "pr_merge_notification"
trigger: "slack_message"
trigger_pattern: ".*github.com.*pull.*"
# 模式选择
coordinator: "script" # 或 "llm"
# LLM模式配置
llm_config:
model: "claude-3-5-sonnet"
temperature: 0.1
max_tokens: 1000
# 代码模式配置
script_config:
path: "scripts/pr_merged.py"
timeout: 30
retry_policy: "exponential_backoff"
# 共享工具配置
tools:
- "github_api"
- "slack_client"
- "jira_integration"
错误处理与监控
无论选择哪种模式,都需要建立完善的错误处理机制:
-
LLM 驱动工作流的错误处理
- 设置工具调用次数限制
- 实现超时控制和重试逻辑
- 建立 LLM 输出验证层
- 记录完整的思维链用于调试
-
代码驱动工作流的错误处理
- 结构化异常处理
- 事务性操作支持
- 状态持久化和恢复
- 详细的日志和指标收集
-
统一监控体系
- 成功率、延迟、成本指标
- 业务影响度量(如错误决策导致的损失)
- 容量规划和自动扩缩容
- A/B 测试和渐进式发布支持
团队协作与技能发展
构建混合架构的 AI 代理系统需要跨职能团队协作:
- 提示工程师:专注于 LLM 提示优化、few-shot 学习、思维链设计
- 软件工程师:负责代码驱动工作流的开发、测试和部署
- ML 工程师:管理模型选择、微调、评估和更新
- 运维工程师:确保系统可靠性、监控和故障排除
团队应该建立共享的知识库,包括:
- 提示词模板库和最佳实践
- 代码工作流的标准模式和工具
- 性能基准和成本分析
- 故障案例和解决方案
未来展望与演进趋势
随着 AI 技术的快速发展,代码驱动与 LLM 驱动工作流的边界正在变得模糊。几个值得关注的趋势:
-
AI 辅助代码生成成熟化:如 Claude Code 已经能够 "几乎总是将提示词重写为代码工作流",这降低了从 LLM 迁移到代码的门槛。
-
确定性 LLM 的兴起:通过约束解码、程序引导生成等技术,LLM 正在获得更强的确定性保证。
-
混合推理架构:结合符号推理、规则引擎和神经网络的混合系统,在保持灵活性的同时提高可靠性。
-
自主演进系统:能够根据性能数据自动在 LLM 驱动和代码驱动之间切换的自适应系统。
Larson 的结论具有启发性:"即使模型变得更强大,在真正需要智能的地方依赖它们,而不是用于迭代工作流,似乎是我们工具包中的长期补充。"
结语
构建内部 AI 代理时,代码驱动与 LLM 驱动工作流不是非此即彼的选择,而是互补的工具。成功的架构应该支持两种模式,并根据具体场景的需求动态选择。
关键洞察包括:
- 从 LLM 开始:利用其快速原型和探索能力
- 为确定性而迁移:当可靠性要求超过 LLM 能力时,迁移到代码驱动
- 保持架构灵活性:设计支持两种模式的基础设施
- 建立数据驱动的决策流程:基于性能指标而非直觉做出技术选择
最终,最有效的 AI 代理系统将是那些能够智能地在人类编写的代码和 AI 生成的推理之间找到平衡点的系统。这种平衡不是静态的,而是随着技术发展、业务需求变化和团队经验积累而不断演进的动态过程。
资料来源:
- Will Larson, "Building an internal agent: Code-driven vs LLM-driven workflows", Irrational Exuberance, 2025-12-31
- Hacker News 讨论:"Building an internal agent: Code-driven vs. LLM-driven workflows", 2026-01-01