构建 AI Agent 系统的编排模式指南

7 阅读39分钟

面向读者:正在构建 AI Agent 系统的工程师 / 架构师

文档定位:从原理到实战的全面参考手册,覆盖模式选型、架构设计、生产落地与常见陷阱

基础参考:Inngest 联合创始人 Dan Farrelly 的 Sub-Agent 三模式框架 + Anthropic Agent 构建指南 + 业界生产实践


目录


一、为什么需要编排模式

一个直观的问题:为什么不能把所有任务都塞给一个大模型,让它自己搞定?

答案来自三个工程现实:

1.1 上下文窗口不是银弹

即使模型的上下文窗口已扩展到 100K+ tokens,"能装下"和"能有效利用"是两回事:

  • 注意力稀释:上下文越长,模型对关键信息的关注度越低("Lost in the Middle" 问题)
  • 延迟线性增长:每增加 1K tokens,推理延迟和成本都在增加
  • 质量不可控:长上下文中的噪声信息会导致幻觉率上升

1.2 单体 Agent 的扩展性天花板

当业务复杂度上升,单体 Agent 会遇到:

  • 能力边界:一个 System Prompt 无法覆盖所有场景的最优指令
  • 调试噩梦:一个 50 步的 Agent 链路中出了问题,定位成本极高
  • 并发限制:同步执行所有任务,无法利用并行加速

1.3 编排的本质:分治与组合

编排模式的核心思想是软件工程中最基本的原则——分治法

复杂任务 → 拆分为可管理的子任务 → 独立执行 → 聚合结果

正如微服务架构拆分单体应用,Agent 编排模式将复杂的 AI 任务拆分为协作的子 Agent,每个子 Agent 有独立的上下文、明确的职责和清晰的接口。


二、核心概念:上下文压缩与 Sub-Agent

在深入具体模式之前,先理解两个基础概念。

2.1 Sub-Agent 是什么

Sub-Agent 是由父 Agent 生成的独立 LLM 执行上下文,用于处理特定范围的任务。关键特征:

  • 独立上下文窗口:不与父 Agent 共享完整的上下文历史
  • 独立 System Prompt:可以针对子任务定制指令
  • 结果摘要返回:完成后只将精简摘要返回给父 Agent

2.2 上下文压缩的威力

这是 Sub-Agent 模式的核心价值。以一个实际场景说明:

场景:父 Agent 需要分析一个代码仓库的安全风险

不使用 Sub-Agent:
├── 读取 8 个文件 → 每个文件 ~2000 tokens → 16,000 tokens
├── 15 次工具调用的输入输出 → ~8,000 tokens  
├── 中间推理过程 → ~4,000 tokens
└── 总计:~28,000 tokens 直接堆入父 Agent 上下文

使用 Sub-Agent:
├── Sub-Agent 在独立上下文中完成所有工作
├── 返回给父 Agent 的摘要 → ~750 tokens
└── 上下文节省:90%+

实测数据(来自 Dan Farrelly):Sub-Agent 模式能将添加到父 Agent 上下文中的 token 数量减少 90% 以上

2.3 深度控制原则

关键设计约束——深度 1 的委托

父 Agent → 可以生成 Sub-Agent → Sub-Agent 不能再生成 Sub-Agent

为什么?

  • 避免递归生成导致的无限循环
  • 防止成本失控(指数级增长)
  • 简化调试和可观测性
  • 实践证明,一层委托已经能覆盖绝大多数场景

三、三种 Sub-Agent 核心模式(深度篇)

3.1 同步模式(Synchronous)

核心语义

"做这件事,我等你"

父 Agent 生成 Sub-Agent 并阻塞等待,直到获得结果。Sub-Agent 完成后将摘要作为工具调用结果返回。

架构图

┌─────────────┐     spawn & wait     ┌─────────────┐
│  父 Agent   │ ──────────────────→  │  Sub-Agent  │
│  (blocked)  │                      │  (running)  │
│             │  ←── summary ──────  │  (done)     │
│  (continue) │                      └─────────────┘
└─────────────┘

适用场景

场景说明示例
数据依赖后续步骤依赖 Sub-Agent 的输出先查库存,再决定是否下单
查询-决策需要基于查询结果做判断分析日志后决定是否告警
代码生成生成的代码需要反馈到当前流程生成 SQL 后执行并展示结果
验证环节需要验证结果才能继续检查 API 响应格式是否正确

设计要点

# 伪代码:同步 Sub-Agent 实现
class SyncSubAgent:
    def execute(self, task: str, tools: list, parent_context: str) -> str:
        """
        关键设计:
        1. 独立的上下文窗口
        2. 指令偏向简洁(因为结果会被父 Agent 综合)
        3. 带有超时机制
        """
        sub_agent = create_agent(
            system_prompt=f"""
            你是一个专注的任务执行者。
            任务完成后,用简洁的摘要返回结果。
            不需要解释过程,只需要关键结论和数据。
            """,
            tools=tools,
            # Sub-Agent 不能再生成 Sub-Agent
            can_spawn_sub_agents=False
        )
        
        # 阻塞等待,带超时
        result = sub_agent.run(
            task=task,
            timeout=60,  # 秒
            max_steps=20  # 最大工具调用次数
        )
        
        # 返回压缩后的摘要
        return result.summary  # ~750 tokens vs 原始 ~28,000 tokens

注意事项

  • ⚠️ 超时必设:没有超时机制的同步等待是生产事故的温床
  • ⚠️ 步数上限:限制 Sub-Agent 的最大工具调用次数,防止无限循环
  • ⚠️ 降级策略:Sub-Agent 超时或失败时,父 Agent 应有兜底方案
  • 💡 指令要求简洁:告诉 Sub-Agent "简洁返回",因为父 Agent 会综合结果

3.2 异步模式(Asynchronous)

核心语义

"去做这件事,完成后直接告诉用户"

父 Agent 启动 Sub-Agent 后立即继续,不等待结果。Sub-Agent 独立运行,完成后直接向用户回复。

架构图

┌─────────────┐     fire & forget     ┌─────────────┐
│  父 Agent   │ ──────────────────→   │  Sub-Agent  │
│  (continue) │                       │  (running)  │
│             │                       │     ...     │
│  (done)     │                       │  (done)     │
└─────────────┘                       └──────┬──────┘
                                             │
                                             ▼
                                      ┌─────────────┐
                                      │    用户      │
                                      │ (收到结果)   │
                                      └─────────────┘

适用场景

场景说明示例
长时间任务执行时间远超用户等待容忍度生成 30 页研究报告
副作用操作需要执行但不影响当前决策发送通知邮件、记录审计日志
并行批处理多个独立任务同时执行同时分析 5 个竞品的产品页
不阻塞交互希望用户继续与 Agent 对话"我帮你查着,你可以继续问别的"

设计要点

# 伪代码:异步 Sub-Agent 实现
class AsyncSubAgent:
    def dispatch(self, task: str, tools: list, callback_channel: str) -> str:
        """
        关键设计:
        1. Fire-and-forget,父 Agent 不等待
        2. 指令偏向详尽(因为结果直接给用户看)
        3. 完成后通过指定渠道通知用户
        """
        sub_agent = create_agent(
            system_prompt=f"""
            你是一个独立的任务执行者。
            完成任务后,生成详细、完整、对用户友好的报告。
            用户不会看到你的执行过程,只能看到最终结果。
            请确保结果自包含、易理解。
            """,
            tools=tools,
            can_spawn_sub_agents=False
        )
        
        # 异步派发,立即返回
        job_id = sub_agent.dispatch_async(
            task=task,
            callback=callback_channel,  # Slack/邮件/WebSocket
            timeout=300,  # 异步任务可以给更长时间
            max_steps=50
        )
        
        return f"任务已启动 (ID: {job_id}),完成后将通知你。"

关键区别:同步 vs 异步的指令差异

这是一个常被忽略但极其重要的设计点:

维度同步 Sub-Agent异步 Sub-Agent
输出风格简洁、结构化详尽、用户友好
原因父 Agent 会整合和润色结果直接面向用户
典型指令"返回关键数据点即可""生成完整报告,包含上下文解释"

注意事项

  • ⚠️ 结果不回流:父 Agent 无法获取异步 Sub-Agent 的结果,如果需要结果做判断,应该用同步模式
  • ⚠️ 通知机制必备:必须有可靠的渠道将结果送达用户
  • ⚠️ 幂等性设计:异步任务可能被重试,确保多次执行不会产生错误副作用
  • 💡 Dan Farrelly 的建议如果你不确定用哪种模式,默认选异步——成本更低,父 Agent 更精简

3.3 定时模式(Scheduled)

核心语义

"在未来某个时间点做这件事"

父 Agent 安排 Sub-Agent 在指定时间运行。执行时基于当时的最新数据做决策,而非预设响应。

架构图

┌─────────────┐     schedule     ┌──────────────┐     at T    ┌─────────────┐
│  父 Agent   │ ──────────────→  │  调度系统     │ ──────────→ │  Sub-Agent  │
│  (done)     │                  │  (waiting)    │            │  (running)  │
└─────────────┘                  └──────────────┘            └──────┬──────┘
                                                                     │
                                                                     ▼
                                                              ┌─────────────┐
                                                              │    用户      │
                                                              └─────────────┘

与传统 Cron Job 的本质区别

传统 Cron Job:
  "每天 9:00 发送昨日报表"
  → 固定脚本,固定数据源,固定格式
  → 无法适应变化

定时 Sub-Agent:
  "明天 9:00 检查部署指标"
  → 在 9:00 基于实时数据判断
  → 可能发现异常 → 自动查日志 → 生成诊断报告
  → 也可能一切正常 → 发送简短确认
  → 具有上下文意识和自主决策能力

适用场景

场景说明示例
智能跟进基于时间点的上下文感知提醒"3 天后检查 PR 是否已合并"
定期巡检周期性的智能检查"每天 9 点检查线上服务健康度"
延迟决策需要等待条件成熟"1 小时后检查 A/B 测试数据是否达到统计显著性"
SLA 监控超时自动升级"24 小时后检查工单是否已处理,否则升级"

设计要点

# 伪代码:定时 Sub-Agent 实现
class ScheduledSubAgent:
    def schedule(self, task: str, run_at: datetime, tools: list, 
                 callback_channel: str) -> str:
        """
        关键设计:
        1. 本质是延迟触发的异步 Sub-Agent
        2. 执行时获取最新数据(不是预存数据)
        3. 需要持久化调度信息(数据库/消息队列)
        """
        job = scheduler.create_job(
            run_at=run_at,
            agent_config={
                "system_prompt": """
                你是一个智能巡检 Agent。
                检查当前系统状态,基于实时数据做出判断。
                如果发现异常,详细说明问题并建议解决方案。
                如果一切正常,简短确认即可。
                """,
                "tools": tools,
                "task": task,
                "callback": callback_channel
            }
        )
        
        return f"已安排在 {run_at} 执行 (Job ID: {job.id})"

注意事项

  • ⚠️ 持久化调度:定时任务必须持久化到可靠存储(数据库),不能只存内存
  • ⚠️ 时区处理:明确时区,避免 "我说的9点和系统理解的9点不一样"
  • ⚠️ 过期策略:定义任务过期窗口(如超过预定时间 1 小时则取消)
  • ⚠️ 执行上下文:确保 Sub-Agent 在触发时能获取到所需的工具和权限
  • ⚠️ 任务描述冻结(关键限制):排队时的任务描述是"快照"——在调度时刻被固定下来。如果从调度到实际执行之间经过了较长时间,任务描述中引用的上下文可能已经过时。例如:"检查 PR #123 的状态"在排队时有意义,但执行时该 PR 可能已被关闭。缓解策略:① 任务描述中尽量引用可查询的标识符(如 PR 编号),而非快照数据;② 通过句柄(handle)支持查询和取消已排队任务
  • ⚠️ 排队后难以修改:一旦任务进入调度队列,修改或取消的成本较高。设计时应预留通过任务句柄(handle)查询状态和取消任务的能力

3.4 三种模式对比总结

维度同步异步定时
父 Agent 行为阻塞等待立即继续立即继续
结果流向返回给父 Agent直接给用户直接给用户
父上下文影响增加(摘要级别)零增加零增加
适合任务时长秒级~分钟级分钟级~小时级未来任意时间
并行支持不支持(阻塞中)天然支持天然支持
典型超时设置30-120 秒5-30 分钟取决于任务
复杂度中-高
底层实现函数调用消息队列/事件调度器+消息队列

3.5 决策框架:如何选择模式

Dan Farrelly 提供了一个简洁的决策树:

需要结果才能继续?
├── 是 → 同步模式
└── 否
    ├── 应该在未来某时间执行?
    │   ├── 是 → 定时模式
    │   └── 否
    │       ├── 多个独立任务?→ 异步模式(并行)
    │       └── 单个独立任务?→ 异步模式
    └── 不确定?→ 默认选异步

核心原则:不确定时选异步。原因:

  1. 零协调开销
  2. 父 Agent 上下文保持精简
  3. 天然支持并行
  4. 成本最优

四、更多编排模式(广度篇)

除了 Dan Farrelly 的三种 Sub-Agent 模式,业界(特别是 Anthropic 官方指南)还总结了更多实用的编排模式。

4.1 提示链(Prompt Chaining)

核心思想

将复杂任务分解为线性的步骤序列,每一步的输出作为下一步的输入。可以在步骤之间加入代码检查点(Gate)。

架构图

Input → [Step 1] → Gate ✓ → [Step 2] → Gate ✓ → [Step 3] → Output
                     ✗                    ✗
                     ↓                    ↓
                   Error               Error

适用场景

  • 文档先写大纲,审核通过后再写正文
  • 数据处理流水线:提取 → 清洗 → 转换 → 格式化
  • 多语言翻译:先翻译,再审校,再本地化调整

代码示例

def prompt_chain(input_data: str, steps: list[str], gates: list[callable] = None) -> str:
    """
    链式调用多个 LLM 步骤,可选地在步骤间加入质量门控。
    """
    result = input_data
    for i, step_prompt in enumerate(steps):
        result = llm_call(f"{step_prompt}\nInput: {result}")
        
        # 可选:步骤间的质量检查
        if gates and i < len(gates) and gates[i]:
            if not gates[i](result):
                raise QualityGateError(f"Step {i+1} failed quality check")
    
    return result

# 使用示例:生成技术文档
doc_steps = [
    "根据以下需求,生成文档大纲(包含章节标题和要点)",
    "基于以下大纲,为每个章节撰写详细内容",
    "审核以下文档,修正技术错误并优化表达"
]

何时使用 / 何时不用

  • :任务可以自然分解为有序步骤,后续步骤依赖前序输出
  • 不用:步骤之间没有依赖关系(应该用并行化)
  • 不用:需要动态决定执行路径(应该用路由或协调者模式)

4.2 路由(Routing)

核心思想

对输入进行分类,将其定向到不同的专门处理链路。适合输入多样、处理逻辑差异大的场景。

架构图

                        ┌──→ [链路 A:账单问题处理]
Input[分类器/路由器] ├──→ [链路 B:技术支持处理]
                        └──→ [链路 C:账户安全处理]

适用场景

  • 客服系统:根据问题类型分流到不同处理链路
  • 多模态输入:文本 / 图片 / 代码走不同处理管线
  • 多租户系统:不同客户走不同的模型或策略

代码示例

def route(input_text: str, routes: dict[str, str]) -> str:
    """
    路由器:先分类,再用对应的专门提示词处理。
    """
    # Step 1: 分类
    classifier_prompt = f"""
    分析以下输入,选择最合适的处理团队:{list(routes.keys())}
    
    <reasoning>你的分析过程</reasoning>
    <selection>选择的团队名</selection>
    
    Input: {input_text}
    """
    response = llm_call(classifier_prompt)
    selected_route = extract_xml(response, "selection").strip()
    
    # Step 2: 使用对应链路处理
    handler_prompt = routes[selected_route]
    return llm_call(f"{handler_prompt}\nInput: {input_text}")

# 路由定义
support_routes = {
    "billing":   "你是账单专家。帮用户解决费用、退款、订阅问题...",
    "technical": "你是技术支持工程师。帮用户排查技术故障...",
    "security":  "你是安全专家。帮用户处理账户安全、权限问题..."
}

关键设计决策

  • LLM 路由 vs 规则路由:LLM 路由更灵活但有延迟开销,规则路由更快但不够灵活
  • 兜底策略:必须有默认路由处理未匹配的输入
  • 信心阈值:路由器信心不足时,走通用处理链路而非强行分类

4.3 并行化(Parallelization)

核心思想

同一任务由多个 LLM 同时处理,结果通过聚合策略合并。有两种子模式:

  1. 分片并行(Sectioning):任务被拆分为独立子任务,并行执行
  2. 投票并行(Voting):同一任务由多个实例处理,通过投票决定最终结果

架构图

分片并行:                         投票并行:
         ┌→ [Worker A: 子任务1]           ┌→ [Instance 1]
Input →  ├→ [Worker B: 子任务2] → Merge    Input → ├→ [Instance 2] → Vote → Output
         └→ [Worker C: 子任务3]           └→ [Instance 3]

代码示例

from concurrent.futures import ThreadPoolExecutor

def parallel_section(task_prompt: str, sub_tasks: list[str], 
                     n_workers: int = 3) -> list[str]:
    """分片并行:不同子任务同时执行"""
    with ThreadPoolExecutor(max_workers=n_workers) as executor:
        futures = [
            executor.submit(llm_call, f"{task_prompt}\n子任务: {sub}")
            for sub in sub_tasks
        ]
        return [f.result() for f in futures]

def parallel_vote(task: str, n_votes: int = 3) -> str:
    """投票并行:多个实例处理同一任务,取多数意见"""
    with ThreadPoolExecutor(max_workers=n_votes) as executor:
        futures = [executor.submit(llm_call, task) for _ in range(n_votes)]
        results = [f.result() for f in futures]
    
    # 简单多数投票(实际可以更复杂)
    return most_common(results)

适用场景

  • 分片:从不同角度分析同一个问题(客户/员工/投资者视角)
  • 分片:同时处理多个独立的数据源
  • 投票:安全敏感的判断(如内容审核,多实例投票降低误判率)
  • 投票:代码审查(多个实例独立检查,汇总发现)

4.4 协调者-工作者模式(Orchestrator-Worker)

核心思想

中央协调者 LLM 动态分解任务,将子任务委派给 Worker LLMs,最后综合结果。与并行化的关键区别:子任务不是预定义的,而是由协调者根据输入动态生成的

架构图

                     ┌→ [Worker 1] → Result 1 ─┐
Input[Orchestrator] ├→ [Worker 2] → Result 2 ─┼→ [Orchestrator] → Output
         (分析&拆分)  └→ [Worker N] → Result N ─┘    (综合&输出)

适用场景

  • 大型代码重构:协调者分析影响范围,动态分配文件级修改任务
  • 复杂报告生成:协调者拆分章节,Worker 并行撰写
  • 多步骤数据分析:协调者规划分析路径,Worker 执行各步

与 Sub-Agent 同步模式的关系

协调者-工作者模式可以视为同步 Sub-Agent 的批量版

Sub-Agent 同步模式:父 → 1Sub-Agent → 等待结果
Orchestrator-Worker:协调者 → N 个 Worker → 等待所有结果 → 综合

4.5 评估者-优化者模式(Evaluator-Optimizer)

核心思想

一个 LLM 生成内容,另一个 LLM 评估并反馈,循环迭代直到满足质量标准。

架构图

                    ┌──────────────────────────────┐
                    │                              │
Task → [Generator] → Output → [Evaluator] → PASS? ─→ Final Output
         ↑                         │
         └── feedback ─────────────┘
                                 FAIL

代码示例

def iterative_refinement(task: str, max_iterations: int = 5) -> str:
    """评估者-优化者循环"""
    # 初始生成
    result = llm_call(f"Generator prompt...\nTask: {task}")
    
    for i in range(max_iterations):
        # 评估
        eval_response = llm_call(f"""
        评估以下内容是否满足任务要求。
        如果满足,回复 PASS。
        如果不满足,提供具体的改进建议。
        
        任务: {task}
        内容: {result}
        
        <evaluation>PASS 或 FAIL</evaluation>
        <feedback>改进建议</feedback>
        """)
        
        evaluation = extract_xml(eval_response, "evaluation")
        if evaluation.strip() == "PASS":
            return result
        
        feedback = extract_xml(eval_response, "feedback")
        # 基于反馈重新生成
        result = llm_call(f"""
        根据反馈改进你的输出。
        原始任务: {task}
        上次输出: {result}
        反馈: {feedback}
        """)
    
    return result  # 达到最大迭代次数

适用场景

  • 文学翻译:翻译 → 审校 → 修改 → 再审
  • 代码生成:生成 → 测试 → 修复 → 再测试
  • 提示词优化:生成 → 评估效果 → 调整 → 再评估

注意事项

  • ⚠️ 必须设最大迭代次数:防止无限循环
  • ⚠️ 评估标准要明确:模糊的评估标准会导致永远无法 PASS
  • 💡 不同模型组合:可以用强模型评估、弱模型生成,优化成本

4.6 DAG 编排(有向无环图)

核心思想

将任务建模为有向无环图,节点是任务,边是依赖关系。系统自动解析依赖,最大化并行度。

架构图

        [A] ──→ [C] ──→ [E]
       ↗                  ↘
[Start]                    [End]
       ↘                  ↗
        [B] ──→ [D] ────

A 和 B 并行执行;C 依赖 A,D 依赖 B;E 依赖 C;最终汇聚。

适用场景

  • 复杂的数据处理流水线(ETL)
  • CI/CD 流水线中的 Agent 任务
  • 多模态处理(图片、文本、音频各走一路,最后汇聚)

实现方式

通常借助现有的工作流引擎:

  • Temporal:分布式持久执行引擎
  • Prefect / Airflow:Python 生态的工作流编排
  • Inngest:事件驱动的后台任务框架
  • LangGraph:LangChain 生态的图状态机
# LangGraph 风格的 DAG 定义(概念示例)
from langgraph.graph import StateGraph

workflow = StateGraph(AgentState)

# 添加节点
workflow.add_node("research", research_agent)
workflow.add_node("analyze", analyze_agent)
workflow.add_node("write", write_agent)
workflow.add_node("review", review_agent)

# 定义依赖边
workflow.add_edge("research", "analyze")
workflow.add_edge("analyze", "write")
workflow.add_edge("write", "review")

# 条件分支
workflow.add_conditional_edges("review", quality_check, {
    "pass": END,
    "fail": "write"  # 循环回写作节点
})

4.7 事件驱动模式(Event-Driven)

核心思想

Agent 的执行由事件触发,而非直接调用。事件可以来自用户操作、系统事件、外部 Webhook 等。

架构图

[Event Source][Event Bus][Event Handler/Agent]
                      ↓
              ┌───────┼───────┐
              ↓       ↓       ↓
         [Agent A] [Agent B] [Agent C]
         (订阅事件X) (订阅事件Y) (订阅事件X+Y)

适用场景

  • 代码合并后自动触发 Agent 做 Code Review
  • 监控告警触发 Agent 做根因分析
  • 用户注册后触发 Agent 做个性化引导
  • 票据创建后触发 Agent 做自动分类和分配

与定时模式的关系

定时模式是事件驱动的特例——触发事件是"时间到了"。


4.8 层级委托模式(Hierarchical Delegation)

核心思想

多层 Agent 形成树状层级结构,每层负责不同粒度的决策和执行。

架构图

              [总监 Agent]
             ↗     ↓      ↘
    [经理 A]    [经理 B]    [经理 C]
    ↙    ↘      ↙   ↘      ↙   ↘
[工人1] [工人2] [工人3] [工人4] [工人5] [工人6]

适用场景

  • 超大规模项目管理
  • 企业级自动化(部门→团队→个人层级)
  • 复杂的多步骤决策链

注意事项

  • ⚠️ Dan Farrelly 建议限制深度为 1:即使业务需要层级,也建议从扁平开始
  • ⚠️ 复杂度指数增长:每增加一层,调试和可观测性难度翻倍
  • ⚠️ 成本风险:深层级意味着大量的 LLM 调用

4.9 编排模式全景对比

模式复杂度灵活性可预测性最佳场景
提示链⭐⭐⭐⭐⭐⭐⭐固定步骤的线性流程
路由⭐⭐⭐⭐⭐⭐⭐⭐⭐输入多样、处理分支明确
并行化⭐⭐⭐⭐⭐⭐⭐⭐独立子任务并发加速
协调者-工作者⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐子任务需动态拆分
评估者-优化者⭐⭐⭐⭐⭐⭐⭐⭐需要迭代优化的输出
同步 Sub-Agent⭐⭐⭐⭐⭐⭐⭐⭐⭐需要结果才能继续
异步 Sub-Agent⭐⭐⭐⭐⭐⭐⭐⭐⭐独立长任务
定时 Sub-Agent⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐未来时间点的智能任务
DAG 编排⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐复杂依赖关系的工作流
事件驱动⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐响应式、解耦的系统
层级委托⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐超大规模、多层决策

五、工具设计原则

Dan Farrelly 在原文中强调了两个关键的工具设计原则,这对系统的可靠性至关重要。

5.1 独立工具优于参数切换

反模式 ❌:

{
  "name": "run_sub_agent",
  "parameters": {
    "task": "分析数据",
    "mode": "sync | async | scheduled"
  }
}

推荐做法 ✅:

原文中 Dan Farrelly 的设计是两个工具,而不是三个——定时模式是异步工具的扩展用法(通过添加 ts 时间戳参数实现),而非独立的第三个工具:

// 工具 1:同步委托(对应 Inngest 的 step.invoke())
{
  "name": "delegateTaskTool",
  "description": "启动一个子代理并等待结果。当你需要答案才能继续当前任务时使用。",
  "parameters": {
    "task": "任务描述",
    "tools": ["可用工具列表"]
  }
}

// 工具 2:异步委托(对应 Inngest 的 step.sendEvent())
// 定时模式 = 异步 + ts 时间戳参数
{
  "name": "delegateAsyncTaskTool",
  "description": "启动一个子代理在后台独立运行。当任务可以独立完成、不需要等待结果时使用。可选指定未来执行时间。",
  "parameters": {
    "task": "任务描述",
    "tools": ["可用工具列表"],
    "ts": "(可选) ISO 8601 时间戳,指定后变为定时模式"
  }
}

设计理念:定时模式本质上是"带时间戳的异步",不需要作为独立工具存在。这样减少了工具数量,同时保持了语义清晰。

原因

  • LLM 擅长工具选择(从多个工具中选一个),不擅长参数优化(在一个工具中选参数值)
  • 但对于"同步 vs 异步"这种核心行为差异,应该用独立工具区分
  • 而"异步 vs 定时"只是一个可选时间参数的区别,合并在一个工具中更合理
  • 独立工具带来更清晰的日志和更简单的调试
  • 每个工具的 description 可以精确描述使用场景

5.2 不要为模型做选择

给 LLM 提供所有可用工具及其清晰描述,让模型自己决定用哪个

❌ 你用 if-else 硬编码路由逻辑
✅ 你给模型三个工具,让它基于任务特征自行选择

5.3 统一的后端实现

三种模式在后端可以复用同一个核心函数,区别仅在于:

维度同步异步定时
触发方式同步调用异步派发调度器触发
结果路由返回给调用者发送给用户发送给用户
输出指令"简洁返回""详尽报告""详尽报告"

5.4 通道无关路由(Channel-Agnostic Routing)

这是原文中一个重要的实现架构细节,对多渠道 Agent 系统至关重要。

核心问题

当异步/定时 Sub-Agent 完成任务后,需要将结果发送给用户。但用户可能从 Telegram、Slack、Email、Web 等不同渠道发起请求。Sub-Agent 不应该关心消息是从哪个渠道来的。

解决方案:通道元数据

┌──────────────┐                     ┌──────────────┐
│   Telegram   │ ──→ ┌─────────┐    │  Sub-Agent   │
│   Slack      │ ──→ │ 父Agent │ ──→│  (不关心渠道) │
│   Email      │ ──→ └─────────┘    └──────┬───────┘
│   Web        │ ──→                        │
└──────────────┘                  结果 + 渠道元数据
                                            │
                                            ▼
                                   ┌───────────────┐
                                   │  通道路由器     │
                                   │  根据元数据     │
                                   │  发回对应渠道   │
                                   └───────────────┘

父 Agent 在委托任务时,将渠道信息作为结构化元数据传递给 Sub-Agent:

# 通道元数据结构
channel_meta = {
    "channel": "telegram",          # 渠道类型
    "destination": "chat_12345",    # 目标标识(聊天 ID / 频道 / 邮箱)
    "channelMeta": {                # 渠道特有的附加信息
        "message_thread_id": 789,
        "reply_to_message_id": 456
    }
}

设计原则

原则说明
Sub-Agent 不感知渠道Sub-Agent 只负责完成任务、生成结果,不关心结果去哪里
结构化的元数据传递渠道信息以 {channel, destination, channelMeta} 结构随任务传递
统一的结果路由层一个独立的通道路由器负责将结果发回正确的渠道
新增渠道零改动添加新渠道(如 Discord)只需在路由器中注册,不影响任何 Sub-Agent

价值:这个设计使得 Agent 系统的核心逻辑与消息渠道完全解耦。在多渠道客服、跨平台助手等场景中,是保持架构清洁的关键。

5.5 持久执行原语(Durable Execution Primitives)

原文的一个核心工程理念是持久执行(Durable Execution)——每次 LLM 调用都是一个可恢复的检查点。

Inngest 的原语映射

原文使用 Inngest 框架,其核心原语及其在三种模式中的映射关系如下:

Inngest 原语语义对应模式
step.invoke()函数到函数的 RPC,具有持久性。调用另一个函数并等待结果同步模式
step.sendEvent()发送事件,触发另一个函数运行,不等待结果异步模式
step.sendEvent() + ts发送带时间戳的事件,在指定时间触发定时模式
createFunction()定义一个可被触发的函数(Agent 的入口)所有模式的基础
step.run()持久化执行步骤,每次 LLM 调用都是一个检查点Agent 循环核心
step.sendEvent() (结果)Sub-Agent 完成后发送结果事件异步/定时结果报告

关键设计:LLM 调用作为检查点

// 原文使用 TypeScript/Inngest,这是其核心设计理念
const agentFunction = inngest.createFunction(
  { id: "my-agent" },
  { event: "agent/run" },
  async ({ event, step }) => {
    // 每次 step.run() 都是一个持久化检查点
    // 如果进程崩溃,恢复后会从最后一个成功的 step 继续
    let messages = [{ role: "user", content: event.data.task }];
    
    for (let i = 0; i < MAX_ITERATIONS; i++) {
      // 这个 LLM 调用是持久化的——崩溃后可从此处恢复
      const response = await step.run(`llm-call-${i}`, async () => {
        return await llm.chat(messages);
      });
      
      // 工具调用也是持久化的
      if (response.toolCalls) {
        const toolResults = await step.run(`tools-${i}`, async () => {
          return await executeTools(response.toolCalls);
        });
        messages.push(toolResults);
      }
    }
  }
);

为什么持久执行很重要

问题无持久执行有持久执行
进程崩溃Agent 从头重新运行,浪费已完成的 LLM 调用从最后一个检查点恢复
长时间运行进程超时被杀 → 任务丢失每个步骤持久化,可跨进程恢复
成本控制崩溃重跑 = 双倍费用只重跑未完成的部分
调试追踪只有最终结果,过程不可见每个检查点都有记录

子会话隔离(Sub-Session Key)

原文还提到了 subSessionKey 的设计——每个 Sub-Agent 有独立的会话标识,确保:

  • 子代理的对话历史不会混入父代理
  • 多个并行 Sub-Agent 之间完全隔离
  • 便于独立追踪和调试每个 Sub-Agent 的执行过程

:本文其他章节的代码示例使用 Python 伪代码以面向更广泛的读者,但原文使用的是 TypeScript + Inngest 框架。上述 Inngest 原语和持久执行机制是原文的核心工程基石,任何实际构建系统时都建议参考这些持久化设计理念,不论使用什么语言和框架。


六、通用 Agent vs. 专业化 Agent

这是一个架构师必须做出的关键决策。Dan Farrelly 给出了明确的建议。

6.1 强烈建议:从通用 Agent 开始

不要过早构建专业化 Agent(如邮件 Agent、数据 Agent、日程 Agent)。

这一观点也得到了业界顶尖团队的验证。Cursor 团队(当前最成功的 AI 编码工具之一)在实践中使用的是"大多是通用的任务接口"(mostly-generic task interface)。他们的经验表明:Sub-Agent 首先是上下文压缩边界(context-compression boundary),其次才是并行性(parallelism)工具。这意味着拆分 Sub-Agent 的首要动机应该是管理上下文复杂性,而不是追求领域专业化。

6.2 反对过早专业化的四个理由

理由 1:路由悖论

你需要一个"超级 Agent"来决定交给哪个"专家 Agent"

如果这个超级 Agent 足够聪明能做出正确路由……
那它为什么不能直接完成任务?

如果它不够聪明……
那路由错误造成的问题比直接处理更严重。

理由 2:工具重叠

Email Agent  → 需要搜索工具 + 日历查询
Calendar Agent → 需要搜索工具 + 联系人查询
Contact Agent → 需要搜索工具 + 邮件查询

→ 大量工具重叠 → 维护成本 × N
→ 通用 Agent 用一套工具就能覆盖

理由 3:错误 Agent 问题

路由错误时,"专家 Agent"会在不完整的能力下尝试任务,产生微妙的、难以检测的错误——比直接失败更危险。

理由 4:评估复杂度爆炸

N 个专业 Agent 需要:
- N 套独立评估
- 1 套路由评估
- O(N²) 的交互测试
= 维护噩梦

6.3 何时应该专业化

只有在以下场景,专业化才有价值:

场景原因示例
不同模型要求不同任务需要不同模型能力视觉识别用多模态模型,快速分类用小模型
安全边界数据隔离是硬性要求客户数据 Agent 和内部数据 Agent 必须隔离
监管要求需要独立的审计管道金融合规 Agent 需要完全独立的日志链路
评估证据实测证明专业化确实更好A/B 测试显示专业 Agent 准确率高 15%

6.4 一句话总结

先用一个通用 Agent + Sub-Agent 模式跑通全流程,有数据证明瓶颈后再考虑专业化。


七、生产环境落地指南(实战篇)

7.1 架构分层设计

生产级 Agent 系统应该遵循分层解耦的架构:

┌────────────────────────────────────────────────┐
│                 用户交互层                       │
│     (多渠道接入、NLU、输入归一化)                 │
├────────────────────────────────────────────────┤
│                Agent 核心层                      │
│  (意图分类、上下文管理、Sub-Agent 调度)           │
├────────────────────────────────────────────────┤
│               知识检索层                         │
│  (向量数据库、混合检索、重排序)                   │
├────────────────────────────────────────────────┤
│              决策推理层                          │
│  (LLM 推理、任务规划、自我优化)                  │
├────────────────────────────────────────────────┤
│              工具执行层                          │
│  (API 编排、外部服务、自主执行)                   │
├────────────────────────────────────────────────┤
│              安全合规层(贯穿全链路)              │
│  (认证鉴权、内容审核、审计日志、异常检测)          │
└────────────────────────────────────────────────┘

核心原则:各层职责单一,通过标准接口交互。更换 LLM 不应影响工具层;更换向量数据库不应影响核心层。

7.2 上下文管理策略

上下文管理是 Agent 系统质量的生命线。

分层记忆架构

短期记忆(会话级)
├── 当前对话历史(滑动窗口 + 摘要压缩)
├── 中间计算状态
└── Sub-Agent 返回的摘要

长期记忆(用户级)
├── 用户偏好和历史
├── 跨会话的关键信息
└── 学习到的用户习惯

知识库(系统级)
├── 向量数据库(语义检索)
├── 结构化知识图谱
└── 文档和 FAQ

Token 预算管理

class ContextManager:
    MAX_CONTEXT_TOKENS = 8000  # 给模型留足够的生成空间
    
    def manage(self, messages: list, tools_schema: str) -> list:
        """确保上下文不超预算"""
        # 1. 工具 schema 是固定开销
        fixed_cost = count_tokens(tools_schema) + count_tokens(system_prompt)
        
        # 2. 计算可用预算
        available = self.MAX_CONTEXT_TOKENS - fixed_cost
        
        # 3. 按优先级分配
        #    - 最新 3 轮对话:必须保留
        #    - 更早的对话:压缩为摘要
        #    - Sub-Agent 结果:已经是摘要形式
        return self.compress_to_budget(messages, available)

7.3 错误处理与容错机制

分层错误处理策略

Level 0:工具级
├── 单次工具调用失败 → 重试(指数退避)
├── 重试 3 次仍失败 → 返回错误描述给 Agent,让 Agent 决定替代方案

Level 1Sub-Agent 级
├── Sub-Agent 超时 → 父 Agent 收到超时通知,触发降级策略
├── Sub-Agent 输出质量低 → 父 Agent 评估后决定重试或换方案

Level 2:任务级
├── 整个任务链路失败 → 保存进度,通知用户,等待人工介入
├── 部分子任务失败 → 返回已完成部分 + 失败说明

Level 3:系统级
├── LLM 服务不可用 → 切换备用模型或排队等待
├── 成本超限 → 立即终止,通知管理员

熔断机制

class CircuitBreaker:
    """Agent 熔断器:防止 Agent 陷入无限循环"""
    
    def __init__(self, max_steps=30, max_cost_usd=1.0, max_time_sec=300):
        self.max_steps = max_steps
        self.max_cost = max_cost_usd
        self.max_time = max_time_sec
    
    def check(self, current_state: AgentState) -> bool:
        """每次工具调用前检查"""
        if current_state.step_count >= self.max_steps:
            raise CircuitBreakerError("达到最大步数限制")
        
        if current_state.total_cost >= self.max_cost:
            raise CircuitBreakerError("达到成本上限")
        
        if current_state.elapsed_time >= self.max_time:
            raise CircuitBreakerError("达到时间上限")
        
        # 检测重复行为(同一个工具调用相同参数 ≥ 3 次)
        if self.detect_loop(current_state):
            raise CircuitBreakerError("检测到循环行为")
        
        return True

7.4 可观测性体系

生产环境的 Agent 系统必须具备完整的可观测性,否则就是在裸奔。

三大支柱

支柱内容工具选型
日志(Logs)每次 LLM 调用的输入/输出/耗时/Token 数ELK、Loki
指标(Metrics)成功率、延迟 P99、Token 消耗、成本Prometheus、Grafana
追踪(Traces)端到端链路追踪,串联父 Agent → Sub-Agent → 工具调用LangSmith、Jaeger

关键监控指标

# Agent 系统核心监控指标
metrics:
  # 质量指标
  - name: task_success_rate
    description: 任务完成成功率
    alert_threshold: < 85%
  
  - name: tool_call_accuracy
    description: 工具调用参数正确率
    alert_threshold: < 90%
  
  # 性能指标
  - name: e2e_latency_p99
    description: 端到端延迟 P99
    alert_threshold: > 30s
  
  - name: sub_agent_latency_p95
    description: Sub-Agent 执行延迟 P95
    alert_threshold: > 60s
  
  # 成本指标
  - name: cost_per_task
    description: 单任务平均成本(USD)
    alert_threshold: > 0.50
  
  - name: daily_total_cost
    description: 日总成本(USD)
    alert_threshold: > 100
  
  # 安全指标
  - name: circuit_breaker_triggers
    description: 熔断器触发次数
    alert_threshold: > 5/hour
  
  - name: loop_detection_count
    description: 循环检测触发次数
    alert_threshold: > 3/hour

7.5 安全与合规

核心原则:安全前置,而非后补

"先把功能做完,安全以后再加""安全是第一天就要设计进去的"

安全清单

维度要求实现方式
认证鉴权每个请求必须经过身份验证OAuth 2.0 / API Key + RBAC
权限最小化Agent 只能访问完成任务所需的最小资源集细粒度的工具权限配置
输入过滤防御 Prompt Injection 攻击输入内容审核 + 指令隔离
输出审核防止泄露敏感信息输出过滤器 + PII 检测
审计日志全链路不可篡改的操作记录结构化日志 + 只追加存储
高风险审批关键操作需人工确认Human-in-the-loop 设计

Prompt Injection 防御

def sanitize_input(user_input: str) -> str:
    """基本的 Prompt Injection 防御"""
    # 1. 检测已知的注入模式
    injection_patterns = [
        r"ignore (?:previous|above|all) instructions",
        r"you are now",
        r"new system prompt",
        r"forget (?:everything|your instructions)",
    ]
    for pattern in injection_patterns:
        if re.search(pattern, user_input, re.IGNORECASE):
            raise SecurityError("Potential prompt injection detected")
    
    # 2. 使用分隔符隔离用户输入
    # 在 System Prompt 中明确标记用户输入的边界
    return f"<user_input>{user_input}</user_input>"

7.6 成本控制

成本模型

单次任务成本 = Σ(每次 LLM 调用的 input_tokens × 输入价格 + output_tokens × 输出价格)
            + 工具调用成本(API 费用等)
            + 基础设施成本(计算、存储、网络)

优化策略

策略预期节省说明
Sub-Agent 上下文压缩60-90%核心策略,减少父 Agent 的 token 消耗
模型分级30-50%简单任务用小模型,复杂任务用强模型
缓存20-40%相同输入的 LLM 调用结果缓存
默认异步10-30%异步 Sub-Agent 不占父 Agent 上下文预算
提前终止变动大检测到答案后立即停止,不执行剩余步骤
class CostAwareAgent:
    """成本感知的 Agent"""
    
    def select_model(self, task_complexity: str) -> str:
        """根据任务复杂度选择模型"""
        model_map = {
            "simple": "claude-3-haiku",      # $0.25/$1.25 per MTok
            "medium": "claude-3-5-sonnet",   # $3/$15 per MTok
            "complex": "claude-3-opus",      # $15/$75 per MTok
        }
        return model_map.get(task_complexity, "claude-3-5-sonnet")
    
    def estimate_cost(self, task: str) -> float:
        """执行前预估成本"""
        estimated_turns = self.estimate_turns(task)
        estimated_tokens = estimated_turns * 2000  # 平均每轮 2K tokens
        return estimated_tokens * self.price_per_token

八、常见陷阱与反模式

陷阱 1:过度工程化

❌ 项目第一天就设计 5 层 Agent 架构 + 3 种专业 Agent + 完整可观测性

✅ 从单个 Agent + 工具开始
  → 遇到上下文瓶颈 → 引入 Sub-Agent
  → 遇到延迟问题 → 引入异步模式
  → 遇到定期需求 → 引入定时模式
  → 遇到质量问题 → 引入评估者-优化者

陷阱 2:递归 Sub-Agent

Sub-Agent 可以再生成 Sub-Agent(无限套娃)
  → 成本指数增长
  → 调试不可能
  → 容易死循环

✅ 严格限制深度 1Sub-Agent 只能调用工具,不能生成新 Agent

陷阱 3:万物皆同步

❌ 所有 Sub-Agent 都用同步模式
  → 父 Agent 串行等待每个子任务
  → 总延迟 = 所有子任务延迟之和
  → 上下文不断膨胀

✅ 默认异步,只在"必须等结果才能继续"时用同步

陷阱 4:忽视评估

"Agent 跑起来了就行"
  → 不知道成功率是多少
  → 不知道哪些场景会失败
  → 不知道质量趋势

✅ 构建系统化的评估体系
  → 定义成功标准
  → 收集测试用例集
  → 定期回归测试
  → 监控质量趋势

陷阱 5:上下文污染

❌ 所有信息不加区分地塞入上下文
  → 干扰模型注意力
  → 前面的关键指令被稀释
  → 幻觉率上升

✅ 精心管理上下文
  → Sub-Agent 返回摘要而非全文
  → 滑动窗口管理对话历史
  → 按相关性过滤检索结果

陷阱 6:没有熔断机制

❌ Agent 自由运行,没有任何限制
  → 可能无限循环调用工具
  → 可能产生天价 API 账单
  → 可能执行不可逆的危险操作

✅ 多维度熔断
  → 最大步数限制
  → 最大成本限制
  → 最大时间限制
  → 循环检测
  → 高风险操作人工确认

陷阱 7:为了架构美学而专业化

❌ "微服务架构好,所以我也要把 Agent 拆成专业化微服务"
  → Email Agent、Calendar Agent、Search Agent...
  → 需要路由器决定找谁
  → 路由错误产生微妙 bug
  → 评估成本 O(N²)

✅ Dan Farrelly 的建议
  → 从通用 Agent 开始
  → 用 Sub-Agent 做上下文隔离
  → 只在有数据证明的情况下才专业化

九、选型决策树

面对一个具体的 Agent 系统需求,按以下路径做技术选型:

1. 任务是否有固定的步骤流程?
   ├── 是 → 步骤之间是否有依赖?
   │       ├── 全部有依赖 → 提示链
   │       ├── 部分有依赖 → DAG 编排
   │       └── 无依赖 → 并行化
   └── 否 → 继续 ↓

2. 输入是否需要先分类再处理?
   ├── 是 → 路由
   └── 否 → 继续 ↓

3. 是否需要迭代优化输出质量?
   ├── 是 → 评估者-优化者
   └── 否 → 继续 ↓

4. 是否需要拆分为子任务?
   ├── 是 → 子任务是否预先确定?
   │       ├── 是 → 并行化
   │       └── 否 → 协调者-工作者
   └── 否 → 继续 ↓

5. 子任务的结果是否需要反馈到父流程?
   ├── 是 → 同步 Sub-Agent
   └── 否 → 是否需要延迟执行?
           ├── 是 → 定时 Sub-Agent
           └── 否 → 异步 Sub-Agent

6. 系统是否需要响应外部事件?
   ├── 是 → 事件驱动模式
   └── 否 → 以上模式按需组合

💡 不确定?从最简单的模式开始,遇到瓶颈再演进。

十、总结与行动建议

核心认知

  1. AI Agent 系统的本质是管理复杂性——编排模式是核心工具
  2. 上下文压缩比大上下文窗口更可持续——Sub-Agent 模式能减少 90%+ 的上下文 token
  3. 简单性是美德——从通用 Agent 开始,用数据驱动架构演进

三步行动建议

Step 1:MVP(1-2 周)

单个 Agent + 基础工具
├── 不用 Sub-Agent,先验证核心业务逻辑
├── 实现基本的错误处理和日志
└── 收集基线数据(成功率、延迟、成本)

Step 2:引入编排(2-4 周)

根据 MVP 阶段暴露的问题引入合适的模式
├── 上下文爆炸 → 引入 Sub-Agent(优先异步)
├── 长任务延迟 → 引入异步 Sub-Agent
├── 需要定期执行 → 引入定时 Sub-Agent
├── 质量不达标 → 引入评估者-优化者
└── 构建可观测性体系

Step 3:生产加固(4-8 周)

面向生产环境的工程化加固
├── 完善熔断机制(步数/成本/时间/循环检测)
├── 完善安全体系(认证/权限/审计/注入防护)
├── 建立评估体系(测试集/回归测试/质量监控)
├── 优化成本(模型分级/缓存/上下文压缩)
└── 只在有数据支撑时才考虑专业化 Agent

最后一句话

不要为了技术美感而架构,为了解决实际问题而架构。

最好的 Agent 系统不是最复杂的,而是恰好满足需求的最简单系统


十一、未来探索方向

Dan Farrelly 在原文末尾提出了三个值得探索的前沿方向,这些方向代表了 Agent 编排系统的演进趋势。

11.1 自我迭代代理(Self-Iterating Agents)

利用定时模式,Agent 可以安排自己在未来某个时间重新检查和迭代自己的工作。

场景:Agent 撰写了一份分析报告
  → 完成后,安排自己 24 小时后回来
  → 24 小时后,基于新数据重新审视报告
  → 如果发现需要更新 → 自动修订
  → 如果无需更新 → 结束

这使得 Agent 从"一次性执行"进化为"持续关注"的模式——Agent 可以给自己排任务

11.2 编排感知:从循环到网状(Orchestration-Aware Patterns)

目前的主流编排模式是循环 + 扇出(loop + fan-out):一个协调者循环决策,必要时扇出多个子代理。

未来的方向是网状结构(mesh):Agent 之间可以直接通信和协调,而非必须通过中心协调者。这需要更复杂的消息传递和状态同步机制,但能解锁更灵活的协作模式。

当前模式:星型拓扑                未来方向:网状拓扑
         [协调者]                    [Agent A] ←→ [Agent B]
        ↙   ↓   ↘                       ↕    ✕      ↕
   [A]    [B]    [C]              [Agent C] ←→ [Agent D]

11.3 回调与通用子代理系统(Callbacks and Generic Sub-Agent Systems)

建立一个通用的 Sub-Agent 回调系统——当子代理完成工作后,不仅可以通知用户,还可以触发父代理或其他系统组件的回调。这为构建更复杂的多代理工作流奠定基础。

核心趋势:Agent 系统正在从"工具式"(完成一个任务就结束)向"生态式"(Agent 之间持续协作、自我进化)演进。


参考资料

  1. Dan Farrelly (Inngest):《Three sub-agent patterns you need for your agentic system》— 本文的核心参考,提出同步/异步/定时三模式框架、两工具设计、通道无关路由、持久执行原语等关键概念
  2. Anthropic:《Building effective agents》(官方 Agent 构建指南,2024.12)
  3. Anthropic:Agent 架构模式详解(提示链、路由、并行化、协调者-工作者、评估者-优化者)
  4. Cursor 团队:关于"大多是通用的任务接口"和"Sub-Agent 首先是上下文压缩边界"的实践分享(在 Dan Farrelly 原文中引用)
  5. Inngest:事件驱动的持久执行后台任务框架,提供 step.invoke()step.sendEvent()step.run() 等持久化原语
  6. LangChain / LangGraph:Agent 编排框架实现参考
  7. 2026 年企业级 AI Agent 终极架构蓝图:六大核心模块 + 生产环境部署指南