Harness Engineering 再进阶:多 Agent 编排、上下文隔离与长任务恢复

企业级多Agent系统实战:Harness Engineering完整教程与架构设计 多Agent系统作为人工智能工程化的重要分支,通过多个AI智能体协同工作来解决复杂任务。其核心原理是将复杂问题分解为子任务,由不同专长的智能体分工处理,再通过通信协议和任务调度机制整合结果。这种架构的技术价值在于突破了单个AI模型的能力限制,显著提升了处理复杂业务流程的效率和可靠性。在企业级应用场景中,多Agent系统特别适用于客户服务自动化、多步骤决策支持等需要多维度智能协作的业务场景。Harness Engineering作为AI工程化的新范式,重点解决智能体之间的协作流程设计、任务分发机制和错误恢复策 阅读详情

Harness Engineering 再进阶:多 Agent 编排、上下文隔离与长任务恢复

单个 Coding Agent 能完成一次修改,不代表它能稳定完成跨模块、跨小时甚至跨会话的工程任务。真正困难的不是“同时启动更多 Agent”,而是如何划分责任、隔离状态、表达依赖、验证交付物、处理冲突,并在任意一步失败后从正确位置恢复。

系列文章:

  1. Harness Engineering 项目实战:把 AI Coding Agent 从“会写代码”变成“可靠交付”
  2. Harness Engineering 延续篇:用 Evals、Trace 与 Failure Mining 构建自进化质量闭环

本文继续以 Spring Boot 多模块能源平台为背景,构建一个生产级多 Agent Orchestrator。

一、为什么单 Agent 会在长任务中失速

假设需求是:

为设备离线事件增加原因分类,管理端提供查询接口,任务模块每天生成统计结果,开放接口保持向后兼容,并补齐数据库脚本和测试。

这个任务横跨领域模型、管理服务、调度服务、开放接口和数据库。把它一次性交给单个 Agent,常见结果有四类。

1.1 上下文腐化

Agent 读取的代码、日志和测试输出越来越多,早期约束被挤到上下文深处。长上下文增加的是容量,不一定增加注意力质量。

1.2 计划漂移

开始时计划修改五个模块,执行到中途只记得眼前的编译错误,最后把局部绿灯误认为任务完成。

1.3 状态不可恢复

会话中断后,新的 Agent 不知道哪些决策已经确定、哪些验证已完成,只能重新考古或冒险接着改。

1.4 并行写冲突

多个 Agent 在同一工作区编辑同一文件,最终结果取决于写入顺序。并行带来的不是吞吐,而是竞态条件。

多 Agent Harness 的核心不是角色扮演,而是分布式系统设计:

任务拆分       → DAG
责任边界       → Contract
并发安全       → Workspace Isolation + Ownership
通信           → Artifact,而不是完整聊天记录
一致性         → 独立验证 + 串行集成
故障恢复       → Checkpoint + Idempotency
资源治理       → Budget + Lease + Backpressure

二、总体架构:控制面与执行面分离

                       ┌─────────────────────┐
需求 / 验收标准 ──────→│ Planner             │
                       └──────────┬──────────┘
                                  │ Task DAG
                                  ▼
┌─────────────────────────────────────────────────────────┐
│                    Orchestrator 控制面                    │
│ Scheduler │ Lease │ Budget │ Checkpoint │ Policy │ Trace │
└──────┬──────────────┬──────────────┬───────────────┬─────┘
       │              │              │               │
       ▼              ▼              ▼               ▼
  Search Agent   Domain Agent   API Agent      Test Agent
  只读上下文      worktree-A     worktree-B      worktree-C
       │              │              │               │
       └──────────────┴───────┬──────┴───────────────┘
                              │ Artifact Manifests
                              ▼
                    Integrator + Evaluator
                              │
                              ▼
                 Maven / ArchUnit / Contract Tests
                              │
                     通过 ─────┴───── 失败回灌

这里有三个硬边界:

  1. Planner 不直接改代码,只生成可验证任务图;
  2. Worker 只写自己拥有的路径,不能直接合并结果;
  3. Integrator 不重新发明实现,只按依赖顺序集成已验证 Artifact。

三、任务图:把计划从自然语言变成可执行 DAG

3.1 Task Contract

# harness/orchestration/contracts.py
from __future__ import annotations

from dataclasses import dataclass, field
from enum import Enum
from typing import Literal


class TaskStatus(str, Enum):
    PENDING = "pending"
    READY = "ready"
    RUNNING = "running"
    VERIFYING = "verifying"
    SUCCEEDED = "succeeded"
    FAILED = "failed"
    BLOCKED = "blocked"


@dataclass(frozen=True)
class AcceptanceCheck:
    kind: Literal["command", "file", "semantic"]
    value: str


@dataclass
class TaskNode:
    id: str
    goal: str
    dependencies: set[str]
    read_paths: tuple[str, ...]
    write_paths: tuple[str, ...]
    checks: tuple[AcceptanceCheck, ...]
    risk: Literal["low", "medium", "high"] = "medium"
    max_attempts: int = 2
    status: TaskStatus = TaskStatus.PENDING
    attempts: int = 0


@dataclass
class TaskGraph:
    goal: str
    nodes: dict[str, TaskNode] = field(default_factory=dict)

一个任务节点必须回答:

  • 产出什么,而不是“研究一下”;
  • 依赖谁的产物;
  • 可以读取和修改哪些路径;
  • 怎样独立判断完成;
  • 失败多少次后升级给人。

3.2 校验 DAG 与写路径冲突

# harness/orchestration/graph.py
from __future__ import annotations

from collections import deque

from harness.orchestration.contracts import TaskGraph


class InvalidTaskGraph(ValueError):
    pass


def topological_order(graph: TaskGraph) -> list[str]:
    indegree = {node_id: 0 for node_id in graph.nodes}
    outgoing = {node_id: [] for node_id in graph.nodes}

    for node in graph.nodes.values():
        unknown = node.dependencies - graph.nodes.keys()
        if unknown:
            raise InvalidTaskGraph(f"{node.id} 依赖未知节点:{sorted(unknown)}")
        indegree[node.id] = len(node.dependencies)
        for dependency in node.dependencies:
            outgoing[dependency].append(node.id)

    queue = deque(sorted(key for key, value in indegree.items() if value == 0))
    result: list[str] = []
    while queue:
        current = queue.popleft()
        result.append(current)
        for child in outgoing[current]:
            indegree[child] -= 1
            if indegree[child] == 0:
                queue.append(child)

    if len(result) != len(graph.nodes):
        raise InvalidTaskGraph("任务图存在循环依赖")
    return result


def patterns_overlap(left: str, right: str) -> bool:
    """保守判定:路径前缀相交即认为可能冲突。"""
    left_prefix = left.removesuffix("/**").rstrip("/")
    right_prefix = right.removesuffix("/**").rstrip("/")
    return left_prefix.startswith(right_prefix) or right_prefix.startswith(left_prefix)


def assert_parallel_safe(graph: TaskGraph) -> None:
    nodes = list(graph.nodes.values())
    for index, left in enumerate(nodes):
        for right in nodes[index + 1:]:
            ordered = left.id in right.dependencies or right.id in left.dependencies
            overlap = any(
                patterns_overlap(a, b)
                for a in left.write_paths
                for b in right.write_paths
            )
            if overlap and not ordered:
                raise InvalidTaskGraph(
                    f"{left.id} 与 {right.id} 写路径重叠,但没有依赖顺序"
                )

这是保守策略。它宁可少并行,也不允许两个 Worker 靠运气覆盖同一文件。更复杂的系统可以分析 Java Symbol 或 Git diff,但路径所有权仍是最容易审计的第一道边界。

3.3 业务任务 DAG

T1 调查现有设备离线链路(只读)
 ├── T2 修改 energy-domain 模型与枚举
 │     ├── T3 修改 manage 查询与 DTO
 │     └── T4 修改 task 日统计逻辑
 ├── T5 编写 API 黑盒验收测试
 └── T6 校验 open 模块向后兼容

T2 + T3 + T4 + T5 + T6
 └── T7 串行集成、全量验证与独立 Review

调查任务可以先行,T3~T6 在路径不冲突时并行,最终集成必须串行。DAG 表达的是依赖关系,不是让所有节点同时启动。

四、调度器:Ready Queue、Lease 与背压

4.1 只有依赖完成的任务才能运行

# harness/orchestration/scheduler.py
from __future__ import annotations

from harness.orchestration.contracts import TaskGraph, TaskNode, TaskStatus


class Scheduler:
    def __init__(self, graph: TaskGraph, max_parallelism: int = 3) -> None:
        self.graph = graph
        self.max_parallelism = max_parallelism

    def refresh(self) -> None:
        for node in self.graph.nodes.values():
            if node.status is not TaskStatus.PENDING:
                continue
            dependency_states = [
                self.graph.nodes[item].status for item in node.dependencies
            ]
            if any(state in {TaskStatus.FAILED, TaskStatus.BLOCKED}
                   for state in dependency_states):
                node.status = TaskStatus.BLOCKED
            elif all(state is TaskStatus.SUCCEEDED for state in dependency_states):
                node.status = TaskStatus.READY

    def claimable(self) -> list[TaskNode]:
        self.refresh()
        running = sum(
            node.status in {TaskStatus.RUNNING, TaskStatus.VERIFYING}
            for node in self.graph.nodes.values()
        )
        capacity = max(0, self.max_parallelism - running)
        ready = [
            node for node in self.graph.nodes.values()
            if node.status is TaskStatus.READY
        ]
        # 高风险任务优先,减少尾部关键路径等待。
        priority = {"high": 0, "medium": 1, "low": 2}
        return sorted(ready, key=lambda item: (priority[item.risk], item.id))[:capacity]

仅设置 max_parallelism 还不够。外部模型 API、构建 CPU、数据库 Fixture 都可能成为瓶颈:

P a r a l l e l i s m ≤ min ⁡ ( M o d e l Q u o t a , S a n d b o x C a p a c i t y , T e s t C a p a c i t y ) Parallelism \leq \min(ModelQuota, SandboxCapacity, TestCapacity) Parallelism≤min(ModelQuota,SandboxCapacity,TestCapacity)

当 Maven 测试队列积压时,调度器应暂停新 Worker,而不是继续生成更多等待验证的代码。这就是 Backpressure。

4.2 Lease 防止任务被重复领取

分布式 Worker 可能崩溃,不能只用内存中的 RUNNING 标志。任务领取需要带租约:

UPDATE agent_task
SET status = 'RUNNING',
    owner = :worker_id,
    lease_until = :now + INTERVAL '5 minutes',
    version = version + 1
WHERE id = :task_id
  AND status = 'READY'
  AND version = :expected_version;

受影响行数为 1 才算领取成功。Worker 定期续租;租约过期后,Orchestrator 可以重新派发。version 提供乐观锁,避免两个 Worker 同时拿到任务。

但租约不能保证“恰好执行一次”。Worker 可能完成写入后、上报成功前崩溃,因此所有副作用都要尽量幂等。

五、Workspace 隔离:共享仓库,独立写入

5.1 为什么使用 Git Worktree

每个 Worker 共用 .git 对象库,但拥有独立工作目录和分支,创建速度远快于完整 Clone:

repo-main/                 # Integrator,只负责集成
worktrees/run-42-T2/       # Domain Worker
worktrees/run-42-T3/       # Manage Worker
worktrees/run-42-T5/       # Test Worker
# harness/orchestration/workspace.py
from __future__ import annotations

import subprocess
from dataclasses import dataclass
from pathlib import Path


@dataclass(frozen=True)
class Workspace:
    task_id: str
    branch: str
    path: Path
    base_commit: str


class WorktreeManager:
    def __init__(self, repository: Path, root: Path) -> None:
        self.repository = repository.resolve()
        self.root = root.resolve()
        self.root.mkdir(parents=True, exist_ok=True)

    def create(self, run_id: str, task_id: str, base_commit: str) -> Workspace:
        branch = f"agent/{run_id}/{task_id}"
        path = self.root / f"{run_id}-{task_id}"
        subprocess.run(
            ["git", "worktree", "add", "-b", branch, str(path), base_commit],
            cwd=self.repository, check=True, capture_output=True, text=True,
        )
        return Workspace(task_id, branch, path, base_commit)

    def diff(self, workspace: Workspace) -> str:
        completed = subprocess.run(
            ["git", "diff", "--binary", workspace.base_commit],
            cwd=workspace.path, check=True, capture_output=True, text=True,
        )
        return completed.stdout

删除 Worktree、分支和临时资源属于生命周期清理,应由控制面在确认 Artifact 已归档后执行,不授权 Worker 自行清理。

5.2 路径权限必须在写入时检查

只在任务 Prompt 中说“只能修改 manage 模块”不够。每次写入前都要检查:

import fnmatch
from pathlib import Path


def assert_write_allowed(relative_path: str, patterns: tuple[str, ...]) -> None:
    normalized = relative_path.replace("\\", "/")
    if Path(normalized).is_absolute() or ".." in Path(normalized).parts:
        raise PermissionError(f"路径越界:{relative_path}")
    if not any(fnmatch.fnmatch(normalized, pattern) for pattern in patterns):
        raise PermissionError(f"任务无权写入:{relative_path}")

工作区隔离解决并发污染,路径策略解决任务越权,两者缺一不可。

六、Artifact 协议:Agent 之间传递证据,不传递噪声

把完整聊天历史传给下游 Agent,会把搜索日志、失败尝试和过期假设一并传播。更稳定的方式是输出结构化 Artifact Manifest:

# harness/orchestration/artifacts.py
from __future__ import annotations

from dataclasses import asdict, dataclass
import hashlib
import json
from pathlib import Path


@dataclass(frozen=True)
class ArtifactManifest:
    task_id: str
    base_commit: str
    patch_file: str
    patch_sha256: str
    changed_files: tuple[str, ...]
    decisions: tuple[str, ...]
    verification: tuple[str, ...]
    residual_risks: tuple[str, ...]


def create_manifest(
    task_id: str,
    base_commit: str,
    patch: bytes,
    output_dir: Path,
    changed_files: list[str],
    decisions: list[str],
    verification: list[str],
    residual_risks: list[str],
) -> ArtifactManifest:
    output_dir.mkdir(parents=True, exist_ok=True)
    patch_path = output_dir / f"{task_id}.patch"
    patch_path.write_bytes(patch)
    manifest = ArtifactManifest(
        task_id=task_id,
        base_commit=base_commit,
        patch_file=str(patch_path),
        patch_sha256=hashlib.sha256(patch).hexdigest(),
        changed_files=tuple(changed_files),
        decisions=tuple(decisions),
        verification=tuple(verification),
        residual_risks=tuple(residual_risks),
    )
    (output_dir / f"{task_id}.json").write_text(
        json.dumps(asdict(manifest), ensure_ascii=False, indent=2),
        encoding="utf-8",
    )
    return manifest

Manifest 是 Agent 间的稳定接口:

  • patch 是可重放交付物;
  • sha256 防止交付后被静默替换;
  • decisions 保存影响后续任务的结论;
  • verification 是已执行证据,不是“应该能通过”;
  • residual_risks 明确不知道什么。

下游 Agent 默认只读取 Manifest,需要证据时再按路径读取 Patch,实现渐进式披露。

七、上下文路由:给每个任务最小充分信息

7.1 Context Pack

# harness/orchestration/context_router.py
from dataclasses import dataclass


@dataclass(frozen=True)
class ContextPack:
    global_rules: str
    task_contract: str
    architecture_slice: str
    dependency_manifests: tuple[str, ...]
    relevant_files: tuple[str, ...]
    token_budget: int


ROUTES = {
    "domain-model": {
        "docs": ("docs/domain-glossary.md",),
        "skills": ("skills/domain-model-change/SKILL.md",),
        "max_tokens": 18_000,
    },
    "api-change": {
        "docs": ("docs/open-api-contract.md",),
        "skills": ("skills/api-change/SKILL.md",),
        "max_tokens": 22_000,
    },
    "scheduled-job": {
        "docs": ("docs/task-module.md",),
        "skills": ("skills/xxl-job/SKILL.md",),
        "max_tokens": 20_000,
    },
}

Context Router 根据任务类型组装上下文,而不是把全部 Skill、MCP Tool 和文档注入每个 Worker。

7.2 信息优先级

上下文超预算时,按以下顺序保留:

1. 原始任务与完成契约
2. 安全和写路径边界
3. 直接依赖 Artifact 的决策
4. 当前修改相关代码
5. 架构切片与领域词汇
6. 历史示例
7. 搜索过程和成功日志

压缩不能只按时间删除旧消息。最早出现的业务约束,往往比最近一次成功的 Maven 日志更重要。

八、Orchestrator:把各组件连接成可恢复状态机

# harness/orchestration/orchestrator.py
from __future__ import annotations

from dataclasses import dataclass
from typing import Protocol

from harness.orchestration.contracts import TaskGraph, TaskNode, TaskStatus
from harness.orchestration.scheduler import Scheduler


class WorkerPool(Protocol):
    def submit(self, node: TaskNode) -> str:
        ...

    def poll(self) -> list[dict]:
        ...


class CheckpointStore(Protocol):
    def save(self, graph: TaskGraph) -> None:
        ...


@dataclass
class Orchestrator:
    graph: TaskGraph
    scheduler: Scheduler
    workers: WorkerPool
    checkpoints: CheckpointStore

    def tick(self) -> None:
        # 先消费完成事件,再派发新任务,避免突破并发上限。
        for event in self.workers.poll():
            node = self.graph.nodes[event["taskId"]]
            if event["type"] == "verified":
                node.status = TaskStatus.SUCCEEDED
            elif event["type"] == "retryable_failure":
                node.attempts += 1
                node.status = (
                    TaskStatus.READY
                    if node.attempts < node.max_attempts
                    else TaskStatus.BLOCKED
                )
            elif event["type"] in {"policy_denied", "ambiguous_requirement"}:
                node.status = TaskStatus.BLOCKED
            else:
                node.status = TaskStatus.FAILED
            self.checkpoints.save(self.graph)

        for node in self.scheduler.claimable():
            node.status = TaskStatus.RUNNING
            self.workers.submit(node)
            self.checkpoints.save(self.graph)

    def finished(self) -> bool:
        terminal = {TaskStatus.SUCCEEDED, TaskStatus.FAILED, TaskStatus.BLOCKED}
        return all(node.status in terminal for node in self.graph.nodes.values())

这段代码刻意没有写成一个巨大的 while True。tick() 是幂等状态推进单元,进程重启后可以从 Checkpoint 重建 Graph,再继续调度。

九、失败恢复:重试不是默认答案

9.1 错误分类决定恢复动作

错误是否重试恢复策略
API 429 / 临时网络失败是指数退避,保持原预算
Sandbox 崩溃是从 Base Commit 重建,重放已验 Artifact
编译失败有条件将精简错误回灌同一 Worker
写路径越权否立即阻断并审计
需求歧义否请求人工澄清,冻结下游节点
架构测试失败有条件回到责任 Worker,不由 Integrator 临时修补
Patch 冲突否重新基于最新集成点执行受影响节点

9.2 幂等键

为防止 Worker 超时后重复提交,每个副作用使用幂等键:

idempotency_key = SHA256(run_id + task_id + attempt + operation)

Artifact Store 对同一键只接受一次写入;重复结果若哈希一致则返回已有记录,不一致则标记为冲突。外部评论、工单更新等操作也必须使用幂等键。

9.3 Checkpoint 保存什么

{
  "runId": "run-42",
  "goalHash": "sha256:...",
  "baseCommit": "a71c...",
  "harnessVersion": "0.5.0",
  "nodes": {
    "T2": {
      "status": "succeeded",
      "attempts": 1,
      "artifact": "sha256:9b2f..."
    },
    "T3": {
      "status": "running",
      "attempts": 1,
      "leaseUntil": "2026-09-02T11:20:00Z"
    }
  },
  "budgets": {
    "tokensUsed": 128430,
    "wallClockSeconds": 1840,
    "costUsd": 6.72
  }
}

Checkpoint 记录可验证状态,不保存冗长思维过程。恢复时重新加载任务契约、Artifact 和必要代码,比恢复完整聊天更稳定。

十、集成策略:Patch、依赖顺序与冲突重算

10.1 为什么 Integrator 不应该“顺手修一下”

如果 Integrator 在合并 T3 时发现错误并直接改代码,责任边界和验证证据都会失真。正确流程是:

Artifact 哈希校验
   ↓
路径所有权校验
   ↓
按 DAG 顺序应用 Patch
   ↓
局部冲突?──→ 原 Worker 基于新 Base 重新执行
   ↓
集成态全量 Sensor
   ↓
独立 Evaluator

自动文本冲突解决只适合低风险机械变更。两个 Agent 对同一方法做语义修改时,应重新规划或指定唯一 Owner。

10.2 乐观并发与重算

设 Worker 开始时基线为 B 0 B_0 B0​,集成时主线已变为 B 1 B_1 B1​。若 Patch P P P 能干净应用,也不能直接认为语义正确:

V a l i d ( P , B 0 ) ⇏ V a l i d ( P , B 1 ) Valid(P, B_0) \nRightarrow Valid(P, B_1) Valid(P,B0​)⇏Valid(P,B1​)

因此必须在 B 1 + P B_1 + P B1​+P 上重新运行该节点的验收检查。若依赖契约发生变化,则废弃旧 Artifact,重新执行节点,而不是机械解决冲突。

十一、人类闸门:把人放在信息增益最高的位置

不是每个节点都需要人工确认。可以根据风险动态插入 Gate:

from dataclasses import dataclass


@dataclass(frozen=True)
class RiskSignal:
    database_migration: bool = False
    public_api_breaking: bool = False
    production_config: bool = False
    permission_change: bool = False
    evaluator_disagreement: bool = False


def requires_human_approval(signal: RiskSignal) -> bool:
    return any((
        signal.database_migration,
        signal.public_api_breaking,
        signal.production_config,
        signal.permission_change,
        signal.evaluator_disagreement,
    ))

向人请求批准时,不应倾倒全部 Trace,而应给决策包:

决策:offline_reason 是否增加 NOT NULL 约束?
背景:历史设备记录没有该值。
方案 A:字段可空,兼容旧数据;查询端映射 UNKNOWN。
方案 B:非空并执行回填;需要数据库变更窗口。
建议:A。原因是本任务要求向后兼容且未授权迁移。
影响:A 保留数据语义不完整风险;B 增加发布风险。

人类最有价值的工作是做语义和风险取舍,不是替 Agent 阅读第 3000 行编译日志。

十二、生产实战:跨模块离线原因统计

把前述需求拆成以下 Contract:

节点Owner 路径输入 Artifact验收
T1 调查全仓只读原始需求输出调用链与风险
T2 领域模型core/energy-domain/**T1domain tests
T3 管理接口platform-energy-manage/**T1、T2MockMvc contract
T4 日统计任务platform-energy-task/**T1、T2日期边界测试
T5 开放接口platform-energy-open/**T1、T2OpenAPI diff
T6 集成无业务写权限T2~T5全量 Maven + Review

几个关键设计:

  • T2 先确定枚举值和空值语义,下游只消费其 Manifest;
  • T3、T4、T5 分属不同模块,可在独立 Worktree 并行;
  • T4 必须包含月末、闰日和补跑日期 Fixture;
  • T5 的目标可能只是证明“不需要修改”,无变更也是合法 Artifact;
  • T6 发现冲突时退回责任节点,不获得任意业务写权限。

端到端状态可能是:

T1 succeeded
T2 succeeded
T3 succeeded
T4 retryable_failure → succeeded
T5 succeeded(no-change)
T6 semantic_review → human_gate(database nullable decision) → succeeded

这比“启动五个 Agent,一会儿再看结果”多了很多结构,但结构正是可靠性的来源。

十三、衡量多 Agent 系统,而不是只看总耗时

13.1 关键指标

指标说明
Critical Path DurationDAG 最长依赖路径耗时
Parallel Efficiency串行预计耗时 / 实际并行耗时
Rework Rate因上游变化而重做的节点比例
Conflict RateArtifact 集成冲突比例
Context Efficiency有效上下文 Token / 总输入 Token
Recovery Success Rate中断后无需人工即可恢复的比例
Human Gate Precision人工介入中真正需要决策的比例
Cost per Reliable Change每个通过独立验收的变更成本

13.2 并行效率的陷阱

若各节点耗时为 t i t_i ti​,理想串行耗时是:

T s e r i a l = ∑ i t i T_{serial}=\sum_i t_i Tserial​=i∑​ti​

并行耗时至少受关键路径约束:

T p a r a l l e l ≥ max ⁡ p a t h   p ∑ i ∈ p t i T_{parallel}\geq \max_{path\ p}\sum_{i\in p}t_i Tparallel​≥path pmax​i∈p∑​ti​

实际还要加创建 Sandbox、加载上下文、验证和集成成本。任务过小时,多 Agent 反而更慢。经验上,只有当子任务满足“边界清晰、可独立验证、产物接口稳定”时,才值得并行。

十四、常见反模式

14.1 用角色名称代替任务边界

“你是资深后端专家”不能替代 write_paths、验收条件和返回 Schema。

14.2 所有 Agent 共享一段长对话

这不是协作,而是共享污染。通过 Manifest 交换结果,通过 Trace 保留证据。

14.3 Planner 一次性决定全部细节

早期信息不足。允许在节点完成后细化下游 Contract,但任何 DAG 变更都必须版本化。

14.4 失败后无限重试

重试只适合瞬态错误。确定性失败应修正输入或实现,歧义应升级给人。

14.5 并行 Agent 直接合并主分支

Worker 只能产出 Patch/Artifact;Integrate、发布和外部副作用属于独立权限域。

14.6 用 Agent 数量衡量成熟度

十个互相干扰的 Agent 不如两个边界清晰的 Worker。吞吐来自可并行的任务结构,不来自界面上更多头像。

十五、落地路线

阶段一:可恢复的单 Agent

  • 状态落盘;
  • 明确迭代、时间和成本预算;
  • 会话中断后从 Checkpoint 恢复;
  • 将聊天历史替换为结构化 Hand-off。

阶段二:只读子 Agent

  • 把代码搜索、调用链分析和日志归纳隔离出去;
  • 主线程只接收结论、证据路径和风险;
  • 测量 Context Token 是否下降。

阶段三:隔离写 Worker

  • 引入 Worktree/Sandbox;
  • 定义写路径所有权;
  • 用 Artifact Manifest 交付 Patch;
  • Integrator 串行应用并重新验证。

阶段四:DAG 调度与治理

  • 增加 Lease、Backpressure 和幂等键;
  • 按风险插入 Human Gate;
  • Eval 覆盖并发、恢复和冲突场景;
  • 依据关键路径与返工率优化拆分粒度。

十六、结语

多 Agent 系统的难点从来不是“如何调用多个模型”,而是如何管理多个不完全可靠的执行者。它本质上综合了工作流引擎、分布式调度、权限系统、测试平台和可观测性工程。

一套可靠的编排 Harness 应满足:

任务有契约,而不是只有角色
并行有隔离,而不是共享目录
交付有 Artifact,而不是口头总结
完成有 Judge,而不是自我声明
失败有分类,而不是盲目重试
中断有 Checkpoint,而不是重头开始
高风险有人类闸门,而不是无限自治

单 Agent 的上限由上下文窗口约束,多 Agent 的上限则由协议质量约束。模型可以不断更换,但清晰的任务图、最小权限、可验证产物和故障恢复机制,会成为长期有效的工程资产。

企业级多Agent协同的Harness Engineering:任务编排、沙箱与Skill沉淀 在AI Agent工程化落地中,多Agent协同并非简单地组合多个模型调用,而是需要一套约束体系来保障任务拆解、代码执行与技能复用的安全可靠。Harness Engineering正是这样一套工程框架,它通过任务编排定义Agent协作流程,借助沙箱隔离让模型生成代码在受限环境中运行,并通过Skill机制沉淀可复用的流程化经验。从技术原理看,沙箱基于容器或WASM提供资源限制与权限控制,人工介入则在高危操作前设置审批节点,所有行为均有审计追踪。这种工程化价值在漏洞修复、测试生成等企业场景中尤为突出。无论模型能 阅读详情

相关推荐

Harness Engineering:企业级多Agent系统从概念到部署实战指南

多智能体系统作为AI工程化的重要方向,通过多个专业Agent的协同工作来解决复杂问题。其核心原理基于任务分解与智能体编排,每个Agent专注于特定能力领域,通过状态管理和错误恢复机制确保系统可靠性。这种架构的技术价值在于将单点AI能力整合为可扩展的企业级解决方案,显著提升业务流程自动化效率。在企业客服、决策支持等应用场景中,多Agent系统能够实现智能路由、负载均衡和性能监控。本文以Harness Engineering为方法论,结合Python和容器化技术,详细展示了如何构建具备生产级可靠性的多Agent

weixin_33966095的博客 541

Harness Engineering:构建稳定高效多Agent系统的工程化实践

在人工智能领域,多Agent系统通过协调多个具备特定能力的智能体来共同完成复杂任务,其核心价值在于解决单一模型难以处理的异构、多步骤问题。从技术原理上看,这本质上是分布式系统与工作流编排在AI场景下的延伸,关键在于设计一套可靠的协调与控制机制,即Harness层。该层负责任务分解、路由、状态管理与容错,确保各Agent能稳定协同。在工程实践中,这种模式能显著提升复杂AI应用的可维护性与可靠性,尤其适用于企业级场景,如智能数据分析、自动化报告生成等需要多种专业化能力协作的流程。通过引入状态机、持久化及动态路由

weixin_33901641的博客 425

企业级多Agent协同与Harness Engineering:从可控沙箱到Skill自进化的落地实践

在AI Agent快速进入生产环境的今天,如何让模型在可控轨道上完成复杂任务,成为工程落地的核心挑战。Harness Engineering 强调通过任务边界、工具权限、沙箱隔离与人工审批等机制,将Agent行为约束在安全边界内,避免“能跑通”与“可复用”之间的鸿沟。企业级多Agent系统通过编排式架构拆解任务,由Coder、Reviewer、Security等角色协同,并借助沙箱提供独立可回收的执行空间,降低误操作风险。Skill机制让Agent沉淀企业特有规范,支持自进化与人工评审;人工介入点设计则保障

weixin_34088583的博客 434

Harness Engineering 与 Environment Engineering:AI Agent 工程化的两条主线

如果只看表层,Harness Engineering 和 Environment Engineering 都是在做 AI Agent 工程化。:关注 Agent 如何被组织、调度和纠正:关注 Agent 如何被放置在一个可控、可用、可治理的世界中前者解决的是“任务执行问题”,后者解决的是“运行世界问题”。而当 Agent 真正进入生产环境时,决定上限的,往往不再是单纯的执行逻辑,而是它所处的环境本身。

xxylllw 418

企业级多Agent系统构建:从Prompt Engineering到Harness Engineering实践

在多Agent系统架构中,AI Agent作为核心组件,通过特定的通信机制和状态管理实现复杂任务的协同处理。其技术原理基于分布式计算和智能决策,能够将单一AI能力组合成更强大的解决方案。从技术价值角度看,多Agent系统显著提升了AI应用的可靠性、扩展性和容错能力,特别适合企业级生产环境。在实际应用场景中,这类系统广泛应用于智能客服、业务流程自动化、数据分析等需要多个AI模块协作的领域。本文聚焦的Harness Engineering正是解决多Agent系统在生产环境中稳定运行的关键工程范式,通过系统化的A

weixin_33695082的博客 422

Harness Engineering:AI Agent开发的核心方法论

在AI Agent开发中,Harness Engineering(驾驭工程)正成为决定系统表现的关键因素。与传统的Prompt Engineering不同,Harness Engineering通过构建完整的工程基础设施,包括工具调用接口、文件系统抽象、沙箱环境等,将大模型的计算能力转化为可执行的系统。这一方法不仅能显著提升AI Agent的性能,还能解决长链路任务中的连贯性和容错性问题。实际案例表明,同一模型在不同Harness下的效果可能相差10倍,这凸显了工程基础设施的重要性。Harness Engi

wjxbj的博客 447

如何开发一个 Agent ?从 Prompt Engineering 到 Harness Engineering,一次讲透

不是“把提示词写得更花”,而是为 AI Agent 设计一整套可运行、可约束、可验证、可恢复的执行环境。当任务从“回答一个问题”升级为“持续完成一个真实任务”时,决定系统上限的不再只是模型本身,而是模型外面的这套harness。AI 工程的重心,正在从“让模型看起来更聪明”,转向“让模型在真实世界里稳定工作”。短任务时代,Prompt Engineering 是主角;复杂任务时代,Context Engineering 开始成为核心;

qq_38604364的博客 467

Hermes Agent实践指南:构建生产级AI Agent的Harness Engineering方法

AI Agent作为人工智能技术的重要应用形态,其核心原理是通过大语言模型实现自主任务执行和持续交互。在工程实践中,AI Agent的价值体现在将单次对话能力转化为可靠的生产力工具,广泛应用于文档处理、客户服务、数据分析等场景。然而,从演示原型到生产系统面临着上下文管理、状态持久化、错误处理等工程化挑战。Harness Engineering正是解决这些问题的系统性方法,它强调通过工程化手段确保AI能力的稳定集成。以Hermes Agent框架为例,该开源工具提供了完整的Harness Engineerin

weixin_33829657的博客 456

3步上手AI Agent Harness开发:Awesome Harness Engineering快速入门教程(附学习资源清单)

**Awesome Harness Engineering** 是一个面向 **AI Agent Harness(智能体挽具/运行框架)工程** 的开源精选资源库,系统整理了课程、上下文工程、安全护栏、评估可观测性、基准测试与参考实现等高质量学习材料,帮助新手快速掌握如何让 AI Agent 在长任务中稳定可靠地工作。本文带你 3 步完成入门,并附完整学习资源清单。 --- ## 一、什么是

gitblog_00710的博客 949

从Prompt Engineering到Harness Engineering:生产级AI Agent工程化实践指南

Prompt Engineering作为大语言模型应用的基础技术,专注于通过优化提示词设计来提升单次交互效果。然而在实际工程化场景中,仅靠提示词工程难以满足生产系统的稳定性要求。Harness Engineering正是在此背景下发展起来的技术体系,它通过上下文工程、工具编排和状态管理等核心原理,解决了AI Agent在生产环境中的复杂性问题。在AI工程化实践中,上下文工程负责管理对话历史和知识检索,工具工程确保外部API调用的可靠性,编排工程则控制任务执行的流程逻辑。这些技术价值体现在构建能够处理真实业务

cuanji3287的博客 472

Harness Engineering 深度学习指南

摘要:Harness Engineering(马具工程)是AI工程化的重要阶段,通过外部系统设计提升智能体的稳定性和执行力。它包含三层架构:Prompt Engineering确保指令理解,Context Engineering优化信息供给,Harness Engineering则通过约束机制、执行编排和状态管理实现任务闭环。核心创新包括动态信息加载(Progressive Disclosure)、进程重启(Context Reflect)和生成-验收角色分离。该体系解决了长链路任务中的状态偏移问题,使AI

华盛AI的博客 735

Harness Engineering(驾驭工程)完全指南

《驾驭工程(Harness Engineering)完全指南》摘要: 本文系统阐述了AI Agent时代的核心工程方法论。研究发现,同一模型在不同驾驭系统(Harness)下表现可差10倍,揭示了基础设施质量的决定性作用。Harness Engineering将AI系统分为模型(计算能力)和驾驭系统(操作系统功能),提出六层架构:信息边界、工具系统、执行编排、记忆状态、评估观测、约束恢复。文章展示了从Prompt工程到Context工程再到Harness工程的三阶段演进,强调长链路任务中系统可靠性的重要性。

在渔村里看AI,偶尔捕点新鲜的。 2390

Hermes Agent与Harness Engineering:从AI脚本到生产级应用的工程化实践

AI应用开发正从单次交互验证转向工程化系统构建。Prompt Engineering关注单次模型交互的优化,而Harness Engineering则致力于将AI能力封装为可复用、可监控的生产级组件。通过任务编排、错误恢复和状态管理等工程化手段,AI应用能够跨越从演示到生产的鸿沟,在数据处理、代码审查等场景中实现稳定运行。Hermes Agent作为实践载体,提供了完整的工程化框架,支持RAG集成和记忆机制,帮助开发者将零散的AI脚本升级为可靠的生产力工具。

weixin_34326179的博客 455

从失控到可控:Harness Engineering企业级多Agent协同实践

AI Agent 正从单点实验迈向工程化落地,多智能体协同(Multi-Agent System)面临上下文漂移、权限放大等问题。Harness Engineering 作为面向 Agent 边界的工程方法论,通过沙箱隔离、Skill 技能体系、人工介入与全链路审计,让多个 Agent 在可控、可信、可审计范围内协作。沙箱约束代码行为,Skill 实现经验复用与版本化,编排引擎以状态机驱动规划、编码、审查、测试全流程,并在高风险节点保留人工决策。以代码变更交付流水线为例,从环境准备到核心代码实现,完整呈现企

weixin_34258838的博客 359

AI Agent工程化实践:从Harness Engineering到多Agent系统构建

在人工智能领域,智能体(AI Agent)作为能够感知环境、自主决策和执行任务的软件实体,其核心原理基于大语言模型的推理能力与环境交互机制。从技术价值看,AI Agent将传统自动化提升至认知智能层面,能够处理非结构化任务并适应动态环境。在实际应用场景中,Agent广泛应用于智能客服、代码生成、数据分析等领域,但工程化落地面临稳定性挑战。本文聚焦Harness Engineering框架,通过状态管理、工具沙箱等工程实践解决Agent生产环境可靠性问题,并结合多Agent系统工程实现复杂任务协同。这些方法为

weixin_34320724的博客 444

机器学习——Anaconda下载安装教程

Anaconda详细下载安装教程

2401_83693485的博客 3065

为什么 Agent 总是跑偏?从 Prompt Engineering 到 Harness Engineering,一次讲透

`Harness Engineering` 不是“把提示词写得更花”,而是为 AI Agent 设计一整套可运行、可约束、可验证、可恢复的执行环境。

m0_59164520的博客 242

DQN网络代码调用env.reset()后存储观测信息报错问题ValueError: setting an array element with a sequence.解决处理

**reset()函数返回的是一个array类型以及其中数据的type!模拟游戏进行学习任务。因此需要将observation指定为真正需要的array信息即可,得到的的变量observation类型与Agent存储时的。因此怀疑返回的observation有问题,于是通过。报错信息提示为数据维度不对应,也即最初通过。在强化学习DQN网络代码实现过程中,针对。

Vulcan_Q的博客 4092

Harness Engineering 是什么?AI Agent 越用越聪明的秘密

你看这六个问题,它们根本不是什么技术理论的包装,而是一个真实工程师在真实环境里做事情的时候,本能会问自己的那六件事。你的 PR Review Agent 今天跑了一遍,明天再跑的时候完全不记得「这个 PR 昨天已经审过了」,于是又审一遍再发一次消息,Slack 频道很快就会变成重复消息的坟场。这次会议的目标是啥。如果你不是简单地问一句「帮我总结这篇文章」,而是让大模型做一个更真实的任务,比如:「帮我分析这份需求文档,找出潜在风险,结合我们之前几次评审的意见,给出改进建议,最后生成一份发给产品经理的反馈稿」

knight_9___的博客 805

CentOS 7.9安装python3.11

CentOS 7.9安装python3.11

leafseelight的专栏 1342

有效Dk值提取方法的仿真分析

通过本文的仿真对比分析,提取有效Dk值方面,TDR技术在一些固定的场景下,依然有其参考应用价值,而随着VNA功能的不断增强和高精度测量手段的不断更新,双端口Delta-L技术才是主流评估方法,而单端口Delta-L技术则可以作为其降本增效的方案补充。

一只豌豆象的博客 1824

Harness Engineering 深度解析

摘要: Harness Engineering(驾驭工程)是AI工程继提示词工程、上下文工程后的第三次重心迁移,聚焦于构建Agent运行时框架与协作机制。其核心包括Agent生命周期管理、行为约束框架及多智能体协作系统,解决当前Agent开发中的黑盒、失控风险等问题。OpenAI和Anthropic等企业已通过SDK编排、状态管理等实践该理念。关键技术涵盖状态持久化、工具调用编排及安全控制,需结合开源框架(如OpenClaw)系统学习。该范式标志着AI开发从优化输出转向可控协作,是生产级应用的必经之路。

雨田小哥的博客 641

C++和OpenGL实现3D游戏编程【连载7】——文字和汉字的显示(附源码)

上一节我们讨论了纹理在二维平面内不规则图形贴图的相关基础操作,本节我们开始了解游戏里文字以及汉字的显示方法。本节课我们将从基本的ASCII字符显示,拓展到中文字符的显示,最后再讲到纹理字符的显示,并对各种文字显示方法的优缺点和使用场景进行分析,这节课将使用到显示列表、兼容视图、屏幕图形转纹理等操作。

zhooyu的博客 1498
上一篇: Harness Engineering 延续篇:用 Evals、Trace 与 Failure Mining 构建自进化质量闭环
下一篇: Harness Engineering 安全篇:零信任 Agent、沙箱隔离与供应链治理
yychen_java
博客等级 码龄8年 1451粉丝 77原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值