从 Loop Engineering 到 Graph Engineering:一文讲透 AI Agent 的下一代工程范式
从 Loop Engineering 到 Graph Engineering:一文讲透 AI Agent 的下一代工程范式
本文是对视频《什么是图工程|Graph Engineering|循环工程|Loop Engineering|多智能体|LangGraph|ReAct|工作流编排|验证器》的系统化学习笔记。
本文不会停留在概念解释,而是从单智能体循环、多智能体协作、状态管理、条件路由、并行执行、验证器和失败恢复等角度,说明 Graph Engineering 到底解决了什么问题,并给出一个可以直接运行的 LangGraph 示例。
文章目录
一、从 Prompt Engineering 到 Graph Engineering
过去使用大模型时,我们最关心的是:
怎样写出一个更好的提示词?
随后,问题逐渐变成:
怎样给模型提供正确的上下文、工具、记忆和运行环境?
再往后,当 AI Agent 开始执行长时间、多步骤任务时,工程重点又发生了变化:
怎样让智能体持续执行,直到任务真正完成?
这就是 Loop Engineering,循环工程。
但当任务越来越复杂,一个智能体即使能够不断循环,也会遇到上下文膨胀、职责混乱、验证不独立、无法有效并行和故障难以恢复等问题。
于是,工程问题进一步升级为:
怎样把多个智能体、工具、确定性程序、验证器以及人工审批节点,组织成一个可观测、可控制、可恢复的系统?
这就是 Graph Engineering,图工程。
可以用一句话概括:
Loop Engineering:
让一个 Agent 持续完成任务。
Graph Engineering:
让多个 Agent、工具和人按照明确的组织关系协同完成任务。
这里的 Graph 并不是知识图谱,也不特指图数据库。
它表示的是一种工作流拓扑:
- 节点 Node:执行任务的单元;
- 边 Edge:任务之间的流转关系;
- 状态 State:节点之间共享的数据;
- 路由 Router:根据运行结果选择下一条路径;
- 检查点 Checkpoint:保存执行进度;
- 验证器 Verifier:判断结果是否合格;
- 终止条件:决定任务何时结束。
1.1 AI 工程的五个层次
为了理解 Graph Engineering,可以把 AI Agent 工程划分为五个层次。
| 工程层次 | 核心问题 | 主要对象 |
|---|---|---|
| Prompt Engineering | 这句话应该怎么说? | 单次提示词 |
| Context Engineering | 这一步应该让模型看到什么? | 上下文、记忆、检索结果 |
| Harness Engineering | 模型周围应该提供哪些能力和约束? | 工具、沙箱、状态、权限 |
| Loop Engineering | 智能体怎样持续执行直到完成? | 单智能体循环 |
| Graph Engineering | 多个执行单元怎样分工和协作? | 多智能体工作流 |
这五层不是互相替代的关系,而是逐层叠加的关系。
Graph Engineering 并不意味着 Prompt Engineering 和 Loop Engineering 已经过时。
恰恰相反,一个图中的每个智能体节点,内部通常仍然需要:
- 合理的提示词;
- 精确的上下文;
- 可控的工具;
- 明确的停止条件;
- 稳定的执行循环。
因此可以认为:
一个可靠的 Graph
=
多个可靠的 Loop
+
明确的节点职责
+
可控的状态流转
+
独立的验证机制
+
失败恢复与人工治理
如果节点内部的 Loop 不可靠,那么把它们连接成 Graph,只会把局部错误放大成系统级错误。
二、Loop Engineering:让单个 Agent 持续完成任务
2.1 从人工循环到智能体循环
传统的大模型交互通常是:
用户提出要求
↓
模型生成结果
↓
用户检查
↓
用户指出错误
↓
模型重新修改
表面上是 AI 在工作,但真正控制循环的是人。
用户实际上承担了以下职责:
- 判断结果是否正确;
- 决定下一步做什么;
- 要求模型调用工具;
- 发现错误;
- 重新发送提示词;
- 判断任务是否结束。
换句话说:
用户自己就是那个
while循环。
Loop Engineering 要做的,就是把这个循环交给智能体系统。
观察环境
↓
分析当前状态
↓
决定下一步行动
↓
调用工具执行
↓
检查执行结果
↓
达到目标了吗?
↙ ↘
否 是
继续循环 结束
2.2 ReAct 是典型的单智能体循环
ReAct 是 Reasoning and Acting 的缩写。
它把模型的推理与外部行动交替组织起来:
Thought:分析当前情况
Action:决定调用什么工具
Observation:读取工具返回结果
Thought:根据新结果继续分析
Action:执行下一步操作
……
Final Answer:输出最终结果
ReAct 的关键价值不是“让模型多想一会儿”,而是让模型能够在推理过程中与外部环境交互。
例如,一个文献检索 Agent 可以执行:
思考:需要先搜索论文标题
行动:调用 Google Scholar 搜索工具
观察:获得候选论文列表
思考:需要核对作者和发表来源
行动:打开候选论文详情
观察:获得作者、年份和期刊信息
思考:标题和作者一致,可以获取 BibTeX
行动:点击引用并导出 BibTeX
观察:获得引用信息
思考:任务已经完成
最终结果:输出经过核验的 BibTeX
ReAct 原论文将推理轨迹和任务行动交替生成,使模型可以根据环境反馈更新计划,而不是一次性猜测完整答案。
2.3 一个可靠的 Loop 必须具备什么?
一个生产级 Loop 至少需要以下组成部分。
1. 明确目标
错误目标:
尽可能把程序写好。
更合理的目标:
完成登录接口,并确保全部单元测试通过。
目标必须能够被检查。
2. 可调用工具
例如:
- 浏览器;
- 搜索引擎;
- 文件系统;
- Python;
- 数据库;
- 编译器;
- 测试框架;
- Git;
- API。
没有工具的 Agent,很多时候只是一个能够输出文本的模型。
3. 环境反馈
Agent 必须看到行动后的真实结果,例如:
HTTP 状态码
浏览器页面变化
测试输出
编译错误
文件差异
数据库查询结果
4. 验证器
不能只让执行者自己说“我完成了”。
系统应该通过外部条件判断:
tests_passed is True
而不是相信模型输出:
我认为所有功能应该已经可以正常运行。
5. 停止条件
例如:
测试全部通过;
找到严格匹配的论文;
连续两轮没有发现新结果;
达到最大重试次数;
等待人工审批;
任务被取消。
没有明确停止条件,Loop 很容易出现无限循环。
2.4 为什么单个 Loop 不够用?
对于简单任务,一个 Agent 加一个明确停止条件通常已经足够。
例如:
每天检查一次仓库 CI
↓
如果失败则读取日志
↓
生成错误摘要
↓
发送通知
这种任务没有必要拆成十几个智能体。
但是,当任务出现以下特征时,单 Loop 的问题就会逐渐暴露。
上下文容易被污染
单个 Agent 既负责规划,又负责搜索、执行、检查和修改。
随着循环次数增加,上下文中会堆积:
- 原始任务;
- 多轮计划;
- 工具调用结果;
- 错误日志;
- 失败方案;
- 旧版本输出;
- 自我反思内容;
- 已经失效的假设。
最终,Agent 可能无法区分:
哪些信息仍然有效?
哪些是旧结果?
哪些只是自己的推测?
哪些已经被工具结果否定?
Graph 可以把不同职责拆到不同节点,并只给每个节点提供完成任务所需要的最小上下文。
执行者很难独立验证自己
假设一个 Agent 写了一段代码,然后又让同一个 Agent 判断代码是否正确。
这个 Agent 很可能沿用之前的假设。
它知道自己为什么这样写,也更容易为自己的结果寻找理由,而不是主动推翻自己的结论。
更合理的结构是:
代码生成 Agent
↓
独立测试节点
↓
安全审查 Agent
↓
逻辑验证 Agent
↓
统一门控节点
验证器应该尽量只看:
- 输入要求;
- 最终结果;
- 客观测试;
- 外部证据。
而不是完全继承执行者的思考过程。
单循环不擅长表达并行任务
例如,要审查一个代码仓库,可以同时进行:
- 安全漏洞扫描;
- 依赖风险检查;
- 代码规范检查;
- 单元测试检查;
- 性能问题分析。
如果全部放在一个循环中顺序执行:
安全检查
↓
依赖检查
↓
规范检查
↓
测试检查
↓
性能检查
总耗时接近所有步骤耗时之和。
Graph 可以采用扇出和汇合结构:
┌→ 安全检查 ────┐
├→ 依赖检查 ────┤
输入 → 任务分解节点 ├→ 规范检查 ────┼→ 汇总节点 → 最终结论
├→ 测试检查 ────┤
└→ 性能检查 ────┘
多个分支可以并行执行,再统一汇总。
错误难以局部恢复
在一个超长循环中,只要后面的步骤失败,系统可能需要重新读取大量上下文甚至重新执行前面的任务。
Graph 可以保存每个节点执行后的状态。
例如:
资料检索:已完成
内容提取:已完成
事实核验:已完成
文章生成:执行失败
恢复时只需要从文章生成节点继续,而不必重新搜索全部资料。
LangGraph 将持久化、检查点、故障恢复、人工介入和长时间运行作为其核心运行能力。
职责与权限难以隔离
生产系统中,不是每个 Agent 都应该拥有相同权限。
例如:
搜索 Agent:只能访问公开网页
分析 Agent:只能读取搜索结果
写作 Agent:只能生成草稿
审核 Agent:只能提出修改意见
发布节点:需要人工批准
如果所有能力都交给一个 Agent,那么一旦出现错误路由或提示词注入,影响范围会很大。
Graph Engineering 不只是任务分解,也是权限分解和责任分解。
三、Graph Engineering:状态、节点、边与工作流模式
Graph Engineering 的核心,是把复杂 Agent 系统表示成一张显式的有向图。
3.1 State:共享状态
State 表示系统当前的运行快照。
例如:
class State:
task: str
search_results: list
draft: str
review_result: str
retry_count: int
approved: bool
不同节点不应该依靠模糊的自然语言聊天记录传递所有信息,而应该通过结构化状态交换结果。
3.2 Node:执行节点
节点负责完成具体工作,例如:
planner
researcher
writer
fact_checker
style_checker
human_approval
publisher
一个节点可以是:
- LLM Agent;
- 普通 Python 函数;
- API 调用;
- 数据库查询;
- 浏览器操作;
- 测试程序;
- 人工审批;
- 另一个子图。
因此,Graph Engineering 不等于“把更多大模型连起来”。
很多关键节点最好使用确定性程序。
例如:
判断 HTTP 状态码:使用代码
检查 JSON Schema:使用代码
执行单元测试:使用测试框架
检查文件是否存在:使用文件系统
判断语义是否完整:使用模型或人工
3.3 Edge:路由关系
边决定任务下一步流向哪里。
固定边
规划 → 搜索 → 写作
条件边
验证通过 → 输出
验证失败 → 返回修改
风险过高 → 人工审批
达到重试上限 → 终止并报告
并行边
写作完成
├→ 事实检查
├→ 引用检查
└→ 风格检查
LangGraph 将工作流建模为 State、Node 和 Edge。节点执行工作,边决定下一步路由;一个节点存在多个出边时,目标节点可以在同一个执行阶段并行运行。
3.4 Graph Engineering 的关键模式
顺序流水线
输入 → 规划 → 执行 → 验证 → 输出
适合步骤明确、前后依赖稳定的任务。
条件路由
┌→ 简单问题 → 轻量模型
输入 → 分类路由节点 ├→ 复杂问题 → 推理模型
└→ 高风险操作 → 人工审核
注意:能够使用代码判断的路由,尽量不要交给模型。
例如:
if amount > 10000:
return "human_approval"
return "auto_process"
通常比让模型判断“这个金额是否足够高”更稳定。
扇出与汇合
也可以称为菱形结构:
┌→ Agent A ─┐
任务拆分 ──┼→ Agent B ─┼→ 结果汇总
└→ Agent C ─┘
适合:
- 多来源搜索;
- 多文件处理;
- 多视角审查;
- 多种方案生成;
- 多个独立实验;
- 多页面浏览器操作。
执行者与验证器分离
执行 Agent
↓
验证 Agent
↓
是否通过?
↙ ↘
否 是
返回修改 输出
验证器可以采用不同策略。
对抗式验证
验证器的目标不是补充内容,而是尝试推翻执行结果。
多视角验证
分别检查:
- 事实;
- 逻辑;
- 安全;
- 格式;
- 引用;
- 用户约束。
确定性验证
通过以下方式验证:
- 单元测试;
- Schema;
- 正则表达式;
- 哈希;
- 数据库约束;
- 浏览器 DOM;
- 文件差异;
- 编译结果。
在可靠性要求较高的系统中,确定性验证通常比“再问一次大模型”更重要。
人机协同节点
Graph 可以在关键位置暂停:
生成数据库修改方案
↓
人工审批
↙ ↘
拒绝 批准
↓ ↓
返回修改 执行变更
人工审批不是 Agent 系统“不够智能”的表现。
对于高风险操作,它是一种必要的治理机制。
LangGraph 的 Interrupt 机制可以暂停图执行、保存状态,并在收到外部输入后从相同任务线程继续运行。
子图模式
一个复杂节点内部还可以拥有自己的图。
例如:
主图:论文审阅系统
解析论文
↓
引用审查子图
├→ 提取引用
├→ 搜索 Scholar
├→ 核对标题和作者
├→ 获取 BibTeX
└→ 生成核验报告
↓
写作质量审查子图
├→ 结构检查
├→ 逻辑检查
├→ 术语检查
└→ 学术表达检查
子图可以隔离:
- 状态;
- 权限;
- 上下文;
- 重试次数;
- 工具;
- 失败范围。
四、使用 LangGraph 实现一个可运行的图工作流
下面实现一个简化版“技术文章生产图”。
工作流如下:
规划文章
↓
生成草稿
├──────────────┐
↓ ↓
事实检查 风格检查
└──────┬───────┘
↓
门控
↙ ↘
不通过 通过
↓ ↓
重新生成 最终输出
为了让示例不依赖任何大模型 API,所有节点暂时使用普通 Python 函数。
后续只需要把节点函数替换成实际的模型调用即可。
4.1 创建虚拟环境
Windows:
python -m venv .venv
.venv\Scripts\activate
python -m pip install --upgrade pip
pip install -U langgraph
Linux 或 macOS:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -U langgraph
4.2 完整代码
新建文件 graph_demo.py:
from __future__ import annotations
from typing import Literal, TypedDict
from langgraph.graph import END, START, StateGraph
class ArticleState(TypedDict, total=False):
"""整张图共享的结构化状态。"""
topic: str
outline: str
draft: str
fact_review: str
style_review: str
fact_ok: bool
style_ok: bool
retry_count: int
passed: bool
final_article: str
def planner(state: ArticleState) -> ArticleState:
"""规划节点:生成文章结构。"""
topic = state["topic"]
outline = (
f"文章主题:{topic}\n"
"1. 背景介绍\n"
"2. 核心概念\n"
"3. Loop 与 Graph 的关系\n"
"4. 适用场景\n"
"5. 示例代码\n"
"6. 总结"
)
print("[planner] 已生成文章大纲")
return {"outline": outline}
def writer(state: ArticleState) -> ArticleState:
"""写作节点:首次生成故意保留问题,第二轮完成修正。"""
retry_count = state.get("retry_count", 0)
if retry_count == 0:
draft = (
f"# {state['topic']}\n\n"
"Graph Engineering 已经取代 Loop Engineering。\n"
"它通过多个节点完成复杂任务,并可以进行并行处理。\n"
)
else:
draft = (
f"# {state['topic']}\n\n"
"Graph Engineering 并不是对 Loop Engineering 的简单替代,"
"而是在可靠单智能体循环之上增加多节点编排、状态管理、"
"条件路由、并行执行、验证和恢复能力。\n\n"
"## 适用场景\n\n"
"当任务需要并行处理、条件分支、独立验证、人工审批或"
"长时间暂停恢复时,可以考虑使用图结构;"
"对于目标单一、步骤简单的任务,单个 Loop 通常更加经济。\n\n"
"## 示例代码\n\n"
"可以使用 LangGraph 的 StateGraph 定义状态、节点和边,"
"再通过条件边控制验证失败后的重试过程。\n"
)
print(f"[writer] 已生成第 {retry_count + 1} 版草稿")
return {"draft": draft}
def fact_checker(state: ArticleState) -> ArticleState:
"""事实检查节点。"""
draft = state["draft"]
fact_ok = "并不是对 Loop Engineering 的简单替代" in draft
review = (
"事实检查通过:正确说明了 Graph 与 Loop 的关系。"
if fact_ok
else "事实检查失败:不能表述为 Graph 已经取代 Loop。"
)
print(f"[fact_checker] {review}")
return {
"fact_ok": fact_ok,
"fact_review": review,
}
def style_checker(state: ArticleState) -> ArticleState:
"""结构与写作检查节点。"""
draft = state["draft"]
style_ok = "## 适用场景" in draft and "## 示例代码" in draft
review = (
"结构检查通过:包含适用场景和代码说明。"
if style_ok
else "结构检查失败:缺少适用场景或示例代码。"
)
print(f"[style_checker] {review}")
return {
"style_ok": style_ok,
"style_review": review,
}
def gate(state: ArticleState) -> ArticleState:
"""统一门控节点:汇总两个并行检查结果。"""
passed = state.get("fact_ok", False) and state.get("style_ok", False)
retry_count = state.get("retry_count", 0)
if not passed:
retry_count += 1
print(
"[gate] "
f"passed={passed}, "
f"retry_count={retry_count}"
)
return {
"passed": passed,
"retry_count": retry_count,
}
def route_after_gate(
state: ArticleState,
) -> Literal["rewrite", "finish"]:
"""条件路由:失败则重写,通过或达到上限则结束。"""
if state.get("passed", False):
return "finish"
if state.get("retry_count", 0) >= 2:
return "finish"
return "rewrite"
def finalizer(state: ArticleState) -> ArticleState:
"""最终输出节点。"""
status = (
"审核通过"
if state.get("passed", False)
else "达到最大重试次数,需人工复核"
)
final_article = (
f"{state['draft']}\n\n"
"---\n\n"
f"事实审查:{state.get('fact_review', '未执行')}\n\n"
f"结构审查:{state.get('style_review', '未执行')}\n\n"
f"最终状态:{status}\n"
)
print(f"[finalizer] {status}")
return {"final_article": final_article}
def build_graph():
"""创建并编译工作图。"""
builder = StateGraph(ArticleState)
builder.add_node("planner", planner)
builder.add_node("writer", writer)
builder.add_node("fact_checker", fact_checker)
builder.add_node("style_checker", style_checker)
builder.add_node("gate", gate)
builder.add_node("finalizer", finalizer)
builder.add_edge(START, "planner")
builder.add_edge("planner", "writer")
# writer 完成后,两个检查节点并行执行。
builder.add_edge("writer", "fact_checker")
builder.add_edge("writer", "style_checker")
# LangGraph 会等待两个分支完成,再执行 gate。
builder.add_edge("fact_checker", "gate")
builder.add_edge("style_checker", "gate")
builder.add_conditional_edges(
"gate",
route_after_gate,
{
"rewrite": "writer",
"finish": "finalizer",
},
)
builder.add_edge("finalizer", END)
return builder.compile()
def main() -> None:
graph = build_graph()
result = graph.invoke(
{
"topic": "从 Loop Engineering 到 Graph Engineering",
"retry_count": 0,
"passed": False,
}
)
print("\n" + "=" * 60)
print(result["final_article"])
if __name__ == "__main__":
main()
4.3 运行程序
python graph_demo.py
预期执行过程:
[planner] 已生成文章大纲
[writer] 已生成第 1 版草稿
[fact_checker] 事实检查失败:不能表述为 Graph 已经取代 Loop。
[style_checker] 结构检查失败:缺少适用场景或示例代码。
[gate] passed=False, retry_count=1
[writer] 已生成第 2 版草稿
[fact_checker] 事实检查通过:正确说明了 Graph 与 Loop 的关系。
[style_checker] 结构检查通过:包含适用场景和代码说明。
[gate] passed=True, retry_count=1
[finalizer] 审核通过
这个示例虽然没有调用大模型,但已经展示了图工程最重要的能力:
- 状态在节点间传递;
- 每个节点职责明确;
- 两个审核节点并行运行;
- 门控节点汇总结果;
- 根据状态进行条件路由;
- 验证失败后回到写作节点;
- 设置最大重试限制;
- 最终结果包含完整审核记录。
4.4 为什么验证器是图中最重要的节点之一?
很多 Agent 项目失败,并不是因为模型不会生成,而是因为系统没有可靠地定义:
什么叫作完成?
例如,开发 Agent 说:
代码已经修改完成。
这不是可靠的完成信号。
更合理的信号是:
程序能够编译;
单元测试全部通过;
接口返回符合 Schema;
代码差异只涉及允许修改的文件;
安全扫描不存在高危问题;
人工审批已经通过。
一个实用原则是:
模型负责生成候选方案,
确定性程序负责检查客观条件,
独立验证器负责审查语义质量,
人工负责高风险决策。
验证器应该尽量做到:
- 与执行者职责分离;
- 采用独立上下文;
- 输出结构化结果;
- 给出可执行的失败原因;
- 不允许无限重试;
- 能够触发人工介入;
- 保留完整审计记录。
五、Graph 的适用场景、浏览器 Agent 启发与常见误区
5.1 什么时候应该使用 Graph?
不要因为 Graph Engineering 是新概念,就把所有任务都拆成多智能体。
可以先问以下几个问题。
任务是否需要并行?
例如:
- 同时搜索多个网站;
- 同时审查多个文件;
- 同时生成多个候选方案;
- 同时执行多种验证。
需要明显并行时,Graph 更合适。
任务是否存在条件分支?
例如:
论文存在 → 获取 BibTeX
论文不存在 → 输出未找到证据
遇到验证码 → 暂停等待人工处理
标题不一致 → 检查其他候选结果
分支越多,显式图结构越有价值。
是否需要独立验证?
例如:
- 临床数据审核;
- 学术引用核验;
- 金融报告;
- 代码安全扫描;
- 数据库写入;
- 自动发布内容。
需要独立验证时,可以把执行和审核拆成不同节点。
是否需要暂停和恢复?
例如:
- 等待用户补充资料;
- 等待验证码;
- 等待审批;
- 等待外部 API;
- 跨天执行;
- 长时间浏览器任务。
这类任务适合具有持久化状态和检查点的图运行时。
是否需要明确权限?
例如:
研究节点只能读取资料;
生成节点只能写草稿;
验证节点不能修改原始数据;
发布节点必须获得审批。
需要权限隔离时,图结构能够更清楚地表达责任边界。
5.2 什么时候不应该使用 Graph?
以下任务通常不需要复杂图结构:
- 一次性问答;
- 简单文本改写;
- 单个工具调用;
- 步骤固定且很短的自动化;
- 一个 Agent 就能可靠完成的任务;
- 没有并行、分支和审批的任务。
判断标准不是任务看起来是否复杂,而是:
任务是否真的需要多个独立责任单元?
如果只是为了显得先进而拆分 Agent,通常会增加:
- Token 成本;
- 网络延迟;
- 状态同步成本;
- 调试难度;
- 错误传播路径;
- 权限管理难度;
- 结果冲突。
并不是所有复杂任务都需要多智能体;一个拥有合适提示词和工具的单 Agent,有时能够更简单地完成相同工作。
5.3 Graph Engineering 不等于 LangGraph
LangGraph 是实现图工作流的一种框架,但 Graph Engineering 是更上层的工程思想。
目前常见的多智能体或图工作流技术包括:
- LangGraph;
- Microsoft AutoGen GraphFlow;
- Google Agent Development Kit;
- 状态机;
- 工作流引擎;
- DAG 调度系统;
- 自定义 Python 编排程序;
- 事件驱动架构;
- 消息队列与任务系统。
Microsoft AutoGen 的 GraphFlow 使用智能体有向图表示多智能体工作流;Google ADK 也支持将多个 Agent 和可执行节点组合成工作流。
因此,重点并不是选择哪个框架,而是能否回答以下问题:
系统中有哪些节点?
每个节点负责什么?
状态怎样传递?
哪些节点可以并行?
谁负责验证?
失败后从哪里恢复?
什么情况下需要人工介入?
谁有权执行高风险操作?
任务什么时候终止?
框架只是实现手段,拓扑和治理设计才是 Graph Engineering 的核心。
5.4 对浏览器 Agent 的启发
以“自动核验论文引用”为例,如果使用单 Agent,可以设计成:
搜索论文
↓
检查结果
↓
打开引用
↓
读取 BibTeX
↓
验证标题作者
↓
失败后重试
这种方式适合简单、单篇论文任务。
当任务扩展到整篇论文的引用审核时,可以使用 Graph:
LaTeX/PDF 解析节点
↓
引用提取节点
↓
任务分发节点
┌────┼────┬────┐
↓ ↓ ↓ ↓
论文1 论文2 论文3 论文4
核验 核验 核验 核验
└────┼────┴────┘
↓
结果汇总节点
↓
冲突检查节点
↓
人工确认异常项
↓
生成 BibTeX 和审阅报告
这里可以把能力拆分为:
- 解析器:负责读取 LaTeX、PDF、Word;
- 搜索节点:负责操作 Google Scholar;
- 匹配节点:负责核对标题、作者、年份和来源;
- BibTeX 节点:负责提取引用;
- 验证节点:负责检查字段完整性;
- 汇总节点:负责生成 CSV、JSON 和 Markdown 报告;
- 人工节点:负责验证码和模糊匹配;
- 检查点:负责保存每篇论文的处理状态。
这样,即使第 57 篇论文处理失败,也不需要重新核验前面已经完成的 56 篇。
这正是 Graph Engineering 对长时间浏览器 Agent 的核心价值:
不只是让 Agent 会操作浏览器,而是把浏览器操作组织成一个可验证、可恢复、可追踪的任务系统。
5.5 常见误区
误区一:Agent 越多,系统越智能
Agent 数量增加,不代表系统能力线性增加。
如果职责没有清晰划分,多个 Agent 只会重复讨论、互相传递错误结论。
误区二:所有节点都必须使用大模型
图中的很多节点应该使用普通代码,例如:
- 路由;
- 数据校验;
- 文件检查;
- 测试;
- 权限判断;
- 重试计数;
- 超时处理;
- 状态持久化。
大模型应该用在确实需要语义理解和开放式推理的位置。
误区三:让模型决定所有路由
对于确定性条件,应该优先使用代码。
错误做法:
请判断是否已经达到最大重试次数。
正确做法:
if retry_count >= max_retries:
return "stop"
误区四:没有全局停止条件
每个循环和整张图都应该有停止条件,例如:
最大执行步数;
最大 Token;
最大运行时间;
最大费用;
最大重试次数;
连续多轮无新结果;
人工取消;
验证通过。
否则图中仍然可能存在局部死循环。
误区五:把所有历史记录塞给所有节点
Graph 的价值之一,就是控制上下文边界。
搜索 Agent 不一定需要看到写作 Agent 的全部历史。
验证 Agent 也不一定需要看到执行者的完整推理过程。
应该遵循:
最小必要上下文原则。
六、总结与参考资料
Loop Engineering 和 Graph Engineering 的区别,可以概括为:
Loop 关注单个智能体怎样持续执行。
Graph 关注多个执行单元怎样分工、路由、并行、
验证、恢复和接受治理。
Loop 是 Graph 的基础单元,而不是被 Graph 淘汰的旧技术。
一个成熟的 Agent 系统往往具有以下结构:
可靠的节点内部循环
+
结构化共享状态
+
显式条件路由
+
并行任务执行
+
独立验证节点
+
持久化检查点
+
人工审批机制
+
权限和成本控制
Graph Engineering 真正带来的变化,不是“多调用几个大模型”,而是工程视角的变化:
从设计一次模型回答,
到设计一个智能体的行为循环,
再到设计一群智能体的组织结构。
当 AI Agent 从演示程序进入真实生产环境后,我们最终面对的已经不只是模型问题,而是一个经典的系统工程问题:
怎样分工、怎样协作、怎样验证、怎样恢复,以及怎样确保系统始终处于可控制状态。
这才是 Graph Engineering 最值得关注的地方。
更多推荐



所有评论(0)