尼恩说在前面

在45岁老架构师尼恩的读者交流群(50+人)里,最近不少小伙伴拿到了阿里、滴滴、极兔、有赞、希音、百度、字节、网易、美团这些一线大厂的面试入场券,恭喜各位!

前两天就有个小伙伴面腾讯, 问到 **“ 听说过Harness Agent 吗?你们怎么实现 Harness Agent 的? ”**的场景题 ,小伙伴没有一点概念,导致面试挂了。

小伙伴 没有看过系统化的 答案,回答也不全面 ,so, 面试官不满意 , 面试挂了。

小伙伴找尼恩复盘, 求助尼恩。

通过这个 文章, 这里 尼恩给大家做一下 系统化、体系化的梳理,写一个系列的文章组成 尼恩编著 《Harness 架构与源码 学习圣经》 深入剖析 Harness AI 平台级 架构的 架构思维与 核心源码,使得大家可以充分展示一下大家雄厚的 “技术肌肉”,让面试官爱到 “不能自已、口水直流”

同时,也一并把这个题目以及参考答案,收入咱们的 《尼恩Java面试宝典PDF》V176版本,供后面的小伙伴参考,提升大家的 3高 架构、设计、开发水平。

尼恩编著 《Harness 架构与源码 学习圣经》

第一章: 什么是 Harness架构?2026年AI核心范式解析 : Harness架构与Agent工程化

具体文章: 54k+Star 爆火!AI 框架 新王者 Harness Agent 来了!尼恩 来一次Harness穿透式解读

第二章: Harness架构 与 LangChain、LangGraph 三者联动 的底层逻辑

具体文章: Harness架构 与 LangChain、LangGraph 三者联动 的底层逻辑

第三章: DeerFlow 源码 14层Middleware 源码解析 ,又一个 “洋葱责任链模式” 架构思维 的 经典案例

具体文章: DeerFlow 源码 14层Middleware 源码解析 ,又一个 “洋葱责任链模式” 架构思维 的 经典案例

第四章: LangChain 超底层 四大设计模式 Design Patterns ,架构师 的 必备 内功,毒打面试官

具体文章: LangChain 超底层 四大设计模式 Design Patterns ,架构师 的 必备 内功,毒打面试官

第五章:Harness宏观架构:基于 PPAF 思维 & REPL 思维,完成 Lead-Agent和Sub-Agent深度拆解

具体文章: 第五章:Harness宏观架构:基于 PPAF 思维 & REPL 思维,完成 Lead-Agent和Sub-Agent深度拆解

第六章:Harness宏观架构:DeerFlow 2.0 断点续跑机制 架构设计与实现

具体文章: Harness宏观架构:DeerFlow 2.0 断点续跑机制 架构设计与实现

第七章: Harness 平台实战: 用 DeerFlow 构建 一个企业自己的 Manus 平台( 企业长任务智能体平台)

具体文章: Harness 平台实战: 用 DeerFlow 构建 一个企业自己的 Manus 平台( 企业长任务智能体平台)

第八章: Harness 超牛逼的 三级记忆架构 :字节 Deerflow 上下文+历史分层+事实列表 ! 落地价值 逆天!!

具体文章: Harness 超牛逼的 三级记忆架构 上下文+历史分层+事实列表 ! 落地价值 逆天!!

第九章: Harness 顶级架构:DeerFlow 2.0 沙盒 Sandbox 架构设计、Sandbox 源码深度解析(史上最深 、价值 逆天)

具体文章: Harness 顶级架构:DeerFlow 2.0 沙盒 Sandbox 架构设计、Sandbox 源码深度解析(史上最深 、价值 逆天)

第10章: 顶奢RAG架构之, 必不可少的 RAG评估体系:7大核心指标落地优化,让RAG从Demo走向生产

【RAG评估、RAG度量指标】顶奢RAG架构之, 必不可少的 RAG评估体系:7大核心指标落地优化,让RAG从Demo走向生产 full - 技术自由圈

第11章:Harness架构 :字节 Deerflow 基于LangGraph的生产级Super Agent驾驭层实现 / DeerFlow 2.0 的 lead_agent 任务总调度 架构设计与实现解析

Harness架构 : DeerFlow 2.0 的 lead_agent 任务总调度 架构设计与实现解析

第十二章: Harness 具体应用:AI编程王炸组合:顶级三剑客 OpenSpec 定方向,Superpowers定纪律,Harness定协同

顶级三剑客 OpenSpec 定方向,Superpowers定纪律,Harness定协同

第十三章: Harness 架构哲学和思维:架构思维、架构哲学、设计模式 大拆解、大总结、大提炼

Harness 架构哲学和思维:架构思维、架构哲学、设计模式 大拆解、大总结、大提炼

本文

第十四章: 架构哲学和思维: Harness /ReAct /PlanExec /Reflect /混合范式 的 区别

架构哲学和思维: Harness /ReAct /PlanExec /Reflect /混合范式 的 区别

第十五章: Harness 底层知识: MCP与FC的10大差别?Harness 怎么 用MCP与FC?

Harness 底层知识: MCP与FC的10大差别?Harness 怎么 用MCP与FC?

第16章: 架构天花板 : 字节 Deerflow 基于LangGraph的生产级 Harness 执行层 Sub-Agent 深度拆解

架构天花板 :基于LangGraph的生产级 Harness 执行层 Sub-Agent 深度拆解

第17章: Harness SDK 架构 :DeepAgent 基于LangGraph的生产级Super Agent驾驭层实现

本文

第18章:Harness架构 核心一:断点续跑机制 的 架构设计 与底层源码分析 .

具体文章: 尼恩还在写, 本周发布

第19章:Harness架构 核心二: XXX

具体文章: 尼恩还在写,后续发布

估计有 10章以上,具体请关注技术自由圈。

五、工序四:middleware 责任链的  三段式装配

DeepAgents的Super-Agent 全局调度中枢

SDK Harness架构 :基于LangGraph的生产级Super Agent驾驭层实现 / DeepAgent 的 lead_agent 任务总调度 架构设计与实现解析

尼恩先问一句:做过 Agent项目的CTO、架构师们,你们是不是也踩过这样的坑?

Agent Demo 阶段, MVP版本 跑起来贼溜: 工具调用丝滑、子Agent分工明确,拍着胸脯跟老板说“能上线”;

结果一到生产环境,直接翻车——工具调用乱套,A工具干了B工具的活;子Agent并行跑起来,中间结果互相污染,排查日志查得头皮发麻;更要命的是,换个模型厂商,整个业务层代码全要改,加班到凌晨还搞不定。

尼恩有个cto 级的vip,带团队做智能运维Agent, 就狠狠栽过这跟头。

当时 堆了8个工具、3个子Agent,Demo阶段号称“全自动化运维”,结果上线3天,因为没有统一调度,子Agent嵌套调用导致内存泄漏,直接把服务器搞崩了,损失几十万。

五、工序四:middleware 责任链的  三段式装配

到底哪里出了问题?

不是工具太多。不是子 Agent 太多。

er 是**缺了一个能管住全局的主 Agent,一个在跑起来之前就把所有规则定死的调度中枢。**这就是 Super-Agent 、或者 Lead-Agent。

研究DeepAgents的lead-Agent, 大家一定会有巨大收获:多Agent生产翻车,从来不是工具不够多、模型不够强,而是缺了一个“全局调度中枢”,缺了一套“构建期定死规则、运行期只做执行”的lead-Agent 架构逻辑。

lead-Agent 干了啥:

  • 中间件排什么顺序?

  • 工具该不该裁?

  • 权限规则怎么走?

  • Prompt 按什么顺序拼?

这些都要在构建期一次性定死,不能在运行期改。

DeepAgents 就是这套 Harness 思路的完整落地。 Super-Agent 是它的核心产品,create_deep_agent 是创建 Super-Agent 的唯一入口。

一整套从模型到工具、从中间件到子 Agent、从 Prompt 到权限的全局组装,全塞在这一个函数里。

接下来,尼恩带大家顺着 create_deep_agent,看它怎么从参数一路装到封箱。

一、先搞懂 Super-Agent:DeepAgents 的全局调度中枢

先把这个概念说清楚。

因为"Super-Agent"这名字容易让人误会, 它不是"比普通 Agent 更强"的意思,更不是模型更大、工具更多、Prompt 更长的 Agent。

Super-Agent 是 DeepAgents 的主 Agent,是全局调度中枢。 在 DeepAgents 的多 Agent 体系里,它是唯一的老大。

子 Agent 归它分派,中间件归它编排,工具调用归它决策。它自己就是那个跑在用户面前的 Agent,只不过它底下还管着一群随时待命的子 Agent。

那它和普通 Agent 到底差在哪?

差在它是"先装好再跑"的。

普通 Agent 可能边跑边拼配置,Super-Agent 是 create_deep_agent 这条装配流水线把模型、工具、中间件、子 Agent、权限规则全装好封死后,才交出去跑的。

装好之后,图结构不可变。只能 .invoke() / .stream(),不能改任何东西。

打个比方:Super-Agent 是一辆整车,create_deep_agent 是造它的生产线。生产线负责把发动机(模型)、方向盘(工具)、安全气囊(中间件)、车载导航(子 Agent)全装好、全锁死,然后交钥匙。车开起来之后,你不能边开边换发动机。

子 Agent 归 Super-Agent 分派,中间件归Super-Agent 编排。

Super-Agent / leader-Agent 自己就是那个跑在用户面前的 Agent,只不过它底下还管着一群随时待命的子 Agent。

一、先搞懂 Super-Agent:DeepAgents 的全局调度中枢

具体来说,Super-Agent 扛三件事:

(1) 全局装配:接用户需求,拆任务,分给子 Agent 去并行跑,最后汇总结果

(2) 安全围栏:上下文截断、工具过滤、权限拦截、子 Agent 隔离。这些安全能力不是外挂插件,是生产线装车时就嵌进去的

(3) 子智能体运行:构建期走完装配流水线后,图结构冻结,运行时只能执行不能篡改

Super-Agent 的分层架构思维

create_deep_agent函数 ,把模型、工具、中间件、子Agent、权限规则,所有“零部件”在构建期全部装配好、封死,等到运行期,你只能调用(invoke/stream),想改图编排结构, 门都没有!

这里就藏着第一个经典架构思维——分层架构思维,也是尼恩当年踩坑后最想复盘的点。

Super-Agent把整个Agent的生命周期,清晰地分成了“构建期”和“运行期”两层,彻底解耦:

(1) 构建期:负责“编译配置”——选什么模型、排什么中间件、定什么权限,所有决策都在这一步定死,相当于“生产线装整车”;

(2) 运行期:负责“执行配置”——调用工具、处理任务、返回结果,只做执行,不做任何决策,相当于“开整车”,不能边开边换零件。

分层架构思维

create_deep_agent:Super-Agent 的唯一入口

好,概念说清了。下一个问题:在 DeepAgents 里,怎么造一个 Super-Agent?

Super-Agent 的生命周期,就两个阶段。

构建期把该定的全定死。模型选谁、中间件排什么顺序、工具该不该裁、Prompt 怎么拼,一次性做完。create_deep_agent() 是这个阶段的唯一入口,它一调,到 return 的那一刻,所有决策都冻住了。

运行期只负责跑。拿到 CompiledStateGraph,调 .invoke() / .stream(),图结构碰都不能碰。

说白了,构建期是装车,运行期是开车。装车时装错了,开起来必翻。

先看create_deep_agent()源码。该方法的十七个参数,全塞在一个函数签名里:


# 真实源码:libs/deepagents/deepagents/graph.py
def create_deep_agent(  # noqa: C901, PLR0912, PLR0915
    model: str | BaseChatModel | None = None,
    tools: Sequence[BaseTool | Callable | dict[str, Any]] | None = None,
    *,
    system_prompt: str | SystemMessage | None = None,
    middleware: Sequence[AgentMiddleware] = (),
    subagents: Sequence[SubAgent | CompiledSubAgent | AsyncSubAgent] | None = None,
    skills: list[str] | None = None,
    memory: list[str] | None = None,
    permissions: list[FilesystemPermission] | None = None,
    backend: BackendProtocol | BackendFactory | None = None,
    interrupt_on: dict[str, bool | InterruptOnConfig] | None = None,
    checkpointer: Checkpointer | None = None,
    store: BaseStore | None = None,
    debug: bool = False,
    name: str | None = None,
    cache: BaseCache | None = None,
) -> CompiledStateGraph:

源码中声明了三个 noqa 抑制:C901PLR0912PLR0915

翻译成人话:这函数太复杂了,复杂到代码检查工具都觉得不对劲。但框架作者没选择把它拆散,而是把复杂度全集中到这一个入口里。公有 API 只有一个。

graph.py 里所有内部函数都以 _ 前缀命名,_build_default_model_apply_excluded_middleware,全是流水线内部的工位,不暴露。

这和微服务对外暴露单一端口、内部随意重构是同一套逻辑。入口集中,内部自由。

十七个参数分三层,每层管不同的事

十七个参数看着多,但尼恩把它们捋了一下,其实就三层。每层管不同的事:

第一层,一等公民。 modelbackendmiddlewaresubagents 这四个,定义了 Agent 是什么。

用什么模型推理、文件落在哪、横切逻辑怎么搞、子 Agent 委派给谁。缺任何一个,Agent 的形态就变了。

第二层,治理开关。 skillsmemorypermissionsinterrupt_on 这四个,控制 Agent 被管到多紧。

不传也能跑,但等于把缰绳全放了。

  • skills 不设,技能只能靠 Prompt 硬塞,回回手写。
  • memory 不开,每次对话从零开始,记不住任何东西。
  • permissions 不配,read_filerm -rf 同级权限,删库跟读文件一样没门槛。
  • interrupt_on 不挂,高风险操作没有审批刹车。

第三层,运行时基础设施。 system_prompt 是用户自定义指令,checkpointer 管会话持久化,store 做跨会话的长期存储,debug 开调试日志。

这些全是 LangGraph 原生的能力,DeepAgents 不包装,不重命名,不藏参数。你传什么,它直接透给 create_agent()

三层合在一起,就是 之前 Harness 工程方案里说的六大闭环:行为闭环靠 middleware,状态闭环靠 checkpointer,经验闭环靠 skills + memory,行动闭环靠 permissions,输入闭环靠 interrupt_on,质量闭环靠 metadata。全部在构建期锁死。

这里涉及的架构思维 关注点分离的思想

把 Agent 的 “骨架”(核心参数)、“安全护栏”(治理参数)、“辅助设施”(运行参数)分开管理,避免参数混乱、职责交叉 。

十七个参数分三层,每层管不同的事

* 这个符号的含义

有个细节很容易被扫过去:tools 参数后面那个孤零零的 *

这符号是 Python 的 keyword-only 分隔符。意思很重:它右边的所有参数,调用时必须写出名字。

所以你写不出 create_deep_agent(model, tools, "my prompt"),必须老老实实写 create_deep_agent(model, tools, system_prompt="my prompt")

尼恩觉得这是整条流水线最精髓的设计。普通框架关心"参数够不够",Harness 关心"参数意图清不清晰"。每条参数在调用点都带名字,不可误读。

这是代码级的确定性约束。

零配置就能跑

model=None 不报错。框架自己补一个 ChatAnthropic(model_name="claude-sonnet-4-6")

backend 不传,那就走 StateBackend()。设个 ANTHROPIC_API_KEY,其他啥都不用配,Agent 就能跑起来。

尼恩提示:原文3w字以上, 超过平台限制, 此处省略 1000字,具体请参考 免费pdf。

完整版本,请参考 尼恩 免费百度网盘 免费pdf ,点赞收藏本文后,截图 找尼恩获取

隐含设计理念: 约定优于配置(Convention over Configuration)

“零配置就能跑” 的设计的是典型体现:model=None、backend 不传时,框架自动补默认值,不用开发者手动配置,只需要设个 ANTHROPIC_API_KEY 就能运行。

这是生产级框架的实用设计,核心是 “减少手动配置,默认约定合理规则”,降低使用门槛,

尼恩提到 “第一次用的时候都惊了:居然能这么简单”,就是被这种设计打动 —— 不用纠结配置细节,专注业务本身。

隐含设计理念:**约定优于配置(Convention over Configuration)**

最后一步:LangChain Agent 创建

装配流水线走完,调 create_agent(...),把模型、工具、中间件、system_prompt 全打进去:


# 真实源码:libs/deepagents/deepagents/graph.py
return create_agent(
    model, system_prompt=final_system_prompt, tools=_tools,
    middleware=deepagent_middleware, ...
).with_config({
    "recursion_limit": 9_999,
    "metadata": {
        "ls_integration": "deepagents",
        "versions": {"deepagents": __version__},
    },
})

这一步就是创建了 Super-Agent 实例,之后只能 .invoke() / .stream(),图结构碰都不能碰。

说白了,create_deep_agent 不推理,不调模型,不跑业务逻辑。它就是一条流水线。把车装好,锁死,交钥匙。

那这条流水线到底串了哪些工序?具体来说,五道:

(1) 模型解析:不管你传字符串还是模型实例,统一转成可用的模型对象

(2) Profile 匹配:根据配置锁定行为策略,同一个配置出同样的行为

(3) 子 Agent 编译:把子 Agent 也编进图里,提前冻死,运行时不再改

(4) 中间件装配:按固定顺序装好所有中间件,顺序定了,行为就定了

(5) Prompt 拼装:把系统提示词按三段顺序拼好,顺序对了缓存才能命中

下面一道一道拆开看。

最后一步:LangChain Agent 创建

尼恩提示:原文3w字以上, 超过平台限制, 此处省略 1000字,具体请参考 免费pdf。

完整版本,请参考 尼恩 免费百度网盘 免费pdf ,点赞收藏本文后,截图 找尼恩获取

二、工序一:模型解析,统一模型入口,换模型不污染业务层

你可能觉得"统一模型入口"这种事太基础,不值一提。

但尼恩翻过不少生产级代码库,模型实例化逻辑散落三四处是常态。

这道工序解决的,就是这个脏活。

model 参数能接三种形式:Nonestr 字符串、BaseChatModel 实例。

三种形式,背后是三条完全不同的处理路径。但对外,只有一种输出

二、工序一:模型解析,统一模型入口,换模型不污染业务层

Mermaid

翻译成人话:

(1) 不传 model:框架自己补一个默认的 ChatAnthropic(model_name="claude-sonnet-4-6")。设个 ANTHROPIC_API_KEY 就能跑,约定优于配置

(2) 传字符串:比如 "claude-sonnet-4-6",先查 ProviderProfile 注册表合并参数,再调 init_chat_model() 实例化。这是最复杂的一条路径

(3) 传现成实例:你传什么它用什么,原样返回,不经过任何 Profile 系统

三条入,一条出。后续所有工序只认 BaseChatModel,不关心它是怎么来的。

三、工序二 HarnessProfile——管行为策略,不与模型配置耦合

模型知道用哪个了。

但光知道用哪个不够,还得告诉它"怎么跑"。

用什么 Prompt、禁哪些工具、注入哪些中间件,这些都属于行为策略。

DeepAgents 用 HarnessProfile 来管这一层。

每个模型名可以注册一个 Profile,声明该模型专属的行为边界。

构建流程可以根据模型名查注册表,找到匹配的 Profile,提取 Prompt、工具排除列表、中间件注入等配置。

为什么是两组 Profile,不是一组

有人可能会想:把 ProviderProfile 和 HarnessProfile 合在一起不行吗?少一组注册表,少一层概念。

不行。因为两者变动的触发条件完全不同。

换模型时你只关心模型怎么构建,不管行为策略。调行为时你只关心 Agent 怎么跑,不管模型参数。

两组 Profile 各管各的:换模型只动 ProviderProfile,调行为只动 HarnessProfile,改一个不影响另一个。

这和 Harness 工程方案里 Config 分层加载是同一套逻辑。

配置系统不是读个 YAML 那么简单,它决定 Agent 的行为边界——能用哪个模型、能调用哪些工具、Token 预算是多少、是否需要审批。

四、工序三 : Sub-Agent治理,单层委派与隔离机制

多 Agent 系统最怕什么?子任务互相污染,一个崩了拖垮全局。

Harness 工程里拆过 Multi-Agent Delegation 的三大内核:任务拆解与委派、隔离与独立生命周期、状态追踪与弹性容错。

四、工序三 : Sub-Agent治理,单层委派与隔离机制

DeepAgents 的子 Agent 治理就是这三个内核在构建期的落地。下面先讲架构设计,再看源码怎么实现。

架构决策一:单层委派,不是级联嵌套

主 Agent 把子任务分给子 Agent,子 Agent 能不能再把活拆开,丢给孙子 Agent?

DeepAgents 的答案是:不行。Sub-Agent 的 task 工具被直接移除。整个体系只有"主 Agent → 子 Agent"这一层委派关系。

为什么要这么设计?尼恩以前跟团队折腾过递归嵌套的方案,深度一失控就是灾难。上下文窗口被套娃撑爆,内存泄漏查得人头秃。一个子 Agent 卡死,它下面的孙子、曾孙全跟着卡死,排查的时候看日志就像看蜂窝。

单层委派的本质不是约束,是保命。 Super-Agent 和 Sub-Agent 之间只有一层,资源消耗可控,调试路径直线。对主 Agent 来说,调 task 跟调 read_file 没区别,统一的工具调用接口,不搞特殊通道。

架构决策二:上下文隔离,各跑各的

每个子 Agent 启动时只拿到一条 HumanMessage,内容就是 task 工具传进来的任务描述。

主 Agent 的完整对话历史、其他子任务的中间产出、用户最初的聊天上下文,全被挡在门外。

怎么做到的?两道机制。

  • _EXCLUDED_STATE_KEYS 白名单规定哪些主 Agent 状态不能传给子 Agent。
  • PrivateStateAttr 允许子 Agent 拥有主 Agent 不可见的私有状态。
  • 两边隔离,一个崩了不会拖垮另一个。

隔离听上去像信息丢失,其实恰恰相反。让子 Agent 去搜 Python 异步最佳实践,它真需要知道用户之前问没问过天气,或者另一个子 Agent 在不在编译代码吗?不需要。这些杂音只会挤占上下文窗口,冲淡核心指令。

这就逼着 Lead Agent 给子 Agent 的任务 prompt 必须自包含:不依赖历史对话,不依赖其他子任务产出,不依赖之前聊过什么。

要做什么、有什么约束、格式怎么要求、参考什么规则,一次性全塞进一条 prompt 里。

架构决策三:GP Sub-Agent 兜底,不让任何任务裸奔

生产环境总有杂活是现有专业子 Agent 不匹配的,有一默认的通用子 Agent,消化这些杂项任务。

这些活儿堆在主 Agent 的上下文里硬扛,工具越调越多,上下文越来越脏,最后不是 Token 耗尽就是死循环。

所以 DeepAgents 在构建流程里自动塞了一个 通用Sub-Agent(General Purpose),专门消化这些杂项任务。

调用方可以显式关掉,也可以自己定义一个同名子 Agent 覆盖默认。

尼恩提示:原文3w字以上, 超过平台限制, 此处省略 1000字,具体请参考 免费pdf。

完整版本,请参考 尼恩 免费百度网盘 免费pdf ,点赞收藏本文后,截图 找尼恩获取

五、工序四:middleware 责任链的 三段式装配

这是 AI Agent 构建流程中最核心、容错率最低的关键工序。

中间件的执行顺序绝非随意编排,一旦顺序错乱,会直接引发缓存雪崩、权限绕过、审批失效等生产级严重故障。

先明确核心概念:

Agent Loop 每一轮执行「模型推理→工具调用→结果回传」,如同一条标准化流水线;中间件就是流水线上的固定工位,负责拦截请求 / 响应,完成上下文注入、工具裁剪、权限校验等治理逻辑,再传递给下一个节点。

所有中间件串联成管道,执行顺序直接决定治理逻辑的生效顺序

五、工序四:middleware 责任链的  三段式装配

middleware 是 Langgraph 洋葱模式责任链

langchain_core.runnables.middleware 是 LangChain 实现洋葱模式责任链的核心,替代了早期 AgentMiddleware,为模型、Agent、链式任务提供统一的拦截增强能力。

1. 标准执行流程

用户输入 → 中间件栈 → AI模型 → 响应输出

2 中间件四大拦截节点

中间件可在 Agent 生命周期的四个关键阶段介入:

  • before_model:模型调用前执行,用于输入预处理、文本格式化;
  • wrap_model_call:包裹模型调用,动态修改工具列表、模型参数;
  • wrap_tool_call:拦截工具调用,实现权限校验、参数合法性检查;
  • after_model:模型返回后执行,用于输出校验、安全过滤。
3 多中间件执行顺序(洋葱模式:先进后出)

# 定义三个中间件
agent = create_agent(
    model="gpt-4o",
    middleware=[middleware1, middleware2, middleware3],
    tools=[...]
)

完整执行顺序

(1) 启动前:middleware1 → 2 → 3 执行before_agent()

(2) 调模前:middleware1 → 2 → 3 执行before_model()

(3) 调用模型:1→2→3 嵌套执行wrap_model_call(),最终调用模型

(4) 调模后:3 → 2 → 1 逆序执行after_model()

(5) 结束后:3 → 2 → 1 逆序执行after_agent()

六、工序五: 提示词工程 Prompt 三段拼装

DeepAgents 设计:三段式装配 + 洋葱式递归

DeepAgents 结合三段刚性结构洋葱递归执行,兼顾稳定性与拦截能力:

三段式装配伪代码


def process_request(request):
    # 1. Base段:框架基础治理(最先执行)
    for middleware in base_middlewares:
        request = middleware.process(request)
    
    # 2. User段:用户自定义逻辑(中间执行)
    for middleware in user_middlewares:
        request = middleware.process(request)
    
    # 3. Tail段:缓存、记忆、审批(最后执行)
    for middleware in tail_middlewares:
        request = middleware.process(request)
    
    # 核心Agent逻辑
    return core_agent_process(request)

DeepAgents 三段式装配:职责与执行流程

DeepAgents 将中间件强制划分为Base 基础段、User 自定义段、Tail 收尾段,三段顺序不可变更,每一段各司其职:

六、工序五: 提示词工程 Prompt 三段拼装

三段核心职责

(1) Base 段(框架内置,必选)

框架底层治理中间件,包含 TodoList、文件系统、子代理、摘要、工具调用补丁等,是 Agent 运行的基础能力。

(2) User 段(用户自定义,可选)

调用方通过参数传入的个性化中间件,用于业务定制化逻辑,插入位置固定在 Base 与 Tail 之间。

(3) Tail 段(框架内置,必选)

最终治理中间件,负责缓存、记忆、人工审批等收尾逻辑,是请求处理的最后一道关卡。

洋葱式递归 VS Netty 链式
特性 洋葱式递归责任链 Netty 链式责任链
处理逻辑 深度优先递归,先进后出 线性传递,先进先出
执行顺序 请求:A→B→C→处理→C→B→A(逆序收尾) 请求:A→B→C→处理(无逆序)
代码实现 递归 + next () 传递 线性遍历 + 显式调用下一个处理器
代表框架 Koa、Express、LangChain Netty、Spring AOP
适用场景 Web 中间件、Agent 拦截器 网络协议栈、数据流处理

尼恩提示:原文3w字以上, 超过平台限制, 此处省略 1000字,具体请参考 免费pdf。

完整版本,请参考 尼恩 免费百度网盘 免费pdf ,点赞收藏本文后,截图 找尼恩获取

六、工序五: 提示词工程 Prompt 三段拼装

很多人将 Prompt 组装简单视为字符串拼接,顺序似乎无关紧要。

但在 Harness 这类追求性能与成本优化的架构中,Prompt 的组装逻辑直接决定了 Claude 等大模型 Prompt Cache 的命中率——逻辑错了,Token 消耗和响应延迟会显著增加。

核心理念:动静态内容必须分离

优化缓存的核心前提是保持 system prompt的完全静态

Claude 等大模型 的 Prompt Cache 机制基于 system prompt的哈希值。只要它不变,缓存就能命中,后续计算成本大幅降低。

因此,任何动态的、每次请求都可能变化的内容,绝不能混入 system prompt

这引出了 Harness 架构中 Prompt 组装的黄金法则:静态行为定义归于 System Prompt,动态任务指令归于 User Message。

静态 System Prompt 的构建:BASE + SUFFIX

最终的 system prompt由两部分静态内容构成:

内容 性质 目的与说明
BASE SDK 行为纪律 静态核心 定义智能体的核心行为范式,在应用构建期确定后冻结不变。
SUFFIX 模型调优后缀 静态调优 提供最终的行为调优指令,置于末尾以最大化效力。

顺序固定为 BASE → SUFFIX。 这个顺序基于两个原因:

(1) 缓存稳定性:BASE作为恒定前缀,确保了 system prompt哈希值的稳定性,是缓存命中的基石。

(2) 指令效力:研究表明,模型对 system prompt末尾的内容关注度最高。将最重要的调优指令(SUFFIX)放在最接近后续对话历史的位置,能使其发挥最大效力。

其中,BASE段定义了四条不可篡改的工程纪律,将开发共识编译为底层契约:

纪律 核心含义
核心行为 回应简洁直接;遇歧义先澄清;对“怎么做”类问题,遵循“先解释后执行”。
专业客观 准确性优先;敢于并礼貌地纠正错误;避免不必要的情感化表达。
任务流控制 遵循“理解→实现→验证”流程;长任务拆分迭代;失败时先分析原因再重试;仅在真实阻塞时移交人类。
进度同步 执行长任务时必须主动同步进度(已完成什么、下一步做什么)。

六、工序五: 提示词工程 Prompt 三段拼装

动态指令的传递:独立的 User Message

每次请求中变化的用户指令、上下文或具体问题,应作为独立的 user message 发送。

这对应了原文中“USER”段的概念,但它的正确位置不是在 system prompt里,而是在其之后。

正确的数据流结构如下:

Mermaid

正确的 Prompt 工程不是简单的三段拼装,而是严谨的动静态分离。

将静态的行为契约(BASE+SUFFIX)固化到 system prompt中以最大化缓存效益,同时将动态的任务指令(USER)通过 user message传递以实现灵活性,是兼顾性能、成本与控制力的唯一正确路径。

任何将动态内容前置到 system prompt的方案,都会直接破坏缓存机制,导致目标与结果的背离。

七、创建 Super-Agent:LangGraph接管运行期

前面五道工序,模型选好了、中间件排好了、工具裁好了、Prompt 拼好了。

但这些都是散件,还没锁死。

最后一步:调 create_agent(),把所有散件锁进一个不可变的 CompiledStateGraph 里。


# 真实源码:libs/deepagents/deepagents/graph.py
return create_agent(
    model, system_prompt=final_system_prompt, tools=_tools,
    middleware=deepagent_middleware, ...
).with_config({
    "recursion_limit": 9_999,
    "metadata": {
        "ls_integration": "deepagents",
        "versions": {"deepagents": __version__},
    },
})

这一调用完,构建期就彻底结束了。之前所有决策全部冻住——中间件顺序不可改、工具列表不可改、权限规则不可改、Profile 快照不可改。

之后就是 LangGraph 运行时接管:Agent Loop、工具调度、状态更新、流式输出,DeepAgents 不再介入。

有人看到 recursion_limit: 9999 会问:这么大的数字,不是放任模型无限循环吗?

不是。9999 只是兜底的硬上限,防止极端情况下的死循环把进程卡死。

真正的循环退出不靠这个数字,靠中间件按业务逻辑控制:

  • SummarizationMiddleware 在上下文快溢出时触发摘要压缩,把对话缩短;
  • PatchToolCallsMiddleware 检测到无效工具调用直接截断,不让模型在死胡同里绕。

交付这一刻,Harness 工程方案里的六大闭环同时落地。

前面各道工序已经把状态闭环、行动闭环、经验闭环锁死了,交付点最后闭合行为闭环、输入闭环和质量闭环。

八、小结:构建期定死一切决策

Super-Agent 的设计理念就一句话:构建期把所有决策定死,运行期不许改。

五道工序就是五次决策:

  • 模型选哪个,构建期定
  • Prompt 拼什么、工具裁哪些、中间件排什么顺序,构建期定
  • 子 Agent 能看什么、能干什么,构建期定

最后交给 LangGraph,运行期只剩一条确定性链路在跑。

分层架构、依赖倒置两大经典思维,贯穿始终;

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐