第十一章:四大工程范式(Prompt/Context/Harness/Loop Engineering)对比

Prompt Engineering ⊂ Context Engineering ⊂ Harness Engineering ⊂ Loop Engineering,四大工程范式嵌套递进。理解它们的关系,是从”会写Prompt”到”能构建生产级Agent系统”的关键跃迁。

四个工程范式,嵌套而非并列:Prompt ⊂ Context ⊂ Harness ⊂ Loop

前三层让 Agent “干活不出错”,第四层让它”自己干到完”。

理解它们的关系,是从”会写 Prompt”到”能构建生产级 Agent 系统”的关键跃迁。


11.1 四大范式总览

graph TD
subgraph Loop["Loop Engineering 循环工程 — 怎么让它自己干到完"]
    direction TB
    subgraph Harness["Harness Engineering 线束工程 — 怎么干不出事"]
        direction TB
        subgraph Context["Context Engineering 上下文工程 — 给它什么信息"]
            direction TB
            Prompt["Prompt Engineering<br/>提示词工程 — 怎么跟它说话"]
        end
    end
end

style Loop fill:#e8f5e9,stroke:#2e7d32
style Harness fill:#f3e5f5,stroke:#7b1fa2
style Context fill:#fff9c4,stroke:#f9a825
style Prompt fill:#e3f2fd,stroke:#1565c0
维度 Prompt Engineering Context Engineering Harness Engineering Loop Engineering
核心问题 表达 — 如何写好指令 信息 — 给 Agent 看什么 执行 — 系统如何不出错 自主 — 任务如何自动干完
范围 一段文本字符串 动态的信息管道 完整的基础设施和编排 带验收标准的自动闭环
关注点 用词、措辞、示例 信息质量、时机、格式 可靠性、安全性、可观测性、恢复 触发、验证、重试、终止、升级人工
性质 静态 动态(每轮变化) 架构性(跨运行持久) 闭环性(迭代到达标为止)
技能要求 写作能力 系统设计能力 工程架构能力 控制系统 + 验收设计能力
失败模式 指令不好 → 输出差 缺少上下文 → 幻觉/错误动作 系统崩溃/失控/无法恢复 死循环烧钱/错误放大/虚假完成

用”带一个新员工”来理解四层(一遍就懂):

范式 你做的事 类比
Prompt 把任务交代清楚:”你是客服,回复要简洁” 写岗位说明书
Context 把资料给到位:客户订单、历史记录、FAQ 开工前备齐资料
Harness 配好工位:工具、权限、制度、监控 办公环境和规章制度
Loop 交代完就走人:他自己”干活→自查→返工→验收合格才交付” 建立自驱闭环,不用你盯

11.2 Prompt Engineering(提示词工程)

定义

Prompt Engineering 是编写和组织给 LLM 的文本指令,以引导其产生期望输出的学科。它关注的是”如何写好指令“ — 提示词中的措辞、结构和示例。

通俗类比:Prompt 就像”给新人交代任务的话术” — 同一件事,交代清楚和没交代清楚,干出来的活天差地别。

核心技术

技术 描述 适用场景
Zero-shot 直接给指令,不提供示例。依赖模型预训练知识 简单分类、格式转换、翻译
Few-shot 提供 2-5 个输入/输出示例 格式不直观的任务
Chain-of-Thought (CoT) 让模型”一步步思考”,先推理再回答 数学、逻辑推理
Tree-of-Thought (ToT) 并行探索多条推理路径,评估选最优 复杂规划、创意任务
ReAct 推理与行动交替:思考 → 行动 → 观察 → 循环 需要工具调用的 Agent
Self-consistency 采样多条 CoT 路径,取多数投票 高风险推理

在三大框架中的代码体现

LangChain — ChatPromptTemplate:

1
2
3
4
5
6
7
8
9
from langchain_core.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_messages([
("system", "你是一个专业的研究助手。回答要简洁。"),
("placeholder", "{chat_history}"),
("human", "{input}"),
])

chain = prompt | model

LangGraph — State 中的系统消息:

1
2
3
4
5
6
7
from langgraph.graph import StateGraph, MessagesState, START

def call_model(state: MessagesState):
system_msg = {"role": "system", "content": "你是一个简洁的编程助手。"}
messages = [system_msg] + state["messages"]
response = model.invoke(messages)
return {"messages": [response]}

DeepAgents — system_prompt 参数:

1
2
3
4
5
6
7
from deepagents import create_deep_agent

agent = create_deep_agent(
model="openai:gpt-4o",
tools=[my_tool],
system_prompt="你是一个研究助手。把任务拆解为步骤再执行。",
)

最佳实践

  1. 清晰胜于聪明 — 简洁直接的指令优于花哨的措辞
  2. 结构化格式 — 用 XML 标签(<instructions>、<examples>)或 Markdown 标题组织
  3. 恰当的抽象层级 — 不要太模糊(无指导),也不要太具体(变成脆弱的 if-else)
  4. 精选示例 — 少量多样化的典型示例 > 大量边界用例
  5. 最小化起步 — 先写最简单的能用的 Prompt,只在失败时增加指令

局限性

  • 静态 — Prompt 写好就不变了,不会适应新信息
  • 无视上下文 — 不能检索外部数据、管理历史、处理记忆
  • 规模脆弱 — 加更多指令修 Bug → 不可维护的”意大利面条式” Prompt
  • 单轮思维 — 为一次性交互设计,不适合多轮 Agent 工作流

11.3 Context Engineering(上下文工程)

定义

Context Engineering 是设计、策划和交付正确信息的学科 — 在正确的时机、以正确的格式,让 LLM 能可靠地完成任务。

通俗类比:Context 就像”开会前把资料备齐” — 光会交代任务没用,订单、数据、历史记录该给的一份不能少,也一份不能多。

“我更喜欢’上下文工程’这个词,而不是’提示词工程’。它更好地描述了核心技能:为任务提供所有必要的上下文,让 LLM 有可能解决它。”
— Tobi Lütke,Shopify CEO

“上下文工程是在不断演化的信息宇宙中,策划什么进入有限上下文窗口的艺术和科学。”
— Anthropic

关键洞察:大多数 Agent 失败不是模型失败 — 而是上下文失败。模型没收到错误指令;它根本没收到正确的信息。

Prompt Engineering vs Context Engineering

维度 Prompt Engineering Context Engineering
范围 写一段指令文本 管理整个上下文状态 — 系统提示词 + 工具 + 检索数据 + 记忆 + 对话历史
本质 一个静态模板 一个动态系统的输出
思维模式 “写一个更好的 Prompt” “构建一个更好的上下文管道”
时机 一次性 每轮迭代 — 每次调用前都要策划
关注点 用词和措辞 信息质量、工具可用性、交付时机、格式

完整的上下文栈

模型生成响应前看到的所有内容:

graph BT
L1["1. 系统提示词(指令)"]
L2["2. 用户提示词(当前任务)"]
L3["3. 状态/历史(对话记录)"]
L4["4. 长期记忆(用户偏好)"]
L5["5. 检索信息(RAG)"]
L6["6. 可用工具定义(Function Schema)"]
L7["7. 结构化输出约束(JSON Schema)"]

L1 --> L2 --> L3 --> L4 --> L5 --> L6 --> L7

style L1 fill:#e3f2fd
style L2 fill:#e3f2fd
style L3 fill:#fff9c4
style L4 fill:#fff9c4
style L5 fill:#f3e5f5
style L6 fill:#ffebee
style L7 fill:#ffebee

每一层都是一个工程决策 — 包含什么、排除什么、用什么格式。

核心模式

模式一:RAG(检索增强生成)

上下文栈中的一个组件。从文档、数据库或 API 中动态检索外部知识:

1
2
3
4
5
6
7
8
9
10
11
12
13
from langchain_core.vectorstores import InMemoryVectorStore
from langchain_openai import OpenAIEmbeddings

vectorstore = InMemoryVectorStore.from_texts(
["公司 2025 年收入为 5000 万", "产品发布计划在 Q3"],
embedding=OpenAIEmbeddings(),
)

# 调用 LLM 前先检索相关上下文
docs = vectorstore.similarity_search("我们的收入是多少?", k=2)
context = "\n".join([d.page_content for d in docs])

prompt = f"基于以下上下文:\n{context}\n\n回答问题。"

模式二:上下文窗口管理

40% 利用率阈值(Dex Horthy 的发现):

区域 上下文占用率 Agent 行为
聪明区 0-40% 聚焦推理、准确的工具调用、高质量输出
愚蠢区 >40% 更多幻觉、兜圈子、格式混乱、质量下降

LangGraph — 消息裁剪:

1
2
3
4
5
6
7
8
9
10
11
12
13
from langchain_core.messages.utils import trim_messages, count_tokens_approximately

def call_model(state: MessagesState):
messages = trim_messages(
state["messages"],
strategy="last", # 保留最近的 N 个 Token
token_counter=count_tokens_approximately,
max_tokens=4000, # Token 预算
start_on="human", # 确保历史从 human 消息开始
end_on=("human", "tool"), # 确保历史在有效边界结束
)
response = model.invoke(messages)
return {"messages": [response]}

LangGraph — 对话摘要:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from langgraph.graph import MessagesState
from langchain_core.messages import HumanMessage, RemoveMessage

class State(MessagesState):
summary: str

def summarize_conversation(state: State):
summary = state.get("summary", "")
if summary:
summary_message = (
f"当前对话摘要:{summary}\n\n"
"根据以上新消息扩展摘要:"
)
else:
summary_message = "创建以上对话的摘要:"

messages = state["messages"] + [HumanMessage(content=summary_message)]
response = model.invoke(messages)

# 删除旧消息,保留摘要 + 最近 2 条
delete_messages = [RemoveMessage(id=m.id) for m in state["messages"][:-2]]
return {"summary": response.content, "messages": delete_messages}

模式三:即时检索(Just-in-Time Retrieval)

Agent 维护轻量级标识符(文件路径、存储查询、URL),运行时按需加载数据。类似人类认知 — 我们不会记住一切,而是使用索引系统。

1
2
3
4
5
# ❌ 坏做法:把所有文件预加载到系统提示词
system_prompt = f"这是所有项目文件:{all_files}" # 臃肿!

# ✅ 好做法:给 Agent 工具按需检索
# Agent 用 glob/grep 找相关文件,只读需要的部分

模式四:工作记忆 vs 长期记忆

类型 作用域 实现方式 示例
工作记忆 当前对话(会话级) 上下文窗口、检查点状态 当前任务、最近工具结果
长期记忆 跨会话持久化 外部存储、文件系统、向量 DB 用户偏好、项目历史

在 DeepAgents 中的体现

DeepAgents 是上下文工程的最佳实践集合:

1. 上下文压缩(85% 阈值自动触发)

阶段 触发条件 机制
工具结果卸载 工具响应 > 20,000 tokens 完整结果保存到文件系统,替换为文件路径 + 前 10 行预览
工具输入卸载 上下文超过模型窗口 85% 旧的文件写入/编辑工具调用截断,替换为文件系统指针
对话摘要 卸载用尽后仍超阈值 LLM 生成结构化摘要(会话意图 + 产出物 + 下一步);完整历史保留在文件系统中
1
2
3
4
5
6
7
8
# DeepAgents 内置,无需手动配置
from deepagents import create_deep_agent

agent = create_deep_agent(
model="openai:gpt-4o",
tools=[my_tool],
# 上下文压缩自动运行,无需任何配置
)

2. write_todos 规划上下文

write_todos 工具把复杂任务拆解为可追踪的子任务。它同时服务于规划和上下文持久化 — 待办列表作为结构化工作记忆,在上下文压缩后仍能存活。

3. 文件系统后端扩展上下文

文件系统同时充当持久存储和上下文管理 — 大输出保存到文件而非占用上下文,Agent 可以按需重新读取。

4. 子 Agent 隔离上下文

task 工具委派工作给具有隔离上下文窗口的子 Agent — 它们不共享父 Agent 的对话历史,防止上下文污染。每个子 Agent 只返回浓缩的摘要。

5. 五类上下文总览

上下文类型 控制方 作用范围
输入上下文 开发者 系统提示词、记忆、技能(启动时加载)
运行时上下文 调用者 用户元数据、API Key(每次 invoke 传入)
上下文压缩 框架自动 大内容卸载 + 历史摘要(到达阈值时触发)
上下文隔离 子 Agent 每个子 Agent 独立上下文,不污染主 Agent
长期记忆 开发者 + 框架 跨会话持久化存储

11.4 Harness Engineering(线束工程)

定义

Harness Engineering 是为 LLM 构建基础设施、工具和编排层的工程,使其达到生产可用级别。

通俗类比:Harness 就是”给新员工配好的整个办公环境” — 工位、电脑、门禁、监控、应急预案,让他干活既顺手又闯不了祸。

核心公式:Agent = Model + Harness

模型只是一个 text-in/text-out 的函数。Harness 是其他一切 — 系统提示词、工具调用、文件系统、沙箱环境、编排逻辑、中间件、反馈循环、约束机制、错误恢复。

类比:Model = CPU,Harness = 操作系统。再强的芯片配一个崩溃频发的操作系统,体验也不如老芯片配稳定系统。

“模型决定天花板,Harness 决定地板。与其纠结选哪个模型,不如先把 Harness 做好。”

模型不能做什么 → Harness 必须补偿什么

模型不能做 Harness 如何补偿 对应组件
记住多轮历史 维护并注入历史 记忆系统
执行代码或运行命令 提供 Bash + 执行环境 通用执行
获取实时信息 搜索、MCP 工具 外部知识
操纵文件和环境 文件系统抽象 + Git 文件系统
知道自己做得对不对 沙箱 + 测试工具 + 浏览器自动化 验证循环
长任务中保持一致 上下文压缩、记忆文件、进度追踪 上下文管理

六层架构

flowchart TD
L1["L1 信息边界<br/>Agent 该/不该知道什么<br/>━━━━━━━━━━<br/>岗位描述 — 关注什么"]
L2["L2 工具系统<br/>Agent 如何与外部世界交互<br/>━━━━━━━━━━<br/>办公工具 — 用什么工作"]
L3["L3 执行编排<br/>如何串联多步任务<br/>━━━━━━━━━━<br/>标准操作流程 — 按什么步骤"]
L4["L4 记忆与状态<br/>如何管理中间结果<br/>━━━━━━━━━━<br/>项目管理 — 如何记住做过的事"]
L5["L5 评估与可观测性<br/>Agent 如何知道自己做得对<br/>━━━━━━━━━━<br/>质检流程 — 如何验证正确性"]
L6["L6 约束、验证与恢复<br/>出错了怎么办<br/>━━━━━━━━━━<br/>红线和应急预案 — 绝不能发生"]

L1 --> L2 --> L3 --> L4 --> L5 --> L6

style L1 fill:#e3f2fd
style L2 fill:#e3f2fd
style L3 fill:#fff9c4
style L4 fill:#fff9c4
style L5 fill:#f3e5f5
style L6 fill:#ffebee
层级 名称 解决的问题 关键设计
L1 信息边界 Agent 该/不该知道什么 定义角色和目标、裁剪无关信息、结构化组织任务状态
L2 工具系统 Agent 如何与外部世界交互 工具选择、调用时机、结果精炼与反馈
L3 执行编排 如何串联多步任务 遵循”理解→判断→分析→生成→检查”循环
L4 记忆与状态 如何管理中间结果 当前任务状态、中间产物、长期记忆
L5 评估与可观测性 Agent 如何知道自己做得对 独立于生成过程的验证
L6 约束、验证与恢复 出错了怎么办 错误拦截、重试、失败回滚

类比新员工入职:

  • L1 = 岗位描述(关注什么)
  • L2 = 办公工具(用什么工作)
  • L3 = 标准操作流程(按什么步骤)
  • L4 = 项目管理系统和笔记本(如何记住做过的事)
  • L5 = 质检流程(如何验证正确性)
  • L6 = 红线和应急预案(什么绝不能发生、出了事怎么办)

实操建议:先做 L1(信息边界)和 L6(约束与恢复)— ROI 最高。中间层随复杂度增长再补。

在 DeepAgents 中的体现

create_deep_agent() 本身就是 Harness 的组装器:

1
2
3
4
5
6
7
8
9
10
11
from deepagents import create_deep_agent

agent = create_deep_agent(
model="openai:gpt-4o", # L1: 模型选择
tools=[search_tool, code_tool], # L2: 工具绑定
system_prompt="你是一个研究助手。", # L1: 信息边界
# L3: 执行编排(内置 agent 循环)
# L4: 记忆与状态(文件系统后端 + write_todos)
# L5: 评估(工具结果验证、结构化输出)
# L6: 错误处理(沙箱、权限系统、重试)
)

DeepAgents 的 Harness 组件与六层对应:

组件 Harness 层级 说明
create_deep_agent 配置 L1, L3 模型选择、系统提示词、编排循环
工具绑定 L2 预配置工具(文件系统、Shell、搜索、子 Agent)
权限系统 L6 沙箱隔离、工具级访问控制
中间件 L3, L6 上下文压缩中间件在 Agent 轮次间运行
结构化输出 L5 工具返回结构化、已验证的数据
write_todos L4 规划和进度追踪
task(子 Agent) L3, L4 任务委派与上下文隔离
自动摘要 L4, L6 防止上下文溢出
文件系统后端 L4 超出上下文窗口的持久存储
HITL 中断 L6 敏感操作的人类审批

在 LangGraph 中的体现

LangGraph 提供了构建 Harness 的底层原语:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.prebuilt import ToolNode
from langgraph.checkpoint.memory import InMemorySaver

# L3: 执行编排
builder = StateGraph(MessagesState)
builder.add_node("agent", call_model)
builder.add_node("tools", ToolNode(tools))
builder.add_edge(START, "agent")
builder.add_conditional_edges("agent", should_continue, {"continue": "tools", "end": END})
builder.add_edge("tools", "agent")

# L4: 状态持久化
checkpointer = InMemorySaver() # 生产用 PostgresSaver
graph = builder.compile(checkpointer=checkpointer)

# L6: 人类审批护栏
graph = builder.compile(
checkpointer=InMemorySaver(),
interrupt_before=["tools"], # 工具执行前暂停
)

实证:瓶颈在 Harness,不在模型

来源 只改了什么 结果
Can.ac 实验 同一个模型,只改工具调用接口格式 得分 6.7% → 68.3%(10 倍提升,模型完全没换)
LangChain Terminal Bench 2.0 优化 Agent 运行时(文档组织、验证循环、追踪) 排名 #30 → #5,得分 52.8% → 66.5%(模型完全没换)

11.5 Agent Loop Engineering(循环工程)

定义

Agent Loop Engineering(循环工程)是设计”自动闭环系统”的学科:给 Agent 一个带验收标准的目标,让它自己”干活 → 检查 → 发现问题 → 调整 → 再干“,循环往复,直到任务真正达标 — 全程不需要人盯。

通俗类比:你请了一位厨师,只说一句”做一道咸淡适中的菜”(目标)。他炒两下尝一口(行动 + 观察),淡了加点盐再炒(调整 + 行动),再尝……直到你说”就是这个味”(达标终止)。你从头到尾只说了一句话,剩下的他自己闭环。

关键转变:开发者的角色从”司机”变成”自动驾驶系统设计师” — 不再一句一句地发提示词,而是设计一套能自我驱动、自我校验、自我纠正的循环系统。

这个热词背后有两面旗帜:

  • Simon Willison(2025,《Designing agentic loops》)给”智能体循环”正名:“Agent 就是在循环里使用工具的 LLM,真正的技能是精心设计工具和循环。”
  • Addy Osmani(Google Cloud AI 总监,2026)正式提出 Loop Engineering,把它定位为 Prompt / Context / Harness 之上的第四层:“开发者设定意图,AI 持续迭代直至任务完成。”

核心循环:一套四步节奏

所有 Agent 循环都是同一个节奏 — 定目标 → 干活 → 看结果 → 调整再来:

flowchart TD
G["🎯 目标 Goal<br/>带可验证的验收标准<br/>'单元测试全部通过'"]
A["🔨 行动 Action<br/>调用工具干活<br/>写代码 / 查数据库 / 改配置"]
O["👀 观察 Observation<br/>客观检查结果<br/>跑测试 / 看报错 / 核对数据"]
J{"达标了吗?"}

G --> A --> O --> J
J -->|✅ 达标| E["🏁 结束,交付"]
J -->|❌ 未达标| ADJ["🔧 调整策略<br/>换方法 / 补信息 / 修复问题"]
ADJ -->|记住教训,再来一轮| A

style G fill:#e3f2fd
style A fill:#fff9c4
style O fill:#f3e5f5
style J fill:#ffebee
style E fill:#e8f5e9
style ADJ fill:#ffe0b2

三个容易忽略的细节:

  1. 停止条件必须可验证 — “把网站弄快一点”是模糊的;”当首页加载 < 1 秒且测试全绿时停止”才能让循环知道自己该停
  2. 每轮都要有客观验证 — 自动化测试就是 Agent 的”神经系统”,没有它,循环就是闭着眼睛开枪
  3. 调整要基于观察 — 把”试过什么、结果如何”记下来,别在同一个坑里反复摔

五大核心组件

组件 干什么 通俗类比
自动触发 任务从哪来:用户一句话 / 定时任务 / 报错自动触发 闹钟一响自动开工
任务执行 拆任务、调工具干活(复用前三层的能力) 埋头干活
质量校验 用客观标准检查干得对不对 质检员验货
自主决策 决定下一步:继续 / 换方法 / 叫人 自己拿主意
迭代与记忆 记住试过什么、学到什么,不重复犯错 错题本

设计循环的四个灵魂拷问

动手设计循环前,先回答这四个问题(它们决定循环是”良性自驱”还是”烧钱永动机”):

灵魂拷问 没答好的后果 正确姿势
1. 怎么算”完成”? Agent 干到天荒地老 / 提前摆烂 停止条件可验证:测试全绿、数据对上、文件生成
2. 干错了怎么发现? 错误一路滚雪球 每轮客观验证,不信 Agent 的”自我感觉”
3. 什么时候重试,什么时候认输? 无限重试风暴 有界重试(如最多 3 次)+ 失败升级人工
4. 成本怎么封顶? 卡住的 Agent 烧穿预算 最大轮数 / token 上限 / 花费上限

Loop vs Harness:最容易混淆的一对

一句话区分:Harness 让”一次运行”可靠,Loop 让”整个任务”自动闭环。

维度 Harness Engineering Loop Engineering
回答的问题 一次调用怎么不出错 整个任务怎么自动干完
时间尺度 单次任务执行 跨多轮迭代,直到达标
人的角色 配置系统、下达明确指令 只设定意图和验收标准,循环自动驱动
典型机制 工具、沙箱、权限、重试、监控 触发器、验收测试、有界重试、终止条件、升级人工
失败表现 一次调用崩溃、越权、失控 死循环烧钱、错误放大、虚假完成

适用场景:什么时候值得上 Loop

判断信号(Simon Willison):① 成功标准清晰可判定;② 解决过程需要反复试错。

适合的场景 为什么适合
Debug 修 Bug 跑测试 → 改 → 再跑,测试就是天然的验收标准
性能优化 加索引 → 压测 → 不行再换方案,benchmark 说话
依赖升级 升级 → 跑测试 → 修 breaking change,测试兜底
定时巡检 / 自动化运维 报错自动触发 → 修复 → 验证 → 记录归档
批量重复任务 批量重构、批量迁移,逐个改、逐个验

不适合的场景:目标模糊、没有客观验收标准的任务。比如”帮我写一篇有创意的文章” — “创意”没法自动判定,循环只会空转烧钱。

代价与风险

风险 表现 对策
无限循环烧钱 反复重试不收敛,token 账单爆炸 最大轮数、token / 花费封顶
错误放大 第一轮错,后面每轮在错误上继续盖楼 每轮独立验证 + 失败早停
虚假完成 Agent 自称”已完成”,实际不达标 客观验收(测试 / 断言 / 评测),不信自述
环境破坏 在真实环境里乱删文件、乱发请求 沙箱隔离、受限凭证、危险操作叫人审批

“An AI agent is an LLM wrecking its environment in a loop.”(AI Agent 就是在循环里破坏环境的 LLM)
— Solomon Hykes(Docker 创始人)— 所以,先给它一个”坏了也不心疼”的沙箱环境。

在 LangGraph / DeepAgents 中的体现

LangGraph — 循环 = 条件边 + 停止条件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.prebuilt import ToolNode

builder = StateGraph(MessagesState)
builder.add_node("agent", call_model)
builder.add_node("tools", ToolNode(tools))
builder.add_edge(START, "agent")

# 循环的核心:agent ↔ tools 来回转,should_continue 决定停不停
builder.add_conditional_edges("agent", should_continue, {"continue": "tools", "end": END})
builder.add_edge("tools", "agent")

graph = builder.compile(checkpointer=InMemorySaver())

# Loop Engineering 三件套:轮数上限 + 危险操作叫人 + 状态可恢复
result = graph.invoke(
{"messages": [{"role": "user", "content": "把所有失败的测试修到全绿"}]},
config={"recursion_limit": 25}, # 轮数上限:防死循环烧钱
)

DeepAgents — create_deep_agent 内置循环引擎:

1
2
3
4
5
6
7
8
agent = create_deep_agent(
model="openai:gpt-4o",
tools=[run_tests, fix_code],
system_prompt="""你是负责修复测试的工程师。
循环:跑测试 → 修一个失败项 → 再跑,直到全部通过。
最多尝试 10 轮;连续 3 轮没有进展就停下,汇总原因并转人工。""",
interrupt_on={"run_deploy": True}, # 危险操作:暂停叫人审批
)

注意:写在 system_prompt 里的停止条件只是”软约束“,recursion_limit、轮数上限、权限系统才是”硬约束“ — 软约束管行为,硬约束保性命,两个都要有。

局限性

  • 依赖客观验收标准 — 没有可自动判定的”完成标准”,循环就无法可靠终止
  • 成本更高 — 多轮迭代意味着更多 token 消耗,适合高价值任务,别为省一次 API 调用而上循环
  • 不是替代,是叠加 — 循环内部跑的仍是前三层:Prompt 写指令、Context 喂信息、Harness 保运行。Loop 只是把”跑一圈”变成”自动跑到达标为止”

11.6 四大范式如何协同工作

以构建客服 Agent为例:

flowchart TD
subgraph PE["Layer 1 — Prompt Engineering"]
    P1["系统提示词定义"]
    P2["'你是一个有帮助的客服代表<br/>回复要简洁且共情<br/>如果用户问账单问题<br/>先要他们的账户 ID'"]
    P1 --> P2
end

subgraph CE["Layer 2 — Context Engineering"]
    C1["从数据库检索用户最近的订单"]
    C2["加载用户账户历史到上下文"]
    C3["搜索知识库中的相关 FAQ"]
    C4["裁剪对话历史以适应上下文窗口"]
    C5["对话过长时进行摘要"]
    C1 --> C2 --> C3 --> C4 --> C5
end

subgraph HE["Layer 3 — Harness Engineering"]
    H1["工具列表:<br/>lookup_order / process_refund / escalate_to_human"]
    H2["Checkpointer 持久化状态"]
    H3["interrupt_before=process_refund<br/>人类审批"]
    H4["错误处理:<br/>API 超时重试,降级到转人工"]
    H5["可观测性:<br/>记录每次工具调用,追踪解决率"]
    H6["限流:<br/>每会话最多 5 次退款尝试"]
    H1 --> H2 --> H3 --> H4 --> H5 --> H6
end

subgraph LE["Layer 4 — Agent Loop Engineering"]
    L1["自动触发:用户消息 / 工单进入即开工"]
    L2["每轮回答后自动质检:<br/>问题真的解决了吗?"]
    L3["未解决 → 自动补充信息再试一轮"]
    L4["有界重试:最多 3 轮<br/>仍失败 → 升级人工 + 记录教训"]
    L1 --> L2 --> L3 --> L4
end

PE --> CE --> HE --> LE

style PE fill:#e3f2fd
style CE fill:#fff9c4
style HE fill:#f3e5f5
style LE fill:#e8f5e9

四层各管一件事:Prompt 决定 Agent 怎么说话,Context 决定它知道多少,Harness 决定它闯不闯祸,Loop 决定它能不能不用你盯、自己干到完。

成熟度模型

flowchart LR
subgraph L0["Level 0<br/>无 Harness"]
    L0D["直接 Prompt 到 Agent<br/>无结构约束"]
end

subgraph L1["Level 1<br/>基础约束"]
    L1D["AGENTS.md + 基础检查<br/>+ 手动测试"]
end

subgraph L2["Level 2<br/>反馈循环"]
    L2D["CI/CD + 自动测试<br/>+ 进度追踪"]
end

subgraph L3["Level 3<br/>专业 Agent"]
    L3D["多 Agent 分工<br/>+ 分层上下文<br/>+ 持久记忆"]
end

subgraph L4["Level 4<br/>自主循环"]
    L4D["无人值守并行<br/>+ 自动熵管理<br/>+ 自愈"]
end

L0 -->|添加约束| L1
L1 -->|自动化| L2
L2 -->|多Agent| L3
L3 -->|自治化| L4

style L0 fill:#ffebee
style L1 fill:#fff9c4
style L2 fill:#e3f2fd
style L3 fill:#f3e5f5
style L4 fill:#e8f5e9
阶段 特征 工程师角色
Level 0:无 Harness 直接 Prompt 到 Agent,无结构约束 手动编码 + 偶尔 AI 辅助
Level 1:基础约束 AGENTS.md + 基础检查 + 手动测试 主要编码,AI 辅助
Level 2:反馈循环 CI/CD + 自动测试 + 进度追踪 规划 + 审查为主
Level 3:专业 Agent 多 Agent 分工 + 分层上下文 + 持久记忆 环境设计 + 管理
Level 4:自主循环 无人值守并行 + 自动熵管理 + 自愈 — Loop Engineering 的完全体 架构师 + 质量守门人

11.7 在你的代码中如何体现

Prompt Engineering 的代码体现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 1. system_prompt 参数 — 最直接的 Prompt Engineering
agent = create_deep_agent(
model="openai:gpt-4o",
system_prompt="""你是一个 SQL 分析师。
工作流程:
1. 先用 list_tables 查看可用表
2. 用 get_table_schema 了解表结构
3. 编写 SQL 查询
4. 解释结果

注意:只允许 SELECT 语句,禁止 DDL/DML 操作。""",
)

# 2. 工具描述 — 另一种 Prompt Engineering
@tool
def search_database(query: str) -> str:
"""在数据库中搜索相关信息。

参数:
query: SQL 查询语句,仅支持 SELECT

返回:查询结果的 JSON 字符串
"""
...

Context Engineering 的代码体现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 1. 记忆配置 — 始终加载的上下文
agent = create_deep_agent(
model="openai:gpt-4o",
memory=["/project/AGENTS.md"], # 每次都注入系统提示词
)

# 2. 技能配置 — 按需加载的上下文(渐进式披露)
agent = create_deep_agent(
model="openai:gpt-4o",
skills=["/skills/sql-analyst/", "/skills/report-writer/"],
)

# 3. 上下文压缩 — 自动管理
# 内置 85% 阈值压缩,无需代码

# 4. 子 Agent 隔离 — 结构化上下文
researcher = {
"name": "researcher",
"system_prompt": "返回简洁摘要,不超过 500 字。", # 控制输出上下文量
}
agent = create_deep_agent(
model="openai:gpt-4o",
subagents=[researcher],
)

# 5. 运行时上下文 — 调用时注入
from dataclasses import dataclass

@dataclass
class AppContext:
user_id: str
department: str
permissions: list

result = agent.invoke(
{"messages": [{"role": "user", "content": "查看销售数据"}]},
context=AppContext(user_id="u123", department="sales", permissions=["read"]),
)

Harness Engineering 的代码体现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# 1. 权限控制 — L6 约束
from deepagents import FilesystemPermission

agent = create_deep_agent(
model="openai:gpt-4o",
permissions=[
FilesystemPermission(operations=["write"], paths=["/secrets/**"], mode="deny"),
FilesystemPermission(operations=["read", "write"], paths=["/workspace/**"], mode="allow"),
],
)

# 2. 人类审批 — L6 安全护栏
agent = create_deep_agent(
model="openai:gpt-4o",
interrupt_on={"delete_file": True, "send_email": True},
checkpointer=InMemorySaver(),
)

# 3. 结构化输出 — L5 验证
from pydantic import BaseModel, Field

class SQLResult(BaseModel):
query: str = Field(description="执行的 SQL 语句")
row_count: int = Field(description="返回行数")
data: list = Field(description="查询结果")

agent = create_deep_agent(
model="openai:gpt-4o",
response_format=SQLResult, # 强制结构化输出
)

# 4. 中间件 — L3/L6 横切关注点
from langchain.agents.middleware import wrap_tool_call

@wrap_tool_call
def log_and_validate(request, handler):
"""日志 + 校验中间件"""
print(f"工具调用:{request.name},参数:{request.args}")
result = handler(request)
print(f"调用完成")
return result

agent = create_deep_agent(
model="openai:gpt-4o",
middleware=[log_and_validate],
)

# 5. 后端选择 — L4 状态管理
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend

agent = create_deep_agent(
model="openai:gpt-4o",
backend=CompositeBackend(
default=StateBackend(), # 临时文件放内存
routes={"/memories/": StoreBackend()}, # 记忆持久化
),
)

Loop Engineering 的代码体现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 1. 轮数上限 — 循环的"刹车"(LangGraph)
result = graph.invoke(
{"messages": [{"role": "user", "content": "把失败的测试修到全绿"}]},
config={"recursion_limit": 25}, # 最多 25 步,防死循环烧钱
)

# 2. 有界重试 + 升级人工 — 循环的"止损"
agent = create_deep_agent(
model="openai:gpt-4o",
system_prompt="""最多重试 3 次;3 次仍失败就停下,
汇总已尝试的方案和失败原因,转交人工处理。""",
interrupt_on={"delete_file": True, "send_email": True}, # 危险动作暂停叫人
)

# 3. 自动触发 — 循环的"闹钟"(外部调度:cron / CI / 报错钩子)
# 每天凌晨 2 点定时拉起 Agent 巡检:查报错 → 修复 → 验证 → 记录

11.8 何时需要哪一层

场景 只需 Prompt 需要 Context 需要 Harness 需要 Loop
单轮问答 ✅
简单分类 ✅
文本转换 ✅
多轮对话 ✅
RAG/知识依赖 ✅
需要用户记忆 ✅
超长文档 ✅
生产部署 ✅
错误恢复和重试 ✅
安全护栏 ✅
Debug / 性能优化等试错任务 ✅ ✅
定时巡检 / 自动化运维 ✅ ✅
批量重复任务(升级、重构) ✅ ✅
无人值守长任务 ✅ ✅

核心原则:

  1. Prompt Engineering 是必要但不充分的 — 它是基础,但无法应对动态信息需求和生产问题
  2. Context Engineering 是新兴学科 — 随着 Agent 能力增强和任务复杂化,管理”什么进入上下文窗口”比”怎么措辞”更重要
  3. Harness Engineering 是生产力的乘数 — 模型决定天花板,Harness 决定地板
  4. Loop Engineering 是”放手”的前提 — 没有可验证的验收标准,就敢让 Agent 自己迭代?那是烧钱的永动机。先有验收,再谈自主
  5. 它们是嵌套的,不是替代的 — 你不会选一个弃其他。你分层构建:写好 Prompt → 构建上下文管道 → 包装生产基础设施 → 设计自动闭环

本章小结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
你的代码里每天都在用这四种工程:

Prompt Engineering:
system_prompt="你是一个..."
@tool 的描述字符串
ChatPromptTemplate.from_messages(...)

Context Engineering:
memory=["/project/AGENTS.md"]
skills=["/skills/sql-analyst/"]
子 Agent 的 system_prompt(控制返回上下文量)
自动上下文压缩(85% 阈值)
RAG 检索

Harness Engineering:
permissions=[FilesystemPermission(...)]
interrupt_on={"delete_file": True}
response_format=SQLResult
middleware=[log_and_validate]
backend=CompositeBackend(...)
checkpointer=InMemorySaver()

Loop Engineering:
config={"recursion_limit": 25} # 轮数上限,防死循环
should_continue 条件边 # 何时继续、何时停
system_prompt 里的验收标准 + 有界重试
interrupt_on / interrupt_before # 干不动了叫人
定时触发(cron / CI)+ 自动验收测试

一句话总结:Prompt Engineering 教你怎么说话,Context Engineering 教你怎么给信息,Harness Engineering 教你怎么让系统不崩溃,Loop Engineering 教你怎么让它自己干到完。四层嵌套,缺一不可。