第2节:从Framework到Harness,Agent需要怎样的底层支撑?
Agent Harness 专题
上一节:第1节:开篇,了解Harness
本节:第2节:从Framework到Harness,Agent需要怎样的底层支撑?
下一节:待更新
如果我们不依赖 LangChain、AutoGen 这类框架,一个真正能够稳定运行在工业环境里的原生 Agent,到底应该长什么样?
这一节,我们不从“功能列表”出发,而是从底层工程视角来回答这个问题。
换句话说,我们要讨论的不是“Agent 能做什么”,而是:Agent 为什么总是容易失控,以及我们到底该怎样为它搭一个能长期运行的底层支撑体系。
先拆黑盒:传统 Framework 的架构陷阱
很多传统 Agent Framework 的设计,诞生于 GPT-3 时代。
那个阶段的模型,原生规划能力和工具调用能力还不够强,所以开发者自然会倾向于用“链式调用”或者“DAG 图”来约束模型行为。
于是,我们会看到这样一种典型开发方式:
定义一个“错误分析”节点。
定义一个“搜索方案”节点。
再通过代码配置一条边,规定当分析器输出某类关键词时,任务流向搜索节点。
图 1:传统 Framework 常见的链式或图式编排方式
这套设计,在 demo 阶段看起来很优雅。
但问题在于,真实世界里的任务并不是静态流程图。
排查一个线上问题时,可能会出现这些情况:
工具调用超时了
网络突然抖动了
返回值不是预期格式
模型中途改判,想换一条思路继续查
这时,静态图结构的缺点就暴露出来了。
它最大的毛病,不是复杂,而是“过度预设”和“过度干预”。
一旦真实执行过程偏离了开发者预先设定的路径,框架就很容易直接抛异常,或者把任务卡死在某个节点上。
更糟的是,为了支撑这些节点跳转,框架底层通常会维护一套相当复杂、并且人类很难读懂的隐式状态机。
一旦进入死循环,或者在图的中段发生异常,开发者常常既看不清问题,也插不进手。
这才是很多 Agent Framework 在复杂任务面前显得脆弱的根本原因。
Harness 的核心思路:极简的动态运行时
当下的大模型,已经不再只是一个被动执行指令的“文本补全器”。
它越来越像一个具备自主规划能力的 CPU。
这意味着,我们不再需要像过去那样,用代码死死规定“先执行 A,再执行 B,最后跳到 C”。
我们真正需要做的,是给模型提供三样东西:
当前状态
可用工具
清晰边界
然后把“下一步该做什么”的决策权,交回给模型的实时推理。
基于这个前提,Harness 工程应运而生。
它不再是一个负责定义业务流程的图结构,而是一个极简、动态、可治理的运行时环境。
图 2:Harness 更像一个动态运行时,而不是静态流程图
如果要概括 Harness 带来的变化,我认为至少有三点:
控制反转 业务流程的控制权,不再由代码里的固定节点掌握,而是转移到大模型的实时推理与规划中。代码只负责提供物理能力,不负责规定任务走向。
防线前移 既然模型拥有更大自由,它也就有更大概率犯错,甚至越界。所以,治理工程的重点不再是“怎么编排功能”,而是“怎么把拦截、约束、审批、资源控制放到底层中间件里”。
状态透明 系统不再依赖一堆藏在内存里的图节点变量,而是尽可能把状态收敛到单一、可观察的数据结构里。这样一来,无论是调试、回放,还是中途人工介入,都会简单得多。
my-claw 的工程蓝图
基于上面的思路,my-claw 的项目结构并不追求“花哨”,而是强调分层清晰、职责单一、治理前置。
整个系统可以概括为 4 个核心层:
1. 入口层
这是引擎对外的触角。
它负责接收用户输入,比如终端 CLI,后续也可以对接飞书等外部入口。更关键的是,这一层还承载人工审批、异步回调等机制,确保高风险操作不是“闷头执行”。
2. 核心引擎层
这是整个系统的控制中枢。
它负责驱动 ReAct 循环;旁边的模型适配器负责对接不同大模型,抹平底层 API 差异;而新增的 think 模块,则负责在行动之前强制模型进行一次更慢、更稳的思考。
3. 上下文工程层
这一层,决定了 Agent 能跑多远。
上下文不是“顺手拼一段 prompt”那么简单,它直接关系到模型是否会降智、是否会遗忘、是否能在长任务里维持稳定判断。
4. 工具与执行层
这是模型真正触碰物理世界的地方。
这里挂载着 Bash、文件编辑、读取等能力,也因此成为风险最高的一层。极简工具集让模型拥有足够强的组合能力,而中间件机制则负责牢牢守住大门,拦截危险命令,并在需要时转入人工审批。
图 3:my-claw 的整体工程分层
构建项目代码骨架
当我们把架构图想清楚之后,下一步就不是继续空谈,而是先把项目骨架立起来。
这个骨架不需要一开始就很复杂,但它必须准确反映出系统未来要承载的职责边界。
图 4:项目骨架初始化示意
下面是当前启动类的最小形态:
@SpringBootApplication public class Main { private static final Logger log = LoggerFactory.getLogger(Main.class); public static void main(String[] args) { SpringApplication.run(Main.class, args); log.info("🚀 欢迎来到 my-claw 引擎启动序列"); // TODO 1: 初始化模型 Provider(大脑) // var provider = provider.NewOpenAiProvider(...); // TODO 2: 初始化 Tool Registry(手脚) // var registry = tools.NewRegistry(); // registry.register(tools.newBashTool()); // TODO 3: 初始化上下文管理器(内存管理器) // var contextManager = context.NewManager(...); // TODO 4: 组装并启动核心 Engine(操作系统心脏) // var agentEngine = engine.NewAgentEngine(provider, registry, contextManager); // log.info("开始执行任务..."); // var result = agentEngine.run("帮我检查一下当前目录下的文件并输出一个 README.md 大纲"); log.info("架构蓝图搭建完毕,等待各核心模块注入!"); } }这个入口类虽然简单,但它已经明确表达出一个核心思想:
Agent 不是从“写一个 Prompt”开始的,而是从“先搭一个可治理的运行时骨架”开始的。
总结
从 Framework 到 Harness,并不是一次简单的“技术选型切换”。
它更像是一次工程认知的变化:
我们不再试图用静态流程图驯服模型
而是开始为模型搭建一个动态、透明、可约束的运行时环境
当 Agent 真正进入生产环境之后,决定它是否稳定、是否可信、是否可持续演进的,往往不是它“能不能调用多少工具”,而是它背后有没有一套像样的 Harness 工程。
