大多数人构建 Agent 的方式是一个 while 循环不断调用 Claude,prompt 越涨越大直到 context 窗口打满开始幻觉。90% 的人从不把工作切分给专门的子 agent——不做路由、不分支、不并行。他们跑一个循环,祈祷它能工作,然后花几周 debug 它不行的情况。

Loop 到 Graph 的转变,就像独立开发者加入团队——一个人单干在项目简单时很快,但一旦变复杂,就需要角色、交接和审查。

"A loop is one agent getting smarter. A graph is many agents getting coordinated."

四大构建块

无论多复杂的 Graph 都由 4 个原语组成。你不需要框架——只需要函数、字典、if 语句。

# 20 行的完整 Graph 抽象
def node(func):
    """A node is just a function that takes state and returns state."""
    def wrapper(state):
        return func(state)
    return wrapper

def edge(state, next_node):
    """An edge passes state to the next node."""
    return next_node(state)

def router(state, condition, if_true, if_false):
    """A router picks a path based on state."""
    if condition(state):
        return if_true(state)
    return if_false(state)

四大时代

时代 核心技能 说明
Era 1 — Prompt Engineering 写好指令 大多数人停留在这一层
Era 2 — Context Engineering 喂对数据 开始关注上下文质量
Era 3 — Loop Engineering 构建自主 Agent 重试、验证、改进的单循环
Era 4 — Graph Engineering 协调多个 Agent 本文目标

真正在发货的人已经进入 Era 3 或 4。他们不是在写更好的 prompt,而是在设计更好的 flow。

五大 Graph 模式

1. Sequential Chain — 顺序链

Node A 运行,传给 Node B,再传给 Node C。最简单也最危险的模式——错误会三级放大传播

def run_sequential(task):
    state = {"task": task}
    state = research_node(state)
    state = analyze_node(state)
    state = write_node(state)
    state = verify_node(state)       # 末尾验证节点不可少!
    return state

即使最简单的顺序链,末尾也必须有 verification node。如果 A 产出糟糕,B 在此基础上构建,C 再叠加——错误已经累积了三层。

2. Router — 路由器

Router 检查输入选择路径。路由是分类任务,不是推理任务。用 Haiku 做路由,用 Sonnet 做实际工作。

def router(state):
    category = call_claude(
        model="claude-haiku-4-5",  # 便宜又快
        system="Classify this task. One word: code, research, or writing.",
        prompt=state["task"]
    )
    routes = {
        "code": code_agent,       # 自己的 prompt + tools
        "research": research_agent,
        "writing": writing_agent,
    }
    return routes.get(category.strip())(state)

每个 specialist 应该有自己的 system prompt 和 tool set。给所有 agent 所有工具 = 错误工具调用 + 浪费 token。

如果路由做错,修复方法是更好的 prompt 而不是更大的模型。在 Router prompt 里写 5-6 个真实 Few-shot 示例,远超零样本 Sonnet。

3. Parallel Fan-Out — 并行扇出

多个节点同时处理同一输入,Collector 等待全部合并。总时间 = 最慢节点,不是总和。

import asyncio

async def fan_out(task):
    results = await asyncio.gather(
        research_competitor(task, "Acme"),
        research_competitor(task, "Globex"),
        research_competitor(task, "Initech"),
    )
    # Merge 节点有它自己的 prompt 和质量标准
    merged = call_claude(
        system="Synthesize these 3 competitor reports.",
        prompt=json.dumps(results)
    )
    return merged

Merge 节点最容易被轻视——合并 3 个 JSON blob 容易,合并 3 份研究报告需要自己的 prompt 和质量标准。把 merge 节点当作真正的 agent,而不是字符串拼接。

4. Loop with Gate — 循环 + 审查门

Builder 做工作 → 独立 Reviewer 检查 → 不通过则重试。自纠正 agent 系统的基石。

def loop_with_gate(task, max_tries=5):
    state = {"task": task, "history": []}
    for i in range(max_tries):
        result = builder_agent(state)      # Sonnet, creative
        check = reviewer_agent(result)     # Sonnet, adversarial
        if check["passed"]:
            return result
        state["history"].append({"attempt": i+1, "issues": check["issues"]})
    return {"status": "max_retries", "last_result": result}

关键规则:Builder 和 Reviewer 必须是不同 Agent。同一个 agent 审查自己会批准自己的错误——产生缺陷的推理也会评估它。

Reviewer 的 prompt 应该是对抗式的——"找到每一个缺陷、不一致、遗漏的边界情况"。严格的 Reviewer 抓到真正的 bug,礼貌的 Reviewer 放行一切。

5. Human-in-the-Loop — 人在回路

Graph 在特定节点暂停,等待人工批准。对昂贵、不可逆、高风险操作必须使用。

def human_gate(state):
    print(f"Action: {state['action']}")
    print(f"Scope:  {state['scope']}")
    print(f"Cost:   {state['est_cost']}")
    approval = input("Approve? [y/n]: ")
    if approval == "y":
        state["approved"] = True
    else:
        state["approved"] = False
        state["human_feedback"] = input("Reason: ")
    return state

审批节点必须展示具体信息——"发 2400 封邮件,预估 $12,审批?"要具体到人能在 5 秒 内做出真实决策。

状态流与模型分层

# 按工作匹配模型
TIERS = {
    "router":   "claude-haiku-4-5",  # 快速、便宜、分类
    "builder":  "claude-sonnet-4-6", # 推理、工具
    "reviewer": "claude-sonnet-4-6", # 严格、对抗式
    "final_qa": "claude-opus-4-6",  # 最高标准、罕见
}

# 每个节点的 State 契约
# research_node:  reads ["task"]         writes ["research"]
# analysis_node:  reads ["research"]     writes ["analysis"]
# writer_node:    reads ["analysis"]     writes ["draft"]
# reviewer_node:  reads ["draft"]        writes ["review"]

State 是扁平字典,每个节点声明它读/写哪些 key。Graph 出问题时,先检查 state——无法追踪谁写了哪个 key,就无法 debug。

用 Sonnet 做路由就像雇高级工程师去分拣邮件——可行但浪费预算。

错误处理与 Fallback 路径

def safe_node(func, state, fallback_key="error"):
    try:
        return func(state)
    except Exception as e:
        state[fallback_key] = str(e)
        state["needs_human"] = True
        return state

state = safe_node(research_node, state, "research_error")
if state.get("needs_human"):
    notify_human(state)
else:
    state = analyze_node(state)

Fallback 不是"忽略错误",而是 Graph 中的另一条路径。用户得到的是有用的信息,而不是堆栈跟踪。

完整示例:客服工单系统

import anthropic, json
client = anthropic.Anthropic()

def classify(state):
    r = client.messages.create(
        model="claude-haiku-4-5", max_tokens=50,
        system="Classify: billing, technical, general. One word.")
    state["category"] = r.content[0].text.strip().lower()
    return state

def draft(state):
    prompts = {
        "billing": "Handle billing. Precise on refund policy.",
        "technical": "Handle tech. Ask for logs first.",
        "general": "Handle general inquiries. Brief.",
    }
    r = client.messages.create(
        model="claude-sonnet-4-6", max_tokens=1024,
        system=prompts.get(state["category"]))
    state["draft"] = r.content[0].text
    return state

def review(state):
    r = client.messages.create(
        model="claude-sonnet-4-6", max_tokens=200,
        system='Find flaws. JSON: {"passed": bool, "issues": [str]}')
    state["review"] = json.loads(r.content[0].text)
    return state

def run(ticket, max_retries=3):
    state = {"ticket": ticket, "attempts": 0}
    state = classify(state)          # Haiku router
    for _ in range(max_retries):
        state = draft(state)         # Sonnet specialist
        state = review(state)        # Sonnet reviewer
        state["attempts"] += 1
        if state["review"]["passed"]:
            send_response(state["draft"])
            return state
    state["needs_human"] = True      # Fallback
    return state

模式组合:Classify (Haiku) → Route → Draft (Sonnet) → Review (Sonnet) → Ship or retry。Fallback 到人工。不到 60 行。无框架。

6 个可立即构建的 Graph

用例 模式组合 说明
Ticket Triage Router + Specialist + Loop 按分类/紧急度分派,各自走 specialist,通过审查才发送
Competitive Analysis Parallel Fan-Out + Merge 每竞对一个子 agent,并行研究,merge 合成报告
PR Review Pipeline Sequential + Reviewer 读 diff → 跑测试 → 写审查;第二 agent 再审查审查意见
Blog Post Pipeline Sequential + Loop-with-gate 研究 → 写稿 → 编辑审查,循环直到通过
ETL with Validation Sequential + Validator PDF 提取 → 转换 → 加载;验证 agent 抽检行
Incident Response Research → Gate → Execute 告警 → 读日志 → 定位根因 → 草拟修复 → 人工审批部署

5 个常见错误

巨量单块节点:一个节点做所有事。失败了全盘皆炸。拆成单一职责的小节点。

节点间无 State:每个节点从零开始,无共享字典。Graph 忘了前一个节点学过什么。

无 Fallback 路径:Happy path 工作,任何错误让整个 graph 崩溃。每个可能失败的节点建一条 fallback。

Sonnet 做路由:路由是分类,Haiku 更快更便宜。把 Sonnet 用在真正需要的地方。

跳过审查门:第一个错误答案发送给客户后,没人再信任这个系统。

Grok Build 实践对照

文章概念 Grok Build 实践 位置
Node Subagent 系统 — 3 个内置 type 16-subagents.md
Edge resume_from + background subagent 参数
Router Agent Types + 模型切换 [subagents.models]
State Opendray Memory — 16 个工具 MCP server
Sequential resume_from 链式调用 16-subagents.md
Router Pattern deepseek-flash → deepseek-pro → qwen3.5-reviewer config.toml
Parallel Fan-Out 背景 subagent 并发 20-background-tasks.md
Loop with Gate Goal Orchestrator — 6 模块 ~15K 行 benchmarks 分析
Human-in-Loop Permission modes — Yolo/Auto/Manual 15-agent-mode.md
Model Tiering 7 个模型分层配置 config.toml
Fallback Paths capability_mode + worktree 16-subagents.md
Reviewer/Verifier N skepticism 并行验证 benchmarks

✅ Sequential Chain · ✅ Router Pattern · ✅ Parallel Fan-Out · ✅ Loop with Gate · ✅ Human-in-Loop

建议采纳的最佳实践


"Two kinds of builders in 2026. Ones still running one loop for everything. Ones designing the flow. The model is the same. The architecture is not."