从循环工程到图工程:构建可靠性
从循环工程到图工程:作为工程单元的智能体循环,以及为何状态纠缠会导致单个循环失效,还有图结构为何能提供帮助。
来源: From Loop Engineering to Graph Engineering: Building Reliable Agentic Systems in Tech Startups
本指南将逐步构建从原材料到可运行系统的完整流程,主题为《从循环工程到图引擎工程:在科技初创企业中打造可靠的智能体系统》。重点在于可操作的步骤、明确的检查点,以及可直接放入代码仓库的代码,无需猜测其用途。 在概览阶段,应在修改代码之前明确输入参数、各步骤的负责人以及完成标准。操作人员应能够从已知的检查点重新运行相应步骤,而无需推测隐藏状态。 除了功能结果外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在系统从演示环境过渡到共享环境时出现意外费用。
while not finished:
context = build_context(state)
action = model.decide(context)
observation = tools.execute(action)
state = update(state, action, observation)
1. 作为工程对象的智能体循环
在处理“1. Agent循环”阶段时,首先写下相关契约:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 将配置信息置于应用程序代码之外。环境文件、密钥存储以及功能开关应集中存放于一个位置,这样操作人员无需查看整个系统结构即可进行审计。 在耗时较高的步骤之后设置检查点。当操作人员重新尝试后续节点时,恢复流程不应再次调用相同的LLM接口。
action = model(current_state)
observation = execute(action)
next_state = transition(current_state, action, observation)
continue_execution =
task_is_not_complete
and execution_budget_is_available
MAX_ITERATIONS = 12
MAX_TOOL_CALLS = 30
MAX_RUNTIME_SECONDS = 600
MAX_TOKEN_COST = 250_000
while budgets_available(state):
action = agent.next_action(state)
if not policy.allows(action):
return TerminalFailure("policy_violation")
result = execute_idempotently(action)
state = persist_transition(state, action, result)
verification = verifier.evaluate(state)
if verification.passed:
return VerifiedSuccess(
state=state,
evidence=verification.evidence
)
return TerminalFailure("budget_exhausted")
2. 单一循环开始出问题的地方
在处理“单阶段两个环节”的流程时,首先需明确相关约定:所需的输入参数、成功信号,以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改不会偏离原有设计。
同时记录正常流程与异常恢复路径。重试机制、人工审核环节以及错误消息处理都是产品本身的组成部分,而非后续需要补充的功能。
在成本较高的步骤之后设置检查点。当操作员重新尝试后续节点时,恢复流程不应再次调用相同的大型语言模型接口。
状态纠缠
在处理状态纠缠阶段时,首先需明确规范:所需的输入参数、成功信号以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 优先选择小型、可测试的单元,而非庞大的脚本。当某一步骤失败时,故障应指向单一责任模块,而非复杂的流程链。 在成本较高的步骤之后设置检查点。当操作员重新尝试后续节点时,恢复流程不应再次调用相同的大型语言模型。 在处理状态纠缠阶段时,首先需明确规范:所需的输入参数、成功信号以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 在功能结果旁记录执行时间以及token或查询成本。提前了解成本情况,可避免从演示环境过渡到共享环境时出现意外费用。
含义模糊的完成状态
将“模糊完成阶段”视为可度量的界面来处理时,其效果最佳。在扩大范围之前,先记录一个成功的示例、一个失败案例以及回滚说明。 将配置置于应用程序代码之外。环境文件、密钥存储和功能标志应集中存放于一处,这样操作人员无需查看整个结构即可进行审计。 保持图结构的扁平化与类型化。嵌套的数据块会掩盖哪个节点修改了哪个字段的信息,且在中断后会导致无法继续执行。
全局重试
将全局重试阶段视为可度量的对象来处理,效果最佳。在扩大范围之前,先记录一份理想的操作日志、一个失败案例以及回滚说明。同时记录正常流程与恢复流程的文档。重试机制、人工审核环节以及死信处理都是产品本身的组成部分,而非后续需要补充的内容。要保持图结构的层次简单且类型明确,嵌套的数据块会掩盖哪个节点编写了哪个字段的信息,还会在中断后导致无法继续处理。
故障隔离能力较弱
将弱故障隔离阶段视为可测量的界面时,其效果最佳。在扩大范围之前,先记录一份标准日志、一个故障案例以及回滚说明。 优先选择小型且可测试的单元,而非庞大的脚本。当某一步骤失败时,故障应指向单一责任模块,而非复杂的处理流程。 保持图结构的状态简洁且具有类型定义。嵌套的数据块会掩盖哪个节点修改了哪个字段的信息,还会导致中断后无法继续执行。 将弱故障隔离阶段视为可测量的界面时,其效果最佳。在扩大范围之前,先记录一份标准日志、一个故障案例以及回滚说明。 在功能结果旁同时记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。
权限聚合
在特权聚合阶段,应在修改代码之前明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 配置信息应置于应用程序代码之外。环境文件、密钥存储以及功能标志应集中存放于一个位置,以便操作人员无需查看整个系统结构即可进行审计。 对于涉及资金支出或修改生产数据的操作,必须经过人工审批。编译时的连接方式并不等同于业务功能的完整性。
有限的并发性
在有限并发阶段,应在修改代码之前明确输入参数、该步骤的负责人以及终止条件。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 需同时记录正常流程和故障恢复流程。重试机制、人工审核环节以及错误处理都是产品本身的组成部分,而非后续需要补充的功能。 对于涉及资金支出或修改生产数据的操作,必须经过人工审批。编译时的逻辑连接并不等同于业务功能的完整性。
可重放性差
在可重放性较差的阶段,修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 优先选择小型、可测试的单元,而非庞大的脚本。当某个步骤失败时,故障应指向单一责任点,而非复杂的流程链。 对于涉及资金支出或修改生产数据的操作,必须经过人工审批。编译时的逻辑连接并不等同于业务功能的完整性。 在可重放性较差的阶段,修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 除了功能结果外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在流程从演示环境转向共享环境时出现意外账单。
3. 图引擎的变更内容
在处理“图引擎的3个方面”这一阶段时,首先需明确相关约定:所需的输入参数、成功标志,以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 应将配置信息与应用程序代码分开存放。环境文件、密钥存储以及功能开关应集中于一个位置,这样操作人员无需查看整个图结构即可进行审计。 在成本较高的步骤之后设置检查点。当操作人员重新执行后续节点时,恢复流程不应再次计费相同的大型语言模型调用。
Graph:
nodes
edges
shared state
terminal states
interface Node<Input, Output> {
id: string;
inputSchema: Schema<Input>;
outputSchema: Schema<Output>;
timeoutMs: number;
retryPolicy: RetryPolicy;
requiredCapabilities: Capability[];
execute(
input: Input,
context: RunContext
): Promise<Output>;
verify(
output: Output,
context: RunContext
): Promise<Evidence>;
}
interface Edge {
from: NodeId;
to: NodeId;
condition: (
state: WorkflowState
) => boolean;
}
const edges = [
edge(
"build",
"tests",
state => state.build.exitCode === 0
),
edge(
"build",
"repair",
state =>
state.build.exitCode !== 0 &&
state.repairAttempts < 3
),
edge(
"build",
"failed",
state =>
state.build.exitCode !== 0 &&
state.repairAttempts >= 3
)
];
4. 用于人工智能辅助交付流程的图结构
在为某个阶段设计4A图表时,首先需明确相关约定:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 同时记录正常流程与异常恢复路径。重试机制、人工审核环节以及死信处理都是产品本身的组成部分,而非后续需要补充的功能。 在成本较高的操作之后设置检查点。当操作员重新尝试某个节点时,恢复流程不应再次调用相同的LLM接口。
+----------------+
| Threat Model |
+--------+-------+
|
Intake -> Normalize -> Plan ------+-----> Implementation
| | |
| +-------v--------+ |
+--->| Test Planning |-----+
+----------------+ |
v
Build
|
+----------------------+------------------+
| pass | fail
v v
Integration Tests Diagnose -> Repair
| |
+----+----+ +-> Build
| |
pass fail
| |
v +-> Diagnose
Security Check
|
+----+----+
| |
pass high risk
| |
v v
PR Creation Human Approval
| |
+----+----+
|
v
Canary Deploy
|
Runtime Verify
| |
pass fail
| |
v v
Done Rollback -> Failed
5. 状态必须是类型化的、持久的且可分区的
在处理“5种必须存在的状态”阶段时,首先需明确相关规范:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 建议采用小型、可测试的单元而非庞大的脚本。当某个步骤失败时,故障应指向单一责任模块,而非复杂的流程链。 在成本较高的步骤之后设置检查点。当操作员重新尝试后续节点时,恢复流程不应再次调用相同的LLM接口。 在处理“5种必须存在的状态”阶段时,首先需明确相关规范:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 在功能结果旁记录执行时间以及Token或查询成本。提前了解成本情况,可避免从演示环境过渡到共享环境时出现意外费用。
{
"runId": "run_93af",
"goal": {
"ticketId": "ENG-482",
"repository": "payments-api",
"baseRevision": "5df87a1"
},
"plan": {
"artifactId": "sha256:71d...",
"version": 2
},
"implementation": {
"commit": "81f3ce2",
"changedFiles": [
"src/refunds/service.ts",
"tests/refunds/service.test.ts"
]
},
"build": {
"exitCode": 0,
"artifactId": "sha256:932..."
},
"verification": {
"unitTests": "passed",
"integrationTests": "passed",
"security": "pending"
},
"budgets": {
"repairAttempts": 1,
"toolCalls": 18,
"tokens": 84320
}
}
{
"eventId": "evt_1092",
"runId": "run_93af",
"nodeId": "integration-tests",
"attempt": 2,
"inputHash": "sha256:8a2...",
"outputHash": "sha256:19c...",
"status": "succeeded",
"startedAt": "2026-09-14T08:41:02Z",
"completedAt": "2026-09-14T08:43:18Z"
}
6. 基于证据的过渡机制
将“6种基于证据的过渡机制”视为可度量的结构来使用效果最佳。在扩大范围之前,先记录一份理想的处理结果、一个失败案例以及回滚说明。 配置应置于应用程序代码之外。环境文件、密钥存储和功能标志应集中存放,以便操作人员无需查看整个结构就能进行审计。 保持图结构的扁平化与类型化。嵌套的数据块会掩盖哪个节点修改了哪个字段的信息,还会在中断后导致无法继续处理。
type TestEvidence = {
command: string;
revision: string;
exitCode: number;
totalTests: number;
failedTests: number;
reportArtifact: ArtifactRef;
};
function testsPassed(
evidence: TestEvidence,
workflow: WorkflowState
): boolean {
return (
evidence.exitCode === 0 &&
evidence.totalTests > 0 &&
evidence.failedTests === 0 &&
evidence.revision === workflow.currentRevision
);
}
repository_valid
and build_passed
and tests_passed
and security_accepted
and deployment_verified
7. 构件溯源与选择性回放
将“7种工件传承与阶段”视为可度量的界面来处理效果最佳。在扩大范围之前,先记录一个成功案例、一个失败案例以及回滚说明。 同时记录正常流程与恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的一部分,而非后续的优化工作。 保持图结构的状态扁平且具有类型约束。嵌套的数据块会掩盖哪个节点修改了哪个字段的信息,还会在中断后导致无法继续执行。
{
"artifactId": "sha256:f39...",
"type": "test_report",
"producedBy": "integration-tests",
"graphVersion": "delivery-v4",
"inputs": [
"sha256:source-revision-81f3ce2",
"sha256:test-config-a17"
]
}
Source code changed:
invalidate build artifact
invalidate unit-test report
invalidate integration-test report
invalidate deployment artifact
Threat model unchanged:
preserve existing threat-model artifact
Requirements unchanged:
preserve normalized requirements
preserve approved implementation plan
8. 可重试性及副作用控制
将“8个幂等性与副作用阶段”视为可度量的对象来处理效果最佳。在扩大范围之前,先记录一份理想的运行日志、一个故障案例以及回滚说明。 优先选择小型且可测试的单元,而非庞大的脚本。当某一步骤失败时,故障应指向单一责任点,而非复杂的流程链。 保持图结构的状态简洁且具有类型定义。嵌套的数据块会掩盖哪个节点修改了哪个字段的信息,还会在流程中断后导致无法继续执行。 将“8个幂等性与副作用阶段”视为可度量的对象来处理效果最佳。在扩大范围之前,先记录一份理想的运行日志、一个故障案例以及回滚说明。 在功能结果之外,还需记录执行时间以及令牌或查询的成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。
const idempotencyKey = [
runId,
nodeId,
inputArtifactHash
].join(":");
await deploymentApi.deploy({
idempotencyKey,
revision,
environment
});
deploy_canary -> verify_runtime
|
+-> failure -> rollback_canary
9. 确定性及基于模型的路由
在9个确定性且基于模型的阶段中,应在修改代码之前明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 配置信息应置于应用程序代码之外。环境文件、密钥存储以及功能标志应集中存放于一个位置,以便操作人员无需查看整个流程即可进行审计。 当下一步是代码执行或工具调用时,优先使用具有架构验证的结构化输出,而非自由形式的文本。
if (testReport.failedTests > 0) {
return "repair";
}
if (securityReport.criticalFindings > 0) {
return "human-review";
}
return "deploy";
const decision = await riskClassifier.run({
changeSummary,
affectedServices,
dataClassification,
migrationPlan
});
type RiskDecision = {
level: "low" | "medium" | "high";
reasons: string[];
requiredChecks: CheckId[];
};
10. 调度、并行处理与连接
对于10个调度并行性及阶段,应在修改代码之前明确输入参数、各步骤的负责人以及终止条件。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 需同时记录正常流程与故障恢复流程。重试机制、人工审核环节以及错误处理都是产品本身的组成部分,而非后续需要补充的内容。 对于涉及资金支出或修改生产数据的操作,必须经过人工审批。编译时的逻辑连接并不等同于业务功能的完整性。
all required predecessor nodes are complete
and the incoming transition conditions are satisfied
+-> Generate Tests --+
Plan Complete ---+-> Threat Model ----+-> Join -> Implementation Review
+-> API Analysis ----+
全部
在“全部”阶段,修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 优先选择小型、可测试的单元,而非冗长的脚本。当某个步骤失败时,故障应指向单一责任点,而非复杂的流程链。 对于涉及资金支出或修改生产数据的操作,必须经过人工审批。仅靠编译时的配置并不足以确保业务的完整性。 在“全部”阶段,修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 在功能结果之外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在流程从演示环境转向共享环境时出现意外账单。
任意
在处理任意阶段时,首先写下相关契约:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 将配置信息与应用程序代码分开存放。环境文件、密钥存储以及功能开关应集中于一个位置,这样操作人员无需查看整个流程就能进行审计。 在耗时较高的步骤之后设置检查点。当操作人员重新执行后续节点时,恢复流程不应再次计费相同的大型语言模型调用。
法定人数
在处理 Quorum 阶段时,首先写下合约的详细内容:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改不会出错。 同时记录正常流程和故障恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的组成部分,而非后续需要补充的功能。 在成本较高的步骤之后设置检查点。当操作员重新尝试某个节点时,恢复流程不应再次调用相同的 LLM 接口。
尽力而为
在“尽力而为”阶段工作时,首先需明确合同条款:所需输入、成功信号以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持透明。 优先选择小型、可测试的单元,而非庞大的脚本。当某个步骤失败时,故障应指向单一责任点,而非复杂的流程链。 在成本较高的步骤之后设置检查点。当操作员重新尝试后续节点时,恢复流程不应再次调用相同的LLM接口。 在“尽力而为”阶段工作时,首先需明确合同条款:所需输入、成功信号以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持透明。 在功能结果旁记录执行时间以及token或查询成本。提前了解成本情况,可避免从演示环境过渡到共享环境时出现意外收费。
快速失败
“快速失败”阶段若被视为可度量的指标,效果最佳。在扩大范围之前,先记录一份理想的运行日志、一个失败案例以及回滚说明。 将配置与应用程序代码分开。环境文件、密钥存储和功能开关应集中存放于一处,这样操作人员无需查看整个系统结构即可进行审计。 保持系统状态的结构简洁且具有类型约束。嵌套的数据结构会掩盖是哪个节点修改了哪个字段,还会在出现中断后导致恢复失败。
11. 失败语义
将“11个失败语义阶段”视为可测量的界面来处理时效果最佳。在扩大范围之前,先记录一份完美的测试用例、一个失败案例以及回滚说明。同时记录正常流程和恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的一部分,而非后续需要补充的功能。保持图结构的状态简洁且具有类型约束,嵌套的数据块会掩盖哪个节点修改了哪个字段的信息,还会在中断后导致流程无法继续。
type FailureClass =
| "transient_dependency"
| "invalid_input"
| "verification_failed"
| "policy_denied"
| "budget_exhausted"
| "human_rejected"
| "unknown";
transient_dependency -> retry with backoff
invalid_input -> return to the upstream producer
verification_failed -> diagnose and repair
policy_denied -> terminal failure
budget_exhausted -> human escalation
human_rejected -> terminal cancellation
unknown -> quarantine and inspect
repair_attempts_remaining
and runtime_budget_available
and token_budget_available
and permitted_blast_radius_not_exceeded
12. 安全边界属于节点
将“12个安全边界归属”阶段视为可测量的界面来处理效果最佳。在扩大范围之前,先记录一份标准操作流程、一个故障案例以及回滚说明。 优先选择小型且可测试的单元,而非庞大的脚本。当某一步骤失败时,故障应指向单一责任主体,而非复杂的流程链。 保持图表状态简洁且具有类型定义。嵌套的数据块会掩盖哪个节点修改了哪个字段的信息,还会在中断后导致无法继续处理。 将“12个安全边界归属”阶段视为可测量的界面来处理效果最佳。在扩大范围之前,先记录一份标准操作流程、一个故障案例以及回滚说明。 在功能结果旁记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。
nodes:
repository_analysis:
capabilities:
- repository:read
implementation:
capabilities:
- repository:read
- workspace:write
create_pull_request:
capabilities:
- repository:pull_request:create
deploy_canary:
capabilities:
- deployment:preview:create
production_release:
capabilities:
- deployment:production:create
approval:
required: true
13. 版本控制与可复现性
在“版本控制与可复现性”阶段,应在修改代码之前明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 配置信息应置于应用程序代码之外。环境文件、密钥存储以及功能开关应集中存放于一个位置,以便操作人员无需查看整个系统结构即可进行审计。 对于涉及资金支出或修改生产数据的操作,必须经过人工审批。编译时的连接方式并不等同于业务功能的完整性。
{
"runId": "run_93af",
"graph": {
"name": "software-delivery",
"version": "4.2.1"
},
"nodes": {
"planner": "planner@2.3.0",
"implementation": "coding-agent@5.1.2",
"security-review": "security-review@1.8.0"
},
"models": {
"planner": "model-a-2026-08",
"implementation": "model-b-2026-09"
},
"policyVersion": "delivery-policy@3.4.0",
"baseRevision": "5df87a1"
}
14. 图级可观测性
在 Graph 阶段的 14 项可观测性要求中,修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 需同时记录正常流程与故障恢复流程。重试机制、人工审核环节以及死信处理都是产品功能的一部分,而非后续需要补充的内容。 对于涉及资金支出或修改生产数据的操作,必须经过人工审批。编译时的连接方式并不等同于业务功能的完整性。
workflow_run_id
graph_version
node_id
node_attempt
parent_node_id
artifact_ids
model_version
prompt_version
15. 最简启动实现方案
在15 A Minimal Startup阶段,修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 优先选择小型、可测试的单元,而非庞大的脚本。当某个步骤失败时,故障应指向单一责任点,而非复杂的流程链。 对于涉及资金支出或修改生产数据的操作,必须经过人工审批。编译时的逻辑连接并不等同于业务功能的完整性。 在15 A Minimal Startup阶段,修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 在功能结果之外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外账单。
>workflow_definitions
workflow_versions
workflow_runs
node_definitions
node_attempts
transition_events
artifacts
approvals
capability_grants
def schedule(run):
state = load_state(run.id)
candidates = find_pending_nodes(run.graph_version)
for node in candidates:
if dependencies_satisfied(node, state):
if incoming_guards_allow(node, state):
enqueue(
run_id=run.id,
node_id=node.id,
graph_version=run.graph_version
)
def execute_node(job):
attempt = create_attempt(job)
try:
inputs = resolve_inputs(job)
validate(inputs, job.node.input_schema)
capabilities = issue_capabilities(job.node)
output = job.node.execute(inputs, capabilities)
validate(output, job.node.output_schema)
evidence = job.node.verify(output)
persist_success(attempt, output, evidence)
evaluate_outgoing_edges(job.run_id, job.node.id)
except Exception as error:
failure = classify_failure(error)
persist_failure(attempt, failure)
apply_failure_transition(job, failure)
finally:
revoke_capabilities(job.node)
16. 从循环结构迁移到图结构
在处理“从某个阶段迁移”的16个步骤时,首先需明确相关约定:所需的输入参数、成功信号,以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 应将配置信息与应用程序代码分开存放。环境文件、密钥存储以及功能开关应集中管理,这样操作人员无需查看整个图结构即可进行审计。 在成本较高的步骤之后设置检查点。当操作人员重新尝试后续节点时,恢复流程不应再次调用相同的大型语言模型。
第一步:为现有循环结构添加监控功能
在处理第一步中的工具阶段时,首先写下相关约定:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 同时记录正常流程和异常恢复流程。重试机制、人工审核环节以及错误消息处理都是产品本身的组成部分,而非后续需要补充的功能。 在成本较高的步骤之后设置检查点。当操作员重新尝试某个后续节点时,恢复流程不应再次调用相同的大型语言模型。
第二步:确定稳定阶段
在完成“第2步:确定稳定阶段”时,首先需写明相关规范:所需输入、成功标志以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 建议使用小型、可测试的单元,而非庞大的脚本。当某一步骤失败时,故障应指向单一责任点,而非复杂的流程链。 在成本较高的步骤之后设置检查点。当操作员重新尝试后续节点时,恢复流程不应再次调用相同的LLM接口。 在完成“第2步:确定稳定阶段”时,首先需写明相关规范:所需输入、成功标志以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 在功能结果旁记录执行时间以及Token或查询成本。提前了解成本情况,可避免从演示环境过渡到共享环境时出现意外收费。
第3步:定义类型化工件
将第三步“定义类型化阶段”视为可度量的结构来处理效果最佳。在扩大范围之前,先记录一份理想的流程示例、一个失败案例以及回滚说明。 将配置与应用程序代码分开。环境文件、密钥存储和功能标志应集中存放于一处,这样操作人员无需查看整个流程图即可进行审计。 保持流程图的状态简洁且类型化。嵌套的数据块会掩盖哪个节点修改了哪个字段的信息,还会导致在流程中断后无法继续执行。
第四步:外部化转换逻辑
将第4步“外部化转换”阶段视为可度量的对象来处理效果最佳。在扩大范围之前,先记录一个成功的用例、一个失败案例以及回滚说明。同时文档化正常流程和恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的组成部分,而非后续需要补充的内容。保持图结构的状态简洁且具有类型定义;嵌套的数据块会掩盖哪个节点修改了哪个字段的信息,还会在中断后导致流程无法继续。
第5步:添加独立验证
将“第5步:添加独立阶段”视为可度量的对象来处理时效果最佳。在扩大范围之前,需记录一份理想的执行日志、一个故障案例以及回滚说明。 优先选择小型且可测试的单元,而非庞大的脚本。当某一步骤出现故障时,故障应指向单一责任主体,而非复杂的流程链。 保持图表状态简洁且具有类型定义。嵌套的数据结构会掩盖哪个节点修改了哪个字段的信息,还会在流程中断后导致无法继续执行。 将“第5步:添加独立阶段”视为可度量的对象来处理时效果最佳。在扩大范围之前,需记录一份理想的执行日志、一个故障案例以及回滚说明。 除了功能结果外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在流程从演示环境转向共享环境时出现意外费用。
第6步:引入检查点
在第六步“引入检查点”阶段,应在修改代码之前明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 配置信息应置于应用程序代码之外。环境文件、密钥存储以及功能标志应集中存放于一个位置,以便操作人员无需查看整个系统结构即可进行审计。 对于涉及资金支出或修改生产数据的操作,必须经过人工审批。编译时的连接方式并不等同于业务功能的完整性。
第七步:隔离功能模块
在第七步“隔离功能”阶段,应在修改代码之前明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 需同时记录正常流程和异常恢复流程。重试机制、人工审核环节以及错误处理都是产品本身的组成部分,而非后续需要补充的内容。 对于涉及资金支出或修改生产数据的操作,必须经过人工审批。编译时的逻辑连接并不等同于业务功能的完整性。
第八步:添加受限的恢复路径
在“第8步:添加有界阶段”中,修改代码之前需明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 优先选择小型、可测试的单元,而非冗长的脚本。当某一步骤失败时,故障应指向单一责任点,而非复杂的流程链。 对于涉及资金支出或修改生产数据的操作,必须经过人工审批。编译时的连接方式并不等同于业务功能的完整性。 在“第8步:添加有界阶段”中,修改代码之前需明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 在功能结果之外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在流程从演示环境过渡到共享环境时出现意外账单。
第9步:并行处理已验证的独立任务
在执行第9步“并行处理已验证的独立任务”时,首先需明确相关约定:所需输入、成功信号以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 将配置信息与应用程序代码分开存放。环境文件、密钥存储以及功能开关应集中管理,以便操作员无需查看整个流程即可进行审计。 在耗时较高的步骤之后设置检查点。当操作员重新尝试后续节点时,恢复流程不应再次调用相同的大型语言模型。
第10步:为流程图添加版本控制
在处理第10步的版本阶段时,首先写下相关契约:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 同时记录正常流程和异常恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的组成部分,而非后续的优化工作。 在成本较高的步骤之后设置检查点。当操作员重新尝试某个后续节点时,恢复流程不应再次调用相同的LLM接口。
17. 常见的图计算工程反模式
在处理17个常见的图工程阶段时,首先写下相关规范:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 优先选择小型、可测试的单元,而非庞大的脚本。当某个步骤失败时,故障应指向单一的责任模块,而非复杂的流程链。 在成本较高的步骤之后设置检查点。当操作员重新尝试后续节点时,恢复流程不应再次调用相同的LLM接口。
每个节点一个智能体
由模型控制的确定性决策
共享的可变状态
无限制的循环
智能体报告的验证结果
全局凭证
缺失的补偿路径
没有追溯历史的图结构
过早的动态路由
18. 当图结构不再必要时
结论
Implicit control flow
becomes
explicit workflow topology
Conversation state
becomes
typed durable state
Agent-declared success
becomes
evidence-gated completion
Global retries
become
bounded local recovery
Shared privileges
become
node-scoped capabilities
Complete reruns
become
dependency-aware replay
Sequential execution
becomes
controlled concurrency
Opaque behavior
becomes
graph-level observability