概述
先交代一下背景。我们团队在做Agent ,Harness是绕不开的一环。2024 年初开始搞这个方向的时候,想法很简单:找个现成的 Agent 框架,接上模型,跑通 RAG,事儿就算起了。
两年过去,框架换了四轮,最后走上了自研的路。
- LangChain4j / SpringAI:
RAG 还行,一上 ReAct 就崩。框架跟不上论文,FC 兼容拉胯,果断弃。 - AgentFlex:
轻量好改,论文落地快,用了一年。但 sandbox、Skill 等新需求单靠改造撑不住。 - Harness 工程包:
参考 OpenClaw 等方案封装承重层,Python/TS 跑通,但 Java 侧缺一块。 - AgentScope 2.0:
功能全但封装厚,上下文压缩拖慢响应,用户体感慢一拍,最终放弃。 - 自研 Harness:
前后端各自实现,核心四个字——按需开关,用哪个开哪个。
如果你也在搞 Agent 框架选型,或者纠结要不要自己动手,往下看过程细节。没有正确答案,只有选择逻辑。
集成效果
集成目前主要是集成在AIPCowork桌面版本还有AIPData数据分析里面。桌面版本是基于ts框架封装的。
TS 版(前端): 运行时零依赖,按需加载对话编排和工具调度模块,复杂多轮交互响应低于 100ms,状态完全透明可控。
Java 版(后端):内核极小,sandbox、记忆、压缩全部插件化,业务场景即插即用,排查问题一条调用链直通底层。
这个是基于数据分析,主要是后台运行。
研发过程
LangChain4j 和 SpringAI,起步就卡住了
2024 年初选型的时候,因为后端是 Java 技术栈,LangChain4j 几乎是第一反应。SpringAI 也拉下来跑过,两个都试了一轮。
说实话,在纯 RAG 场景下,这两个框架都还能用。文档切片、向量检索、提示词拼接、吐回答——这套链路跑通没什么大问题。当时觉得挺顺手,心想 Agent 这事儿好像也没那么复杂。
然后开始上 ReAct。
问题全冒出来了。
第一,框架跟不上论文。 那段时间 Agent 方向的论文出得飞快,ReAct、Plan-and-Execute、Multi-Agent 协作……几乎每个月都有新范式冒出来。但 LangChain4j 和 SpringAI 的迭代节奏明显慢半拍,你看到一篇论文觉得思路很好,回头对着框架文档翻了半天,发现根本没法落地。
要么自己魔改源码,要么干等社区更新。两个选项都不太能接受。
第二,模型差异被忽略了。 不同模型的提示词结构、Function Calling 实现、上下文窗口管理,差异比想象中大得多。框架给你抽象了一层统一的接口,但一跑真实场景就出事——同一个 prompt,GPT-4 跑得好好的,换成国产模型就崩。你没法靠框架的"通用适配"来兜底,最后还是要一个个模型去调。
第三,拼接逻辑定制成本太高。 Agent 的推理链路里,工具调用结果怎么拼回上下文、历史消息怎么裁剪、系统提示词怎么动态注入——这些不是"配置一下就能搞定"的东西。框架给的默认行为跟你的场景对不上,要改就得往源码里钻,改到后面已经分不清是在用框架还是在跟框架打架。
最终让我下决心放弃的,是 Function Calling 的兼容问题。有些模型压根不支持原生的 FC,LangChain4j 的处理方式本质上是在 prompt 里手动拼工具描述,效果很不稳定。问自己一个问题:如果框架连"模型能不能调工具"这件事都没法帮我解决好,那我还要它干嘛?果断弃了。
AgentFlex,改造了一年还是不够用
放弃 LangChain4j 之后,选型标准变了。不再追求"功能全"的框架,而是找"改得动"的。
AgentFlex 就是在这个阶段进来的。它的定位很对胃口——轻量、不绑死模型、架构上留了足够多的扩展点。最关键的是,你能读懂它的源码,改起来不费力。
这一年里我们做了不少事情。ReAct 的实现自己调过好几版,工具调用的链路按自己的场景重新串了一遍,论文里看到有意思的范式——比如 Reflection、Tool Selection 的新思路——都能在 AgentFlex 的基础上快速跑一个原型出来验证。那种"看了一篇论文,两天就能落地测试"的快感,是之前用大框架完全体验不到的。
大概用了快一年。然后框架开始撑不住了。
不是因为 AgentFlex 不够好,而是 Agent 这个领域跑得太快了。一年时间里,我们的需求从"让模型调个 API"进化到了另一件事:sandbox 隔离执行、文档映射和虚拟文件系统、Skill 的动态注册与进化、记忆的多层压缩与检索……
这些不是"在现有框架上改改"就能解决的问题,它需要一套全新的架构来承载。
Harness 架构的需求就是这时候冒出来的。Agent 不再是一个"模型+工具"的简单组合了。它需要一套承重结构——资源怎么隔离、上下文怎么流转、能力怎么热插拔——这些底层的"脚手架"工作,任何单一 Agent 框架都做不好。
还有一个更现实的问题:前端需要自己的 Agent 运行时来处理复杂的多轮对话和 UI 交互,后端 Java 侧要管工具执行和业务编排。AgentFlex 只覆盖了一端,另一端是个空白。前后端都需要 Agent 能力,而且是两套不同语言的实现,单靠改造一个框架做不到。
参考主流方案,封装第一版 Harness
AgentFlex 不够用这件事想清楚之后,我们没急着造轮子。先花了两周时间把市面上几个代表性的项目翻了一遍——OpenClaw、Codex CLI、以及当时刚冒头的 Harness 相关方案。
这几个项目有一个共同点:它们解决的不是"Agent 怎么推理",而是"Agent 跑起来需要什么底座"。sandbox 怎么设计、工具怎么注册和发现、上下文在多个 Agent 之间怎么传递——这些问题的答案,比"用 ReAct 还是 Plan-Execute"重要得多。
参考这些项目的设计思路,我们封装了第一版 Harness 工程包。本质上就是把 Agent 运行所需的基础设施——资源管理、工具总线、上下文管道——抽象成一套可复用的组件。不依赖某个具体的 Agent 实现,只提供"承重层"。
Python 和 TypeScript 版本跑下来效果还不错。轻量、可拆可合、跟业务代码的边界清晰。
但问题卡在了 Java 上。我们的后端服务是 Java 栈,TS 侧的 Harness 已经能跑了,Java 侧却找不到一个合适的对标实现。市面上的 Java Agent 方案要么太重,要么跟 Python/TS 生态的设计思路完全不搭。这意味着后端 Agent 能力跟前面两套 Harness 不在同一个架构体系里——这显然不行。
就是在找 Java 侧方案的时候,阿里正好放出了 AgentScope 2.0。
AgentScope 2.0,什么都有,但就是慢
AgentScope 2.0 刚出来的时候,坦白讲,我是有点兴奋的。
阿里在这件事上想得很全。Agent 编排、多模态支持、记忆管理、sandbox 执行、上下文压缩——基本上你能想到的 Agent 基础设施,它都给你包进去了。而且 Java 侧有完整的 SDK,跟我们的技术栈正好对得上。集成跑通第一版的时候,感觉终于找到了"大一统"方案。
但用了一个月,问题开始冒出来。
第一个问题:封装太厚了。 AgentScope 2.0 的抽象层级很高,一个简单的工具调用链路,背后串了四五层内部处理——协议层、编排层、记忆层、压缩层、执行层。你想搞清楚一个参数是怎么传下去的,得从入口类一路追到最底层。学习成本高是一回事,更难受的是出了问题很难定位。在 AgentFlex 时代你改一行代码就能验证的东西,在这里要先理解一套内部状态机。
第二个问题,也是最终放弃的原因:响应速度。
AgentScope 2.0 在每次交互中都会自动做上下文压缩和记忆处理,这些逻辑在后端默默执行,前端看不到,也控制不了。结果是用户发一条消息,肉眼可见地等两三秒才开始吐字。不是网络延迟,是框架内部的"智能处理"在消耗时间。
办公场景下,这个延迟是致命的。用户不会管你后台在做什么上下文压缩,他只知道"这个 AI 回得好慢"。
还有一个让交互优化很痛苦的点:sandbox 的文件上传。AgentScope 的 sandbox 机制在文件传递链路里做了多层校验和转换,我们试了很多办法去优化这个交互速度,始终达不到能接受的程度。用户在聊天框里拖一个文件进去,等半天才开始处理,这在产品里是没法交代的。
想了很久,结论很简单:一个框架,如果"为了你好"做的事情反而成了体验瓶颈,那说明它的设计目标跟我们的产品目标不在一条线上。放弃了。
自己写,反而简单了
四次选型失败之后,决策变得异常清晰:不再找一个"别人写好的框架",而是把我们已经搞清楚的需求,用最少的代码实现出来。
自研的 Harness 框架分两块:前端 TS 侧和后端 Java 侧。两边共享同一套架构理念,但各自按运行环境的特性独立实现。
核心理念就一句话:按需开关。
什么意思?不同的业务场景,对 Agent 基础设施的需求完全不同。DataHarness 场景需要 sandbox 隔离执行和文件映射,但不需要 Skill 进化。DocHarness 场景需要文档解析管道和虚拟文件系统,但不需要多 Agent 协作。还有一些轻量场景,只需要简单的工具调用链路,连记忆管理都不需要。
以前的思路是"框架提供了什么我就用什么,用不上的也忍着"。自研之后反过来了——我需要什么才挂什么。用不上的模块不编译、不加载、不占资源。一个场景启动一个最小化的 Agent 运行时,几秒钟就绪。
听起来好像工作量很大,但实际上,因为每个模块只做一件事、边界清晰,代码量反而比之前用第三方框架时写的适配层还少。而且出了问题你能一眼看到底——没有黑盒、没有隐藏的状态机、没有"框架替你做了决定"。
总结
两年下来,最大的体会其实和技术选型关系不大。
你用的框架应该是你的工具,而不是你的老板。当一个框架开始替你做产品决策、替你决定用户体验、替你消耗用户的等待时间——不管它的功能列表多长,都应该果断放手。
轻量和可控,比"功能全"重要得多。这也是我们从 LangChain4j 一路走到自研,最核心的判断标准。

