Harness Engineering

第1章 Agent 不等于大模型:Harness 的价值

作者 杨艺韬 · 6,719 字

第1章 Agent 不等于大模型:Harness 的价值

1.1 Demo 五分钟,生产五个月

如果你参加过 AI Hackathon,很可能见过这样的场景:一个三人小队用一个周末搭出一个令人惊叹的 AI Agent Demo——它能读代码、调 API、写测试、甚至自动修 bug。评委赞不绝口,观众掌声雷动。

然后这个 Demo 就死了。

不是因为它不够酷,而是因为它无法在真实环境中存活。用户输入一段中文夹英文的需求,它的 prompt 解析崩了;调用一个返回 500 的 API,它陷入了无限重试;用户连续追问几轮,它的上下文窗口爆了;更要命的是,它可能把"清理测试数据"理解成危险写操作——因为没有权限控制、确认流程和回滚边界。

这就是 Agent 工程的核心悖论:大模型的能力已经足够强大,但把这个能力安全、可靠、高效地交付给用户,是一个完全不同的工程问题。

让我用一个简单的对比来说明:

# 这是一个 "Demo 级" Agent —— 30 行代码
import anthropic

client = anthropic.Anthropic()

def simple_agent(user_input: str) -> str:
    response = client.messages.create(
        model=SELECTED_MODEL,
        max_tokens=4096,
        messages=[{"role": "user", "content": user_input}]
    )
    return response.content[0].text

# 它能工作吗?能。它能上生产吗?不能。

这 30 行代码缺少什么?缺少的东西可以列一个长长的清单:

这些"缺少的东西",就是 Harness。

1.2 什么是 Harness Engineering

1.2.1 一个类比:马与马具

"Harness"这个词在英文中的本意是马具——缰绳、鞍座、马镫、笼头的总称。一匹马的奔跑能力再强,没有马具,骑手就无法驾驭它。马具不是马的一部分,但没有马具,马对骑手的价值就无法兑现。

这个类比精确地映射到 AI Agent 的世界:

马的世界 Agent 的世界
马(原始动力) 大模型(LLM)
缰绳(方向控制) Prompt Engineering + 编排逻辑
鞍座(稳定接口) 工具系统 + API 抽象
马镫(安全保障) 权限模型 + 安全边界
笼头(约束范围) 上下文管理 + 输出校验
马车(承载用途) 用户界面 + 交互协议
骑手(使用者) 终端用户

Harness Engineering,就是设计和构建这套"马具"的工程学科。

下面这张图展示了 Harness 在整个 Agent 系统中的位置:

graph TD
    User["👤 用户"] -->|输入| Harness
    subgraph Harness["Harness 工程层"]
        direction TB
        PM["提示词管理"] --- TS["工具系统"]
        TS --- OE["编排引擎"]
        OE --- SP["安全与权限"]
        SP --- MC["记忆与上下文"]
        MC --- OB["可观测性"]
    end
    Harness -->|API 调用| LLM["🧠 大模型 (LLM)"]
    LLM -->|推理结果| Harness
    Harness -->|工具调用| Tools["🔧 外部工具\n文件系统 / Shell / API / DB"]
    Tools -->|执行结果| Harness
    Harness -->|输出| User

    style Harness fill:#f0f4ff,stroke:#3b82f6,stroke-width:2px
    style LLM fill:#fef3c7,stroke:#f59e0b,stroke-width:2px

更正式地定义:

Harness Engineering 是指在大模型(LLM)和终端用户之间,设计、实现、优化工程层的方法论。这个工程层负责工具编排、提示词管理、安全控制、上下文管理、状态持久化、可观测性等一系列关键功能,使得大模型的能力能够安全、可靠、高效地交付给用户。

1.2.2 Harness 不是 API Wrapper

很多团队第一次做 Agent,会把 Harness 误解成"给模型 API 包一层函数"。Wrapper 的职责是隐藏调用细节;Harness 的职责是管理一个不确定系统的执行过程。二者差异非常大:

维度 API Wrapper Harness
核心目标 简化模型调用 管理完整任务执行
输入输出 一次请求、一次响应 多轮消息、工具结果、状态变化
错误处理 抛异常或返回错误 重试、降级、让模型修正、请求用户介入
安全边界 通常依赖调用方 内建权限、沙箱、确认、审计
状态管理 可无状态 需要维护会话、计划、环境、记忆
观测对象 HTTP 请求 决策链路、工具调用、成本、失败原因

一个 Wrapper 可以这样写:

async function ask(prompt: string) {
  return llm.messages.create({ model: SELECTED_MODEL, messages: [{ role: 'user', content: prompt }] })
}

一个 Harness 至少要回答更多问题:

async function runTask(task: UserTask, session: SessionState) {
  const context = await buildContext(task, session)
  const plan = await chooseExecutionMode(task, context)

  for await (const event of executePlan(plan, context)) {
    await auditLog.write(event)
    if (event.type === 'tool_call') await enforcePermission(event)
    if (event.type === 'failure') await recoverOrEscalate(event)
    if (shouldStop(event, context.budget)) break
  }

  return summarizeOutcome(session)
}

这段伪代码不关心具体模型是哪一个。它关心的是:上下文怎么构造、计划如何执行、工具调用如何授权、失败如何恢复、预算何时耗尽、最终结果如何向用户解释。换句话说,Harness 把"模型回答"提升成"系统完成任务"。

1.2.3 Harness 的六大支柱

一个成熟的 Harness 系统通常包含以下六个核心子系统:

┌──────────────────────────────────────────────┐
│                  用户界面层                    │
│          (CLI / Web / IDE / API)              │
├──────────────────────────────────────────────┤
│                                              │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  │
│  │ 提示词    │  │ 工具系统  │  │ 编排引擎  │  │
│  │ 管理     │  │          │  │          │  │
│  └──────────┘  └──────────┘  └──────────┘  │
│                                              │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  │
│  │ 安全与   │  │ 记忆与   │  │ 可观测   │  │
│  │ 权限     │  │ 上下文   │  │ 性       │  │
│  └──────────┘  └──────────┘  └──────────┘  │
│                                              │
│              Harness Engineering              │
├──────────────────────────────────────────────┤
│              大模型 (LLM) API                 │
└──────────────────────────────────────────────┘

第一支柱:提示词管理(Prompt Management)

提示词不只是一句"你是一个有帮助的助手"。在生产级 Agent 中,System Prompt 可能长达数万字,包含角色定义、行为规范、工具使用说明、输出格式约束、安全规则等多个维度。提示词管理需要解决版本控制、A/B 测试、动态注入、上下文长度优化等问题。

// Claude Code 的 System Prompt 构建(简化示意)
function buildSystemPrompt(context: AgentContext): string {
  return [
    getBasePersona(),                    // 基础人格
    getToolDescriptions(context.tools),  // 工具描述(根据可用工具动态生成)
    getEnvironmentInfo(context.env),     // 环境信息(OS、Shell、CWD)
    getMemoryContext(context.memory),    // 记忆上下文(.claude/CLAUDE.md)
    getSafetyRules(context.permissions), // 安全规则
    getUserPreferences(context.config),  // 用户偏好
  ].join("\n\n");
}

第二支柱:工具系统(Tool System)

工具系统是 Agent 与外部世界交互的桥梁。一个健壮的工具系统需要处理:工具注册与发现、参数校验(schema validation)、执行超时、错误处理、结果格式化、并发控制。

// 一个生产级工具定义的骨架
interface Tool {
  name: string;
  description: string;
  inputSchema: ZodSchema;      // 运行时类型校验
  permissions: PermissionRule[];// 权限声明
  timeout: number;             // 超时限制
  execute(input: unknown, context: ToolContext): Promise<ToolResult>;
}

// 工具执行不是简单的函数调用
async function executeTool(tool: Tool, input: unknown, context: ToolContext) {
  // 1. 参数校验
  const parsed = tool.inputSchema.safeParse(input);
  if (!parsed.success) return { error: `Invalid input: ${parsed.error}` };

  // 2. 权限检查
  const allowed = await checkPermission(tool, parsed.data, context);
  if (!allowed) return { error: "Permission denied" };

  // 3. 带超时的执行
  const result = await Promise.race([
    tool.execute(parsed.data, context),
    timeout(tool.timeout).then(() => ({ error: "Timeout" }))
  ]);

  // 4. 结果记录(用于可观测性)
  context.telemetry.recordToolCall(tool.name, parsed.data, result);

  return result;
}

第三支柱:编排引擎(Orchestration Engine)

编排引擎负责 Agent 的核心循环——接收用户输入、调用模型、解析工具调用、执行工具、将结果反馈给模型、判断是否终止。这听起来简单,但实际上涉及大量的工程决策:循环终止条件、并行工具调用、子 Agent 协调、流式输出管理。

# Agent 循环的伪代码
async def agent_loop(user_input: str, context: AgentContext):
    messages = context.history + [{"role": "user", "content": user_input}]

    for step in range(MAX_STEPS):
        # 调用模型
        response = await call_model(messages, tools=context.available_tools)

        # 检查是否有工具调用
        tool_calls = extract_tool_calls(response)

        if not tool_calls:
            # 模型直接给出了最终回答
            yield FinalAnswer(response.text)
            return

        # 执行所有工具调用(可能并行)
        results = await execute_tools_parallel(tool_calls, context)

        # 将工具结果追加到消息历史
        messages.append(response.to_message())
        messages.extend(tool_result_messages(results))

        # 上下文窗口管理:如果消息太长,进行裁剪
        messages = truncate_if_needed(messages, context.max_tokens)

    # 达到最大步数,强制终止
    yield Error("Max steps exceeded")

这个循环的核心流程可以用下图表示:

flowchart TD
    A["接收用户输入"] --> B["构建消息上下文"]
    B --> C["调用 LLM"]
    C --> D{"返回工具调用?"}
    D -->|是| E["执行工具\n(可能并行)"]
    E --> F["将结果追加到消息"]
    F --> G{"达到步数上限?"}
    G -->|否| C
    G -->|是| H["强制终止"]
    D -->|否| I["输出最终回答"]

    style C fill:#fef3c7,stroke:#f59e0b
    style E fill:#dbeafe,stroke:#3b82f6

第四支柱:安全与权限(Safety & Permissions)

这是 Harness 中最容易被低估、也最容易出灾难性事故的部分。安全系统需要回答:哪些工具在什么条件下可以被使用?文件系统的哪些路径可以被读写?哪些操作需要用户确认?如何防止 Prompt Injection?

第五支柱:记忆与上下文(Memory & Context)

短期记忆(当前对话历史)和长期记忆(跨会话持久化的知识)的管理。上下文窗口的裁剪策略、向量数据库的检索、项目级知识的注入(如 Claude Code 的 CLAUDE.md 机制),都属于这个支柱。

第六支柱:可观测性(Observability)

在生产环境中,你需要知道:Agent 执行了多少步?每步花了多长时间?调用了哪些工具?消耗了多少 token?为什么在第 7 步做出了错误决策?这些信息对于调试、优化和合规审计都至关重要。

1.2.4 判断一个系统是否具备 Harness 能力

判断一个 Agent 是否只是 Demo,不要看它能不能在一次演示里完成任务,而要看它在坏情况下怎么表现:

问题 Demo 级表现 Harness 级表现
工具参数错了 报错或继续瞎试 返回结构化错误,让模型修正或降级
用户要求危险操作 直接执行或完全拒绝 根据权限策略确认、沙箱或阻止
上下文太长 直接超窗 摘要、裁剪、检索、分层记忆
工具超时 卡死或无限等待 超时、取消、重试上限、替代路径
结果不确定 给出自信答案 暴露假设、标记不确定性、请求验证
成本异常 不可见 记录 token、步数和工具调用预算
任务失败 只说失败 解释失败点、保留可恢复状态

这个表也是本书后续章节的路线图。每一类坏情况背后都有一组 Harness 子系统:工具设计、编排循环、上下文工程、权限模型、可观测性、评估测试。生产级 Agent 的差距往往不是"会不会调用模型",而是"坏情况是否被设计过"。

1.3 可观察的 Harness:三个案例

理论总是苍白的,让我们看看几个可观察的 Harness Engineering 形态。

1.3.1 Claude Code:38 万行 TypeScript 的 Harness(本地快照统计)

Claude Code 是 Anthropic 的 AI 编程助手 CLI。它的底层模型通过 API 调用,但用户体验并不只来自模型。本地 ../claude-code-main 快照中,src/ 下所有 .ts 文件合计 379997 行,统计命令是:

find ../claude-code-main/src -name '*.ts' -type f -print0 | xargs -0 wc -l | tail -n 1

这些代码大部分都在做 Harness:命令行 UI、工具定义、权限、API 请求构造、上下文拼装、MCP、子 Agent、沙箱、遥测、错误恢复。

模型本身的代码量?零。因为模型是通过 API 调用的云服务。

这 38 万行代码在做什么?按 src/ 顶层目录重新统计,最大的几个部分如下:

子系统 实测行数 职责
src/utils/ 175951 占全仓 46%——大量散文件式工具:activityManager / advisor / agentContext / Shell / Cursor / abortController 等数百个
src/services/ 53495 后台服务:MCP / analytics / api / SessionMemory / MagicDocs / autoDream / claudeAiLimits 等
src/tools/ 42309 25+ 内置工具:BashTool 10894 + PowerShellTool 7829 + AgentTool 4514 + LSPTool 1778 + FileEditTool 1524 + FileReadTool 1418 + 等
src/ink/ 15703 终端交互渲染
src/hooks/ 13725 React hooks(useManageMCPConnections 等)
src/bridge/ 12613 IDE / 外部环境桥接
src/cli/ 11883 CLI 入口和命令行行为
src/commands/ 9798 CLI 命令实现
src/components/ 4731 UI 组件(Ink/React 渲染)
其他目录和顶层文件 49984 入口、类型、状态、插件、查询引擎等
合计 379997

这里不需要把每一行都解释成"智能"。恰恰相反,价值在于这些普通工程代码:路径处理、命令解析、权限判断、UI 状态、工具 schema、请求参数、缓存边界、错误信息。Agent 产品越接近生产,越依赖这些不显眼的工程层。

关键洞察是:同一个底层模型,通过不同 Harness 暴露给用户,会形成完全不同的产品能力。模型决定可达到的上限,Harness 决定这个上限能不能被稳定兑现。

1.3.2 LangChain / LangGraph:通用 Harness 框架

如果说 Claude Code 是一个"垂直集成"的 Harness(为特定产品定制),那么 LangChain 和 LangGraph 就是"通用"的 Harness 框架——它们提供构建 Harness 的积木。

LangChain 的核心贡献是建立了一套标准化的抽象:

# LangChain 的 Harness 抽象层
from langchain_core.language_models import BaseChatModel  # 模型抽象
from langchain_core.tools import BaseTool                  # 工具抽象
from langchain_core.prompts import ChatPromptTemplate      # 提示词抽象
from langchain_core.output_parsers import BaseOutputParser # 输出解析抽象
from langchain_core.runnables import RunnableSequence      # 编排抽象

LangGraph 在此基础上加入了有状态的图执行引擎

from langgraph.graph import StateGraph, START, END

# 定义状态
class AgentState(TypedDict):
    messages: list[BaseMessage]
    tool_results: list[dict]
    step_count: int

# 构建图
graph = StateGraph(AgentState)
graph.add_node("think", call_model)
graph.add_node("act", execute_tools)
graph.add_edge(START, "think")
graph.add_conditional_edges("think", should_continue, {
    "continue": "act",
    "end": END,
})
graph.add_edge("act", "think")

# 编译并运行
agent = graph.compile(checkpointer=MemorySaver())

这段代码的每一行都是 Harness,没有一行是模型。模型只是 call_model 节点内部的一个 API 调用。图的定义、状态管理、条件路由、检查点持久化——这些全部是 Harness Engineering 的范畴。

1.3.3 OpenAI Agents SDK:最小化 Harness

OpenAI Agents SDK 代表了另一种 Harness 设计哲学——极简主义:

from agents import Agent, Runner

agent = Agent(
    name="assistant",
    instructions="你是一个有帮助的助手。",
    tools=[web_search, file_reader],
)

result = Runner.run_sync(agent, "帮我搜索最新的 AI 论文")

看起来只有几行代码,但 Runner.run_sync 内部隐藏了一个完整的 Harness:Agent 循环、工具调度、Handoff(Agent 间切换)、Guardrail(安全护栏)、Tracing(追踪)。它的设计选择是"约定优于配置"——大量默认行为被封装在框架内部,开发者只需要声明式地定义 Agent 的行为。

三个案例的对比揭示了一个重要事实:不管外在形态如何不同,Harness 的核心组件是相同的——工具、编排、安全、记忆、可观测性。 差异只在于哪些部分暴露给开发者,哪些部分被封装起来。

graph LR
    subgraph CC["Claude Code (垂直集成)"]
        CC1["38万行 TS"] --> CC2["深度定制\n每个组件"]
    end
    subgraph LC["LangChain/LangGraph (通用框架)"]
        LC1["标准化抽象"] --> LC2["开发者组装\n自选组件"]
    end
    subgraph OA["OpenAI Agents SDK (极简)"]
        OA1["声明式配置"] --> OA2["约定优于配置\n框架封装"]
    end

    CC ---|"定制度 高\n灵活度 低"| LC
    LC ---|"定制度 中\n灵活度 高"| OA

1.4 为什么是现在

Harness Engineering 并不是一个全新的概念。从某种意义上说,任何在 LLM 和用户之间写代码的人,都在做 Harness Engineering。但为什么近几年它突然成为了一个值得系统化研究的学科?

1.4.1 模型能力已经跨过了"够用"线

在早期通用大模型阶段,模型的能力是主要瓶颈。你可以写出很精巧的 Harness,模型依然会在基本的推理任务上犯错。那个时候,提升模型能力的 ROI 远远高于优化 Harness。

现在,主流模型在代码生成、逻辑推理、工具调用等 Agent 核心能力上已经进入"够用但不完美"的阶段。这里的"够用"不是说模型不会犯错,而是说很多失败已经不再是模型完全无能,而是上下文给错、工具设计差、权限边界不清、错误恢复缺失。

换句话说:瓶颈从模型侧转移到了 Harness 侧。

一个形象的比喻:早期模型还不稳定时,系统上限主要由模型能力决定;当模型具备基本工具调用和推理能力后,系统上限开始被工程层决定。输入是否完整、工具是否可用、失败能否恢复、安全边界是否明确,都会直接影响用户感知。

1.4.2 工具调用成为一等公民

早期的 LLM API 需要开发者自己解析模型输出来提取"函数调用"意图。这种方式不可靠、不规范,导致 Harness 的工具系统需要做大量的容错处理。

随着 Tool Use / Function Calling 变成常见 API 能力,模型可以输出结构化的工具调用请求,Harness 不再需要完全依赖自然语言解析工具意图。这降低了一部分工程复杂度,但同时也提高了标准——用户的期望从"能调工具就行"变成了"调工具要快、要准、要安全"。

1.4.3 Agent 从实验室走向生产

AI Agent 概念从 Demo 走向日常工具和企业流程之后,问题的性质也变了:

生产环境对可靠性、安全性、可维护性的要求,比 Demo 高出几个数量级。这些要求全部落在 Harness 的肩上。

1.4.4 行业开始标准化

MCP(Model Context Protocol)的出现是一个标志性事件。它试图标准化 Agent 与外部工具/数据源的交互协议——这本质上就是对 Harness 工具系统的标准化尝试。

类似的标准化趋势还包括:

当一个领域开始出现标准化努力时,说明它已经从"手工作坊"阶段进入了"工程学科"阶段。Harness Engineering 正处在这个转折点上。

1.5 Harness Engineering 的核心挑战

既然 Harness 如此重要,它的核心工程挑战是什么?我们来逐一分析。

1.5.1 不确定性管理

传统软件的输入输出是确定的:给定相同的输入,函数总是返回相同的输出。但 Agent 的核心组件——LLM——是概率性的。同一个输入,模型可能返回不同的工具调用序列,甚至可能返回完全不同的推理路径。

这意味着 Harness 不能假设模型会"按照预期"行动。它必须:

# 不确定性管理的典型模式
async def robust_tool_call(model_response):
    # 1. 校验模型输出的格式
    if not is_valid_tool_call(model_response):
        # 不是简单报错,而是尝试修复
        model_response = await retry_with_clarification(model_response)

    # 2. 校验参数的语义合理性
    tool_name = model_response.tool_name
    if tool_name not in ALLOWED_TOOLS:
        return fallback_response("Unknown tool requested")

    # 3. 执行时的防御性编程
    try:
        result = await execute_with_timeout(tool_name, model_response.args)
    except ToolExecutionError as e:
        # 将错误信息反馈给模型,让它自行修正
        return ToolResult(error=str(e), suggestion="Please try a different approach")

    # 4. 校验结果的合理性
    if is_suspicious_result(result):
        return await human_in_the_loop_review(result)

    return result

1.5.2 安全边界的划定

Agent 能力越强,安全风险越大。一个能够执行 Shell 命令的 Agent,本质上拥有了操作系统级别的能力。Harness 需要在"有用"和"安全"之间找到平衡:

Claude Code 的权限模型提供了一个可借鉴方向:将操作分成允许、需确认、禁止等不同等级,并支持用户通过配置文件自定义规则。这种"分级授权 + 用户可配置"的模式,比简单的全允许或全拒绝更适合生产 Agent。

1.5.3 上下文窗口的经济学

大模型的上下文窗口虽然在持续扩大,但窗口越大,通常成本越高、延迟越大。Harness 需要做"上下文经济学"的决策:

这些决策直接影响 Agent 的质量、速度和成本,是 Harness 工程中最需要精心调优的部分之一。

1.5.4 状态管理的复杂性

一个生产级 Agent 需要管理多层状态:

对话状态  ← 当前会话的消息历史
工具状态  ← 工具执行的中间结果、文件句柄、数据库连接
Agent 状态 ← 当前在执行计划的第几步、已完成的子任务
用户状态  ← 用户的偏好设置、历史行为、权限级别
环境状态  ← 当前工作目录、Git 分支、运行时环境

这些状态之间有复杂的依赖关系。例如,工具执行的结果会改变环境状态(写了一个文件),环境状态的变化会影响后续工具调用的行为(文件已存在,不需要再创建)。LangGraph 把这个问题抽象为"有状态图",是目前处理 Agent 状态管理最系统化的方法之一。

1.5.5 可迁移性的设计

Harness 的另一个难点是可迁移性。很多 Agent Demo 能在作者自己的电脑上运行,是因为它隐含依赖了一整套环境假设:固定 shell、固定目录结构、固定包管理器、固定权限、固定 API key。真正的 Harness 不能把这些假设藏在代码里,而要把它们变成可检测、可配置、可失败恢复的系统能力。

可迁移性可以拆成四层:

层级 需要回答的问题 典型设计
环境迁移 机器、系统、shell 变了还能跑吗 启动时探测能力,按平台选择命令
项目迁移 从 Node 项目换到 Rust 项目怎么办 根据项目标识文件加载不同规则
组织迁移 不同团队权限和流程不同怎么办 配置化权限、项目级记忆、团队 skill
模型迁移 换模型供应商是否要重写 Agent 隔离模型适配层,保留工具和状态协议

这也是为什么 Harness Engineering 不应该和某个模型 API 绑定太死。模型会变,供应商接口会变,工具和权限边界也会变;真正值得沉淀的是任务循环、上下文协议、工具契约、错误恢复和可观测性这些可迁移结构。

1.6 本书会教什么,不会教什么

1.6.1 本书的定位

这本书是关于 Harness Engineering 方法论 的书。它关注的是"如何构建从模型到用户之间的工程层"这个普适性问题,而不是某个特定框架的使用教程。

本书会教:

本书不会教:

1.6.2 本书的读者

这本书适合以下读者:

1.6.3 本书的结构

本书共 21 章,按八篇递进组织,每一篇对应 Harness 的一组关联子系统:

  1. 开篇(ch01):本章——Harness 价值与基本论证
  2. 架构基础(ch02-04):核心架构模式、Agent 循环、上下文工程
  3. 工具工程(ch05-07):工具设计哲学、编排、错误恢复
  4. 提示词架构(ch08-10):System Prompt 分层、指令优先级、Prompting 策略
  5. 状态与记忆(ch11-13):短期记忆、长期记忆、会话状态机
  6. 安全与权限(ch14-15):权限模型、沙箱与隔离
  7. 协调(ch16-17):多 Agent 协调、Human-in-the-Loop
  8. 生产化(ch18-21):评估测试、可观测性、成本性能、设计模式总结

每一章的组织遵循 "为什么 → 是什么 → 怎么做 → 可迁移模式" 的递进结构。

1.7 小结

回到本章开头的问题:为什么拥有一个强大的大模型远远不够?

因为大模型只是一个概率推理引擎。它不知道你的文件系统长什么样,不知道你的 API 需要什么认证,不知道哪些操作是危险的,不知道你的对话历史有多长,不知道用户等了多久。把这个"不知道"变成"知道",把"不安全"变成"安全",把"不可靠"变成"可靠"——这就是 Harness Engineering 的使命。

在接下来的章节中,我们将逐一深入 Harness 的每个子系统,从原理到实现,从理论到生产实践。

让我们从 Agent 的心脏开始——编排循环。