摘要:Harness Engineering 最近很火,但我翻了数十篇文章大部分都在讲它的概念,极少人去讲解它的落地实践。今天这篇文章我将大致讲解什么是 Harness Engineering,并讲解一个采用 Harness Engineering 架构设计、基于 LangChain Deep Agents 框架实现的项目落地核心代码实现,以及我们日常如何将这个概念运用到日常开发中。

三个阶段的演进

  • Prompt Engineering(提示词工程) 主要优化单次交互的质量,重点是"一句提示词该怎么写,模型才更容易给出想要的结果"。

  • Context Engineering(上下文工程) 则动态构建知识、记忆、RAG,解决"模型看什么"的问题,减少幻觉、提高检索命中率。

  • Harness Engineering(驾驭工程) 重点构建整个运行环境,解决"模型怎么把长链路任务稳定做完"的系统级问题。

核心定义

Harness 原意是马具、缰绳。放到 Agent 里,它指除模型本身之外的所有东西——工具、记忆、规划、安全护栏、执行循环、状态管理。LangChain 团队将其精炼为公式:

Agent = Model + Harness

模型提供"思考"能力,Harness 负责"让它真的能干活,而且别出大事"。

传统 Agent 在应对长周期、多步骤任务时,常面临上下文窗口爆炸、状态丢失、工具调用混乱、缺乏规划、无法从失败中恢复等工程难题。Harness Engineering 正是为了解决这些"工程上的’稳’的问题"而生的。模型决定能力的上限,Harness 决定它能不能把能力变成可交付的结果。

DeepAgents 中的七大能力模块

在 DeepAgents 框架中,Harness Engineering 被拆成一组可组合的能力模块:

模块核心能力Harness 价值
Planningwrite_todos 维护结构化任务清单将非结构化思考转为可追踪、可恢复的确定性工作流
Virtual Filesystem读、写、编辑、搜索、执行文件对抗 Context Rot,扩展有效上下文窗口
Subagents主 Agent 委派专项任务给子 Agent上下文隔离 + 算力分配,引入"多线程"和"微服务"架构
Context Management内容卸载、摘要压缩、长期记忆自动执行上下文工程,让模型注意力集中在核心决策
Code Execution沙箱内执行 shell 命令"Trust the LLM"但隔离执行环境
Human-in-the-Loopinterrupt_on 在关键操作前暂停在高风险操作前插入确定性的人工控制点
Skills渐进式披露,按需加载领域知识知识模块化,让 Agent 具备领域专长

五个核心原理

  1. 配置优于编码:所有复杂能力被封装为可配置的中间件栈,通过声明式方式组合,而非编写底层控制流。开箱即用,分钟级定制。(对应第 1~7 节的所有模块配置)
  2. 中间件架构:每个核心能力都是独立的 AgentMiddleware,在 Agent 生命周期的各阶段插入钩子,动态注入工具、修改提示、管理上下文。(对应第 1、3、5 节的 Planning、Subagents、Skills)
  3. 后端协议抽象:统一的 BackendProtocol 抽象了文件存储和执行环境。内存、本地磁盘、云存储还是沙箱,对 Agent 而言都是统一的 lsreadwrite 接口。(对应第 2 节的 Sandbox)
  4. 上下文工程自动化:Harness 自动执行摘要压缩、内容卸载、按需加载等策略,确保模型在任何时刻看到的都是最相关、最精炼的信息。(对应第 6 节的 Context Engineering)
  5. 从智能到系统:通过规划管理目标,通过文件系统管理状态,通过子 Agent 管理复杂度,通过安全沙箱管理风险,通过人在回路管理不确定性。最终,将一个"聪明的对话者"转变为一个"可靠的操作者"。

范式转变

这套思路意味着开发范式的根本转变:

  • 从前:手动编写任务分解逻辑、管理上下文窗口、实现子 Agent 通信、构建安全机制。
  • 现在:通过组合规划、文件系统、子 Agent、上下文管理和人工审批等能力,可以快速搭建具备长任务执行基础的 Agent Harness;真正进入生产前,仍需围绕权限、幂等、审计、失败恢复、评测与观测补齐业务级保障。

这不是另一套抽象名词,而是一条具体实现路径。下面从一个真实项目看它怎样落地。


1. Planning:先把复杂任务拆成可追踪的待办

简单任务不必每次都规划;但只要目标包含调研、查询、生成报告、调用多个系统这类步骤,就应该先把任务外置为结构化清单。这样做的重点不是给用户展示进度,而是让 Agent 自己始终知道:当前做到哪里、下一步是什么、哪些任务还没有完成。

我们这里通过 write_todos 做长任务分步规划:

它将任务 ID、内容、状态、依赖关系和合并策略都变成明确字段。代码中的装饰器和导入路径取决于你的具体封装与框架版本。

from deepagents import tool, ToolParameter

@tool(
    name="write_todos",
    description=(
        "创建并管理一个结构化的任务清单,用于规划复杂目标。"
        "可以一次性创建完整列表,或者增量更新现有列表。"
        "每一步执行完成后必须更新对应任务的状态。"
    ),
    parameters={
        "todos": ToolParameter(
            type="array",
            description="要应用的任务列表。如果提供空数组则清空所有任务。",
            items={
                "type": "object",
                "properties": {
                    "id": {"type": "string", "description": "唯一标识符"},
                    "content": {"type": "string", "description": "任务描述"},
                    "status": {
                        "type": "string",
                        "enum": ["pending", "in_progress", "completed", "cancelled"],
                    },
                    "depends_on": {
                        "type": "array",
                        "items": {"type": "string"},
                        "description": "前置依赖的任务ID列表",
                    },
                },
                "required": ["id", "content", "status"],
            },
        ),
        "merge": ToolParameter(
            type="boolean",
            description="是否与现有列表合并(默认True),否则全量替换",
            default=True,
        ),
    }
)
def write_todos(todos: list[dict], merge: bool = True) -> str:
    # 实际逻辑将由框架自动接入,这里只是占位函数体
    ...

这段代码里有三个很关键的点。

  • 第一,status 被限制为固定枚举值,模型不能随手写一个"快完成了"之类的自然语言状态。
  • 第二,depends_on 让任务顺序可以被显式表达,例如"生成图表"必须等待"数据调研"完成。
  • 第三,merge 让 Agent 可以增量更新计划,而不是每做一步就丢掉已有任务。

Harness 在这里真正做的,是校验模型传来的结构是否合理,并把更新后的清单写回运行时状态。计划一旦外置,模型就不必把全部进度硬记在对话里;中断后也能从最近状态继续。

任务跑到最后一步时,Agent 看到的应该是这样的状态,而不是一长串失效的聊天记录:

Updated todo list to [
  {'content': '扫描技能目录并加载分析操作手册', 'status': 'completed'},
  {'content': '收集产品规格与技术参数(web_search + ERP查询)', 'status': 'completed'},
  {'content': '市场价格调研(爬取竞品B2B页面)', 'status': 'completed'},
  {'content': '供应商渠道对比(supplier_query + part_search)', 'status': 'completed'},
  {'content': '执行综合分析并生成图表', 'status': 'completed'},
  {'content': '输出最终报告到 /analysis/ 目录', 'status': 'in_progress'}
]

这份清单不是"任务完成后的汇报",而是 Agent 执行过程中的工作内存。真正容易出问题的不是模型不会列计划,而是计划只写在提示词里,没有被工具、状态管理和验收流程约束住。


2. Sandbox:允许执行,但不要把宿主机直接交出去

Agent 要完成真实任务,往往需要读写文件、执行命令、安装依赖甚至访问外部服务。我们可以用到 OpenSandbox 或 Cube Sandbox,这一步不能省。

沙箱的意义不只是防止"删错文件"。更重要的是把代码执行、依赖安装、临时文件和高风险工具放进受控环境,让 Agent 有执行能力,但没有无限制的系统权限。读操作、写操作、网络访问、密钥使用和生产资源都应该按最小权限拆开配置。

对 Harness 来说,安全不是在系统提示词里写一句"请谨慎操作",而是让危险动作在架构上根本没有越界的机会。

下面是 OpenSandbox 的核心配置代码。OpensandboxBackend 将其适配为 DeepAgents 的沙箱后端;文件操作走 BackendProtocolexecute 则是沙箱后端提供的扩展能力。该适配包独立于 DeepAgents 主包,生产使用时应锁定与 DeepAgents、OpenSandbox 兼容的版本。

import os
from opensandbox.sync.sandbox import SandboxSync
from opensandbox.sync.connection_config import ConnectionConfigSync
from datetime import timedelta
from deepagents_opensandbox import OpensandboxBackend

# ---------- 方式一:通过环境变量配置(推荐生产环境) ----------
# os.environ["OPEN_SANDBOX_API_KEY"] = "your-secret-api-key"
# os.environ["OPEN_SANDBOX_DOMAIN"] = "sandbox.example.com:8080"

# ---------- 方式二:直接创建沙箱实例 ----------
# use_server_proxy=True 适用于 Server 在 Docker、Client 在宿主机的场景
config = ConnectionConfigSync(use_server_proxy=True)
sandbox = SandboxSync.create(
    "python:3.11",                          # 指定 Docker 镜像
    timeout=timedelta(seconds=600),         # 沙箱最大存活时间
    ready_timeout=timedelta(seconds=120),   # 等待沙箱就绪的超时
    connection_config=config,
)

# 将沙箱包装为 DeepAgents 后端,Agent 通过 BackendProtocol 访问
backend = OpensandboxBackend(sandbox=sandbox)

print(f"Sandbox ID: {backend.id}")

# Agent 可以在沙箱内执行命令,宿主机不受影响
result = backend.execute("pip install pandas && python -c 'import pandas; print(pandas.__version__)'")
print(f"Exit code: {result.exit_code}")   # 0
print(f"Output: {result.output}")          # pandas 版本号

# 错误命令也能被捕获,不会影响宿主机
result = backend.execute("exit 42")
print(f"Exit code: {result.exit_code}")   # 42

# ---------- 清理 ----------
sandbox.kill()
sandbox.close()

在实际项目中,backend 会被传入 create_deep_agentbackend= 参数。对 Agent 来说,它通过统一的文件工具操作后端;当后端实现沙箱执行协议时,才可以调用 execute。实际隔离边界取决于你部署的 OpenSandbox 配置。这就是"后端协议抽象"的价值——切换沙箱、本地磁盘或云存储时,业务 Agent 的调用方式可以保持一致。


3. Subagents:把专项任务隔离出去,主 Agent 只收结论

当一个任务涉及多个专业领域(比如订单创建流程里既有物料调研、又有价格比对、又有合规检查),如果全部塞给一个 Agent,上下文会迅速膨胀,工具列表也会越来越长,模型注意力被稀释。

Subagents 的思路类似微服务:主 Agent 是编排者,负责拆任务和收结果;每个子 Agent 在独立的上下文中完成专项工作,只返回压缩后的结论。这样主 Agent 的上下文窗口始终保持在可控范围。

内联定义子 Agent

最直接的方式是在 create_deep_agent 时通过 subagents 参数传入:

from deepagents import create_deep_agent

# 定义一个物料调研子 Agent
research_sub_agent = {
    "name": "researcher",
    "description": "负责产品规格、技术参数和市场价格的调研,返回结构化结论",
    "model": "anthropic:claude-haiku-4-5-20251001",  # 子 Agent 可用更轻量的模型
    "system_prompt": (
        "你是一个专业的物料调研助手。"
        "根据给定的物料名称,搜索产品规格、技术参数和市场价格。"
        "返回 JSON 格式的调研结论,不要返回冗长的原始数据。"
    ),
    "tools": [web_search, supplier_query, part_search],
}

# 定义一个合规检查子 Agent
compliance_sub_agent = {
    "name": "compliance_checker",
    "description": "检查采购订单是否符合合规要求(供应商资质、预算上限、审批层级)",
    "model": "anthropic:claude-sonnet-4-20250514",
    "system_prompt": (
        "你是一个采购合规审核助手。"
        "检查订单的供应商资质、预算上限和审批层级是否满足要求。"
        "返回 pass/fail 及具体原因。"
    ),
    "tools": [erp_query, budget_check],
}

# 将子 Agent 接入主 Agent
agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-20250514",
    tools=[order_create, order_update],
    system_prompt=SYSTEM_PROMPT,
    subagents=[research_sub_agent, compliance_sub_agent],
    backend=backend,  # 接入第 2 节的 OpenSandbox 后端
    checkpointer=CHECKPOINTER,
    interrupt_on={
        "order_create": {"allowed_decisions": ["approve", "reject"]},
        "order_update": {"allowed_decisions": ["approve", "reject"]},
    },
)

YAML 配置子 Agent

如果子 Agent 较多,也可以用 YAML 文件管理;当前 DeepAgents 不提供 load_subagents,需要由应用自己把 YAML 解析为 SubAgent 列表:

# subagents.yaml
researcher:
  description: 负责产品规格、技术参数和市场价格的调研
  model: anthropic:claude-haiku-4-5-20251001
  system_prompt: |
    你是一个专业的物料调研助手。
    根据给定的物料名称,搜索产品规格、技术参数和市场价格。
    返回 JSON 格式的调研结论。
  tools:
    - web_search
    - supplier_query
    - part_search

compliance_checker:
  description: 检查采购订单是否符合合规要求
  model: anthropic:claude-sonnet-4-20250514
  system_prompt: |
    你是一个采购合规审核助手。
    检查供应商资质、预算上限和审批层级。
    返回 pass/fail 及具体原因。
  tools:
    - erp_query
    - budget_check
import yaml
from deepagents import create_deep_agent

TOOL_REGISTRY = {
    "web_search": web_search,
    "supplier_query": supplier_query,
    "part_search": part_search,
    "erp_query": erp_query,
    "budget_check": budget_check,
}

with open("subagents.yaml", encoding="utf-8") as f:
    raw_subagents = yaml.safe_load(f)

subagents = [
    {
        "name": name,
        **config,
        "tools": [TOOL_REGISTRY[tool_name] for tool_name in config["tools"]],
    }
    for name, config in raw_subagents.items()
]

agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-20250514",
    tools=[order_create, order_update],
    system_prompt=SYSTEM_PROMPT,
    subagents=subagents,
    backend=backend,
    checkpointer=CHECKPOINTER,
)

主 Agent 如何委派任务

配置好子 Agent 后,主 Agent 会自动获得一个 task 工具。当它判断某个子任务应该交给专家处理时,会调用 task 并指定 subagent_type

主 Agent 接收:"帮我创建一张采购订单,物料是 X"

→ write_todos 拆解任务
→ 调用 task(description="调研物料X的规格和市场价格", subagent_type="researcher")
    └─ researcher 子 Agent 在独立上下文中执行调研
    └─ 返回结构化结论给主 Agent(原始搜索结果不进入主上下文)
→ 调用 task(description="检查此订单的合规性", subagent_type="compliance_checker")
    └─ compliance_checker 子 Agent 执行审核
    └─ 如果发现违规,触发 interrupt 等待人工确认
→ 主 Agent 拿到两个结论,继续执行 order_create

这里的关键是上下文隔离:researcher 搜索到的几十条原始网页数据、compliance_checker 查到的 ERP 记录,都不会进入主 Agent 的上下文。主 Agent 只收到一句"调研完成,物料X规格如下…“和"合规检查通过”。这就是 Subagents 对抗上下文膨胀的核心价值。


4. Human-in-the-Loop:信息不够时,暂停,不要瞎猜

订单创建、文件修改、付费调用、生产数据更新这类场景,最怕 Agent 缺字段还继续往下跑。正确做法是暂停,展示已收集的信息和缺失字段,等待人补充后从原状态恢复。

from langgraph.types import interrupt
import json

def request_missing_info(missing_fields: list[str], collected_data: dict) -> str:
    """当工具调用时发现必要字段缺失,暂停执行并向用户展示
    缺失字段,等待人类补充输入后继续执行。

    Args:
        missing_fields: 缺失的字段列表,格式如 "partId (物料ID, 必填)"
        collected_data: 当前已收集到的数据

    Returns:
        用户补充的字段数据(JSON 字符串)
    """
    response = interrupt({
        "type": "order_info_request",
        "missing_fields": missing_fields,
        "collected_data": collected_data,
    })
    return json.dumps(response, ensure_ascii=False)

这里的 interrupt 不是普通报错。它把当前任务停在一个可恢复点,把缺失项和已收集的数据一起交给人。前提是 Agent 创建时传入了 checkpointer;用户补完 partId 后,要用同一个 thread_idCommand(resume=...) 恢复,系统才会继续原任务,而不是让用户从头再说一遍需求:

from langgraph.types import Command

config = {"configurable": {"thread_id": "order-20260723-001"}}

# 首次调用在 request_missing_info() 处暂停
agent.invoke({"messages": [{"role": "user", "content": "创建采购订单"}]}, config=config)

# 人工补齐字段后,从同一个 checkpoint 恢复
agent.invoke(Command(resume={"partId": "P-10086"}), config=config)

下面的 YAML 则把人工确认放在订单创建和更新这两个关键节点上:

interrupt_on:
  order_create:
    allowed_decisions: ["approve", "reject"]
  order_update:
    allowed_decisions: ["approve", "reject"]

人不必盯住每一步,但必须控制不可逆或高风险的那一步。


5. Skills:把能力拆成模块,按需加载

这里体现了两个 Harness 原则:

渐进式披露。Agent 启动时只读取 SKILL.md 的元数据部分,根据用户请求匹配到相关技能后,才加载完整内容。这大幅减少了初始上下文的 Token 消耗。已配置 /skills/order/ 作为技能来源后,新增技能只需放进该目录,无需再改 Agent 代码——这就是"配置优于编码"。

角色边界system_prompt 不是写一篇百科全书,而是明确告诉 Agent:你是谁、在哪里运行、核心流程是什么。订单相关的详细规则不塞在全局 Prompt 里,而是拆进技能目录按需加载。

from deepagents import create_deep_agent

agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-20250514",
    backend=backend,
    # /skills/order/ 下的每个子目录均可作为一个技能被扫描
    skills=["/skills/order/"],
    system_prompt=(
        "你是一个专业的 ERP 采购订单管理助手,运行在隔离的 OpenSandbox 沙箱环境中。"
        "你的核心职责是:理解订单操作需求 → 调用 MCP 工具执行操作 → 验证结果 → 返回确认。"
    ),
)

这几行配置把"技能发现"和"职责边界"写得很清楚:订单相关的详细规则不需要塞在全局 Prompt 里;Agent 匹配到订单任务后,再去读取 /skills/order/ 下的资料。

这个项目的 skills 实现了自我进化:自动下载、自动创建、功能测试与自动分配。


6. Context Engineering:Token 爆了,别硬塞

一条复杂任务跑久了,上下文一定会越来越大。检索原文、工具返回、运行日志、代码片段都堆在对话里,模型真正需要记住的计划反而被淹没。

这四种处理方式,基本就是长任务的常用组合:

  • 自动 Offloading:一次读取内容过多时,将大结果拆分或落到文件系统,需要时再读取;
  • 自动 Summarization:上下文接近上限时,把历史压缩为结构化摘要;
  • 手动 compact_conversation:在适当节点主动收缩历史,保留结论、约束、文件路径和未完成任务;
  • Isolation:让多个子 Agent 在独立上下文中完成专项工作,主 Agent 只接收压缩结果。

下面是一个手动压缩上下文的示例。当前 DeepAgents 通过 create_summarization_tool_middleware 注册 compact_conversation;该工具不接收手写摘要,而是由中间件生成摘要、更新状态并将原始历史按 backend 配置落盘:

from deepagents import create_deep_agent
from deepagents.middleware.summarization import (
    create_summarization_tool_middleware,
)

model = "anthropic:claude-sonnet-4-20250514"
agent = create_deep_agent(
    model=model,
    backend=backend,
    middleware=[
        create_summarization_tool_middleware(model, backend),
    ],
)

Context Engineering 不是拼命扩大 Token,而是管理模型注意力。一个好的 Harness 会让模型每一轮只看到"此刻必须知道的内容",而不是把整段历史原封不动再发一遍。


7. Checkpoint:人工介入后,任务还能接着跑

当 Agent 接入 SSE 事件流、异步子 Agent、用户偏好和多轮审批后,内存里的状态远远不够。任务中断、服务重启、人工补字段后,都需要 checkpoint 把它带回原来的执行位置。

import os
from deepagents import create_deep_agent
from langgraph.store.memory import InMemoryStore
from langgraph.checkpoint.mongodb import MongoDBSaver

# ---------- MongoDB 配置(用于 Agent 短期记忆 / checkpoint) ----------
MONGODB_URI = os.environ["MONGODB_URI"]

# ---------- 持久化存储 ----------
STORE = InMemoryStore()  # 仅开发环境使用

# MongoDB 持久化:用于 Agent 对话状态 checkpointing。
# checkpointer 的生命周期应覆盖 Agent 的调用和恢复过程。
with MongoDBSaver.from_conn_string(MONGODB_URI) as CHECKPOINTER:
    agent = create_deep_agent(
        model="anthropic:claude-sonnet-4-20250514",
        tools=[order_create, order_update],
        backend=backend,
        checkpointer=CHECKPOINTER,
        store=STORE,
    )
    # 使用同一个 thread_id 调用 agent,并在 interrupt 后以 Command(resume=...) 恢复。

这里要分清三类信息:当前任务状态放 checkpoint;会话中间结果放工作区或会话存储;长期偏好可以沉淀到 preferences.md 或受控数据库。不要把三类东西混成一个"记忆库",否则很难排查权限、更新来源和过期数据。

对应的项目目录可以保持简单:

/agent.md
/prompts.py
/persisted-skills
/preferences.md

agent.md 放总规则和索引,prompts.py 放可测试的提示词构造,persisted-skills 放经过审核的可复用技能,preferences.md 只记录允许跨会话复用的偏好。不要把一切都塞进 agent.md,控制在一两百行的规范通常更容易维护。


8. 完整链路:七层如何协同

把上面的代码连起来看,一次完整的订单创建流程是这样的:

用户:"帮我创建一张采购订单,供应商是华为,物料是..."
  ↓
Agent 启动 → 加载 system_prompt → 匹配 /skills/order/ 技能(渐进式披露)
  ↓
write_todos → 拆任务:收集字段 → 调研物料 → 合规检查 → 创建订单 → 验证结果
  ↓
task(subagent_type="researcher") → 子 Agent 在独立上下文中调研物料规格和市场价格
  ↓
task(subagent_type="compliance_checker") → 子 Agent 执行合规审核
  ↓
调用 order_create → 发现 partId 缺失
  ↓
interrupt() 暂停 → CHECKPOINTER 把状态写入 MongoDB
  ↓
人类补充 partId → 从 MongoDB checkpoint 恢复
  ↓
Agent 拿到数据继续执行 → order_create 调用 MCP 工具
  ↓
interrupt_on 触发 → 人类 approve
  ↓
执行完成 → 验证结果 → 返回确认

每一层各司其职:system_prompt 定义角色,skills 按需加载领域知识,write_todos 管理规划,task 委派子 Agent 隔离上下文,interrupt() 实现暂停,MongoDBSaver 保证状态可恢复,OpenSandbox 隔离执行环境。这就是 Harness Engineering 的"配置优于编码"——不是手写控制流,而是组合模块。


三、日常开发中如何运用 Harness 思路

先从当前项目最容易失控的地方补起。

1. agent.md 不要写成百科全书

首页只放角色、边界、启动流程和目录索引,控制在两百行以内。详细规则拆进 skills、prompts、验收规范等子目录,按需加载。新增能力时改的是对应模块,不是把主提示词越堆越长。

2. 每接一个工具,都补齐契约

明确输入字段、权限范围、失败类型、幂等性和返回格式。特别是写操作,必须定义"执行成功后怎么验收"——不能只返回一段自然语言说"已完成"。

3. 把中间结果落盘

调研原文、代码修改记录、测试输出、待办状态都应能被重新读取。不要只存在模型的短期上下文里。大文件写入工作区,对话中只保留摘要和路径,需要时再读取。

4. 给 Agent 验收能力

浏览器、日志查询、单元测试、接口检查都可以成为最终确认的一部分。Agent 调完工具不能只看返回一句"success",而要检查文件是否真的生成、接口状态是否符合预期、测试是否通过。Harness 的交付标准不是模型说"我做完了",而是系统能验证"结果确实在"。

5. 高风险操作设人工闸门

涉及删除、提交、付费、外发、生产数据时,先展示影响范围,再由人批准。人不需要盯住每一步,但必须在风险真正发生前拥有控制权。

一句话总结

按这个顺序补:多步骤任务就接一个结构化待办;工具有写操作就加校验和审批;工具结果很长就落到文件系统;任务会跨会话或等待人工输入,就加 checkpoint。


结语

本文讲解了一个基于 Harness 架构实现的 Agent 项目,包含了 Planning、Sandbox、Subagents、Human-in-the-Loop、Skills、Context Engineering 和 Checkpoint 七个核心模块的代码实现。这种思维架构值得我们去学习、去运用到日常开发中。

Harness Engineering 不替模型思考,却把模型的思考接进一个可以规划、执行、校验和恢复的系统。它不替代 Prompt 或 Context,而是把它们放进一个可持续运行的闭环里。Prompt 决定模型如何理解任务,Context 决定模型看到什么,Harness 决定它如何规划、执行、校验、恢复,并最终完成交付。

当 Agent 开始真正操作文件、调用系统、完成多步骤工作时,工程重点就已经从"怎样让它回答得更漂亮",转向"怎样让它可靠地做完,而且出了问题能被看见、能被拦住、能继续恢复"。这才是 Harness 最有价值的地方。

项目参考

【Harness Engineering 企业级多 Agent 协同项目实战!Multi-Agent+SandBox+自我进化的 Skill+人工介入-码士集团 AI 大模型】https://www.bilibili.com/video/BV1Cs7h6MEsX?p=31&vd_source=0d5a4d32633eb45ba20dd7e06a8a4604

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐