墨 禹头像
Agent Scope Java 2.x 系列【15】Harness Engineering(驾驭工程)封面图

Agent Scope Java 2.x 系列【15】Harness Engineering(驾驭工程)

1. Harness Engineering(驾驭工程)

1.1 定义

Harness Engineering(驾驭工程)是 AI 智能体 Agent 时代新一代系统化工程范式,行业标准公式:

Agent = 大模型 Model + Harness 驾驭系统

其中:

  • Model(模型):GPT、Claude、DeepSeek 等大模型,只负责推理、生成、思考(如同千里马);
  • Harness:包裹模型的整套运行控制系统、约束环境、反馈闭环、调度基础设施(马具、跑道、管控规则)。

引用 Anthropic 官方定义:支撑长周期复杂 Agent 稳定运行的外部框架、安全控制结构、任务编排系统。

分为三层体系:

  • 执行 Harness:工具调用、任务拆解、子代理调度(负责干活)
  • 评估 Harness:自动化校验、打分、结果比对(判断对错)
  • 控制 Harness:沙箱隔离、权限、行为白黑名单(划定边界)

1.2 发展历史

2025-11-26,Anthropic 发布《Effective harnesses for long-running agents》,首次在官方技术博客把外部运行系统命名为 Harness,将 Claude Agent SDK 定义为通用 Harness 载体,社区开始零散使用 Agent Harness 词汇,但无统一工程方法论。

2026-02,HashiCorp Mitchell Hashimoto 正式提出 Harness Engineering 完整工程方法论,统一术语、三层架构、迭代哲学,瞬间席卷硅谷与国内 AI 工程圈。

OpenAI 跟进发布《Harness engineering: leveraging Codex in an agent-first world》白皮书,公开 Codex 生产级 Harness 落地流程。

LangChain 创始人、Martin Fowler 等技术权威背书,Harness Engineering 取代 Prompt Engineering 成为生产 Agent 第一工程范式。

2026 Q2, 大量开源框架、评估基准、安全组件集中发布,形成完整生态。


1.3 VS Agent 框架

Agent 开发框架 vs AI Harness 运行框架 对比表:

对比维度Agent框架(LangChain、CrewAI、AutoGen、Vercel AI SDK)AI Harness框架(AgentScope、OpenHarness、DeepAgents、Harbor)
核心定位模块化开发SDK、代码组装工具库受控完整运行时容器、生产驾驭底座
设计目标提供Agent基础原子组件,让开发者自定义流程约束模型行为、保障长任务稳定、安全可落地上线
核心内置能力LLM封装、基础Memory、Tool基类、Chain流程、多Agent通信抽象沙箱隔离、细粒度权限、断点续跑、自动校验反思、人在回路、全链路观测、持久状态快照、故障回滚
安全体系无原生安全防护,沙箱/权限需业务自行编码实现原生多层安全围栏:操作白名单、高危指令拦截、资源配额、数据脱敏、审计日志
灵活自由度极高,循环逻辑、记忆策略、调度方式完全自定义中等,底层运行规则固化,仅支持配置化微调,无法推翻驾驭主循环
依赖层级最底层组装零件,可被Harness封装在内外层运行容器,可内嵌Agent框架作为内部组件
上手方式手写代码拼装Agent每一环,脚手架模式配置驱动为主,少量业务代码,开箱即用具备生产防护
任务适配短流程Prompt任务、实验原型、轻量工具调用长周期复杂任务、代码执行、运维操作、政企/金融高合规场景
多智能体模式仅提供通信与调度抽象,协作规则自己写内置分布式集群、A2A协议、任务委派、批量协同调度能力
迭代评估无内置自动评估体系,需额外集成第三方工具自带评估打分、错误回放、策略对比实验能力
典型产出可二次改造的Agent代码片段、业务逻辑模块可直接部署运行的独立Agent服务实例

1.4 主流开源 Harness 框架

主流开源 AI Harness 框架对比表:

框架名称开发主体原生Harness实现开发语言核心定位Harness核心能力模型兼容性多智能体能力开源协议适用场景
AgentScope阿里通义实验室完整内置HarnessAgent九大子系统Python/Java/TS企业级分布式智能体驾驭运行底座Docker沙箱、Workspace工作区、双层记忆压缩、会话持久、细粒度权限、生命周期钩子、子Agent调度、故障断点续跑、人在回路审批通义、GPT、Claude、DeepSeek、Ollama全兼容Actor分布式集群、超大批量多Agent协同、A2A/MCP协议Apache 2.0政企大规模SRE、数据智能、业务多角色协作、国产化生产部署
OpenHarness(HKU)香港大学数据系统实验室原生轻量化纯Harness运行时Python极简透明学术/自研驾驭底座43+内置工具、多级权限、MEMORY.md持久、流式工具循环、后台任务、基础沙箱隔离所有OpenAI兼容本地/云端模型轻量子Agent集群、任务委派MIT算法研究、自定义深度改造、个人本地代码Agent、轻量工具智能体
DeepAgentsLangChain官方基于LangGraph封装标准Harness层PythonLangChain生态专属生产驾驭壳图状态快照、重试校验、HITL人工拦截、上下文自动裁剪、基础安全围栏、评估回调钩子适配全部LangChain接入模型子Agent嵌套、串行/并行任务编排MIT存量LangChain项目快速生产化改造、通用业务单/多Agent
Harbor Framework学术社区(Terminal-Bench配套)评测专用标准化Harness运行时PythonAgent批量基准评测驾驭平台统一执行管道、变量约束控制、批量打分回放、策略对比实验环境、无业务侵入沙箱通用LLM接口标准化接入仅评测场景轻量化多AgentMITAgent性能对比实验、Harness调参对照、学术基准测试
ClawAegis蚂蚁集团+清华安全增强型Harness插件层(无独立Runtime)Python/Java第三方安全防护Harness组件高危命令拦截、文件操作白名单、数据泄露检测、操作审计日志、无侵入挂载各类Agent框架适配所有主流Agent运行时跟随宿主框架多Agent能力Apache 2.0金融等高合规场景安全加固、现有智能体安全补强

2. AgentScope Harness 架构

2.1 定位

HarnessAgent 是 ReActAgent 的一层薄包装,把长期运行 Agent 必备的工程能力打包进单一 Builder。

裸的 ReActAgent 只解决”一次请求 → 推理 → 工具 → 回复”,Harness 在此基础上回答:

  • 下一轮怎么接着上一轮?
  • 上下文如何保持有界?
  • 多用户如何隔离?
  • 危险操作如何先 review 再执行?
  • 可复用能力如何沉淀?

2.2 核心工作原理

原则一:能力叠加在推理循环的关键时机上,不改写循环。

工作区注入、对话压缩、子 Agent、沙箱、Plan Mode —— 每个能力都通过 Middleware 钩在 ReAct 循环的关键时机上。core 的推理算法本身不动,Harness 只在上面加东西。

原则二:能力之间互不依赖,只通过三个共享对象通信。

共享对象作用生命周期
RuntimeContext本次 call() 的身份信息:sessionId、userId、自定义 extra不持久化,单次调用
工作区(Workspace)文件读写入口,物理落到本机、沙箱还是 KV 存储由配置决定跨调用持久
AgentStateStore跨调用恢复运行时状态跨调用持久,按 (userId, sessionId) 寻址

原则三:内置 Middleware 注册顺序固定,自定义 Middleware 跑在最前面。

Harness 在构建期按固定顺序串起所有内置 Middleware。通过 .middleware(...) 添加的自定义 Middleware 会在 Harness 内置之前执行。


2.3 核心能力一览

每个能力对应一个具体问题,按需在 Builder 上打开:

能力解决的问题Builder 入口
工作区驱动的人格人格 / 知识 / 子 Agent / 技能 / MCP 白名单都以文件形式存在.workspace(path)
状态持久化同 (userId, sessionId) 跨请求、跨进程、跨副本恢复默认开启;.stateStore(...) 替换实现
双层长期记忆长会话中有价值的事实自动沉淀到 MEMORY.md默认开启;.memory(...) 定制
对话压缩保持上下文有界;模型真正溢出时强制重试.compaction(...)
大工具结果卸载超 80K 字符的工具结果落盘 + 占位符,避免撑爆上下文.toolResultEviction(...)
子 Agent 编排委派任务给子 Agent,支持同步/后台,自动反向通知.subagent(...) 或 workspace/subagents/
可插拔文件系统本机 + Shell / 共享存储 / 沙箱,不改代码切换.filesystem(...)
沙箱隔离文件与命令隔离,跨调用恢复,支持多副本部署.filesystem(new DockerFilesystemSpec()...)
计划模式(Plan Mode)只读思考阶段 + HITL 审批退出.enablePlanMode()
技能装配技能来源:Git / Nacos / MySQL / classpath / 工作区.skillRepository(...)
MCP 集成与工具白名单声明式 MCP Server + 工具粒度允许/拒绝workspace/tools.json
Channel 路由会话管理、per-session 并发控制、多 Agent 路由、流式事件agent.channel(...) / GatewayBootstrap

2.4 状态流转

状态分三层,框架自动在层之间搬数据:

第一层:调用内状态

  • AgentState:对话上下文、权限规则、Plan Mode 状态、工具状态
  • RuntimeContext:sessionId、userId、沙箱句柄、extra

第二层:跨调用状态(每次 call() 结束自动写盘,下次自动加载)

  • AgentState 运行时快照 → AgentStateStore(默认 ~/.agentscope/state/<agentId>/)
  • 对话日志 → sessions/<sessionId>.log.jsonl(永不压缩)
  • 子任务记录、沙箱元数据

第三层:长期记忆(跨 Session 累积)

  • memory/YYYY-MM-DD.md:每日只追加
  • 后台节流任务周期性合并到 MEMORY.md
  • MEMORY.md 每轮推理被注入 system prompt

三个关键规律:

  1. System prompt 每轮重新拼,修改 AGENTS.md 或 MEMORY.md 立刻生效,无需重启。
  2. 压缩、记忆提炼、后台维护都由节流闸门控制,不会每轮都跑。
  3. AgentState 由 core 的 ReActAgent + AgentStateStore 自动持久化,Harness 不额外处理。

2.5 自定义 Middleware 注意事项

在 Harness 环境下添加自定义 Middleware 时:

  • 使用 .middleware(...) 注册,自定义 Middleware 会在所有 Harness 内置之前执行。
  • 通过 agent.getRuntimeContext() 读取当前调用的身份信息(userId / sessionId),不要在 Middleware 实例字段中缓存请求级状态。
  • 读写工作区使用 harnessAgent.getWorkspaceManager(),它会按当前文件系统模式(本机 / 沙箱 / 远端)正确路由。直接使用 java.nio.Files 在沙箱或远端模式下会写入错误位置。

3. 快速开始

3.1 依赖

<dependency>
    <groupId>io.agentscope</groupId>
    <artifactId>agentscope</artifactId>
    <version>2.0.0-RC2</version>
</dependency>
<dependency>
    <groupId>io.agentscope</groupId>
    <artifactId>agentscope-harness</artifactId>
    <version>2.0.0-RC2</version>
</dependency>

3.2 最小示例

import io.agentscope.harness.agent.HarnessAgent;
import io.agentscope.core.model.DashScopeChatModel;
import io.agentscope.core.message.*;

// 1. 创建模型
var model = DashScopeChatModel.builder()
    .apiKey(System.getenv("DASHSCOPE_API_KEY"))
    .modelName("qwen-plus")
    .build();

// 2. 构建 HarnessAgent(本地工作区)
var agent = HarnessAgent.builder()
    .name("my-first-agent")
    .model(model)
    .sysPrompt("你是一个有用的 AI 助手,用中文回答。")
    .workspace(Paths.get(".agentscope/workspace"))
    .build();

// 3. 调用
var msg = Msg.builder().role(MsgRole.USER)
    .content(List.of(TextBlock.builder().text("你好,介绍一下你自己").build()))
    .build();

var reply = agent.call(List.of(msg)).block();
System.out.println(reply.getTextContent());

运行后自动创建的目录结构:

.agentscope/workspace/
├── AGENTS.md           ← 你的 sysPrompt 自动写入
├── MEMORY.md           ← 长期记忆(跨会话累积)
├── memory/             ← 日流水账 memory/YYYY-MM-DD.md
├── skills/             ← 技能目录
├── subagents/          ← 子 Agent 声明
├── agents/<id>/sessions/  ← 会话日志
└── plans/              ← Plan Mode 计划文件

3.4 带工具 + 多轮对话

import io.agentscope.core.tool.Toolkit;
import io.agentscope.core.agent.RuntimeContext;

// 注册工具
var weatherTool = new WeatherTool();  // 标注 @Tool 的 Bean
var toolkit = new Toolkit();
toolkit.registerTool(weatherTool);

var agent = HarnessAgent.builder()
    .name("weather-assistant")
    .model(model)
    .toolkit(toolkit)
    .sysPrompt("你是一个天气助手,使用工具回答天气问题。用中文回复。")
    .workspace(Paths.get(".agentscope/workspace/weather"))
    .build();

// 多轮对话
var ctx = RuntimeContext.builder()
    .sessionId("session-001").userId("alice").build();

// 第一轮
agent.call(List.of(userMsg("北京天气")), ctx).block();
// 第二轮 —— 自动从 stateStore 加载上一轮的对话历史
agent.call(List.of(userMsg("上海呢?")), ctx).block();

3.5 三种文件系统模式

// 模式 1:本地文件系统(默认,无需配置)
var agent = HarnessAgent.builder()
    .name("local-agent").model(model)
    .workspace(Paths.get("./my-workspace"))
    .build();

// 模式 2:Docker 沙箱(隔离执行)
var agent = HarnessAgent.builder()
    .name("sandbox-agent").model(model)
    .workspace(Paths.get("./ws"))
    .filesystem(new DockerFilesystemSpec()       // ← 一行切换
        .image("agentscope/sandbox:latest"))
    .isolationScope(IsolationScope.USER)
    .build();

// 模式 3:远程共享存储(多副本)
var agent = HarnessAgent.builder()
    .name("distributed-agent").model(model)
    .workspace(Paths.get("./ws"))
    .filesystem(new RemoteFilesystemSpec(store))  // ← Redis/JDBC 共享
    .distributedStore(RedisDistributedStore.fromJedis(jedis))
    .build();

3.6 技能(Skill)

var agent = HarnessAgent.builder()
    .name("skill-agent")
    .model(model)
    .toolkit(toolkit)
    .workspace(Paths.get("./ws"))
    // 从本地目录加载 skill
    .skillRepository(new FileSystemSkillRepository(Paths.get("./skills")))
    // 从 Git 加载 skill
    .skillRepository(new GitSkillRepository("https://github.com/org/skills.git"))
    .build();

3.7 Spring Boot 完整示例

@Configuration
public class HarnessConfig {

    @Bean
    public Model model() {
        return DashScopeChatModel.builder()
            .apiKey(System.getenv("DASHSCOPE_API_KEY"))
            .modelName("qwen-plus").build();
    }

    @Bean
    public HarnessAgent agent(Model model, WeatherTool weatherTool) {
        Path ws = Paths.get(System.getProperty("user.home"), ".agentscope", "workspace", "demo");
        try { Files.createDirectories(ws); } catch (Exception ignored) {}

        return HarnessAgent.builder()
            .name("demo-agent")
            .model(model)
            .toolkit(registerTools(weatherTool))
            .sysPrompt("你是一个 AI 助手,可以用中文回答,使用工具获取信息。")
            .workspace(ws)
            .build();
    }

    private Toolkit registerTools(WeatherTool weatherTool) {
        Toolkit tk = new Toolkit();
        tk.registerTool(weatherTool);
        return tk;
    }
}

@RestController
@RequestMapping("/agent")
public class AgentController {
    private final HarnessAgent agent;

    @GetMapping("/call")
    public Mono<Map<String, Object>> call(@RequestParam String query,
            @RequestParam(defaultValue = "demo") String uid) {
        var ctx = RuntimeContext.builder()
            .sessionId("s-" + System.currentTimeMillis()).userId(uid).build();
        var msg = Msg.builder().role(USER)
            .content(List.of(TextBlock.builder().text(query).build())).build();
        return agent.call(List.of(msg), ctx)
            .map(r -> Map.of("response", r.getTextContent()));
    }
}

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/qq_43437874/article/details/161999690

文章来源转载

评论

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--