编程 Harness 运行时:AI Agent 的执行引擎——从上下文管理到自适应进化的底层架构深度解析

2026-08-08 21:50:50 +0800 CST views 12

Harness 运行时:AI Agent 的"执行引擎"——从上下文管理到自适应进化的底层架构深度解析

前言:被忽视的中间层

2026年的今天,大模型的能力边界已经被反复讨论——上下文窗口从128K扩展到1M,推理速度从分钟级压缩到秒级,多模态从文本延伸到了视觉、音频甚至视频。几乎每个月都有新的"最强模型"诞生,每一次发布都伴随着基准测试分数的刷新。

然而,当我们真正去使用这些模型构建生产级 AI Agent 系统时,一个残酷的事实浮现出来:同样的模型权重,换一个 Harness,运行效果能差出十几个百分点

Harness,中文里很难找到精确的对应词汇。如果勉强翻译,可以叫"运行时框架"或"执行引擎"。它处于模型与外部世界之间,负责把模型的"思考"转化为可执行的动作,把外部反馈编织进模型的"记忆",把错误恢复机制串联成连贯的体验。

这层中间件,长期被视为"胶水代码"——不够优雅,不够有技术含量,不值得深度投入。但2026年的实践告诉我们,Harness 才是决定 Agent 系统质量的天花板。它决定了模型看到什么、能做什么、错了怎么兜底、成功了如何复用。

本文将系统性地解析 Agent Harness 的底层架构,从上下文管理、工具调用、错误恢复、记忆系统到自适应进化,配合完整的代码实现,帮助读者真正理解为什么 Harness 才是 AI Agent 工程化的核心战场。


一、问题本质:为什么 Harness 如此关键

1.1 模型能力 ≠ Agent 效果

让我们用一个具体场景来说明。假设你需要用 Claude Code 这样的终端 Agent 修复一个 GitHub issue:

  1. 你把 issue 描述扔给模型
  2. 模型开始阅读代码、分析问题
  3. 模型执行 git 操作、编写代码
  4. 模型运行测试、发现失败
  5. 模型分析失败原因、调整代码
  6. 再次测试……

这个循环可能持续几十轮。在这个过程中,模型本身的"聪明程度"只是成功的一个因素。真正决定成败的,是:

  • 上下文窗口管理:哪些信息该保留、哪些该丢弃、保留的顺序如何
  • 工具定义质量:工具的描述是否清晰、参数 schema 是否无歧义
  • 错误恢复机制:测试失败后模型知道该怎么分析吗,还是直接放弃
  • 记忆复用能力:曾经踩过的坑,这次是否避免了重蹈
  • 执行状态连续性:长时间任务中断后能否无缝恢复

这些全部由 Harness 负责。模型只是一个"强大的推理引擎",Harness 才是把推理结果转化为真实价值的"执行系统"。

1.2 真实数据:Harness 差异带来的性能鸿沟

SWE-bench 是一个评估 AI Agent 解决真实软件工程问题能力的标准测试集。2025年底,Claude Code 首次在这个测试集上突破了 72.5% 的 solve rate,引发了社区的广泛关注。

但鲜为人知的是,同一个 Claude 模型,在不同的 Harness 配置下,SWE-bench 的得分波动范围超过 20 个百分点:

Harness 配置SWE-bench 得分主要差异点
基础 ReAct Loop~50%无状态管理,上下文溢出即失败
带记忆缓存的 Loop~62%失败后能复用之前的信息
带规划层 + 记忆~68%任务分解能力增强
完整 Harness(含自适应)~72.5%动态策略调整,最优执行路径

这不是因为模型变了,而是 Harness 实现了更精细的上下文管理、更智能的失败恢复策略、以及跨任务记忆复用。

1.3 Harness 的技术边界

Harness 不是万能的。它需要处理的问题包括:

上下文窗口的稀缺性:即使是最新的 1M token 上下文窗口,在处理大型代码库时仍然不够用。Harness 需要智能地决定保留什么、压缩什么、丢弃什么。

工具调用的可靠性:当模型决定调用一个工具时,Harness 需要确保调用的语义正确、参数完整、超时合理、结果可解析。

长时间运行的稳定性:一个可能持续数小时的代码修复任务,中间的任何环节出错都需要能恢复,而不是从头开始。

多轮对话的连贯性:Agent 不同于单轮对话,需要在几十甚至上百轮交互中保持目标一致性。

接下来,我们深入 Harness 的每一个核心模块。


二、上下文管理:让有限窗口发挥无限价值

2.1 上下文管理的核心挑战

大模型的上下文窗口是一个固定容量的"工作记忆"。当处理真实项目时,这个容量很快就会被填满:

  • 一个中等规模的代码库可能有数十万行代码
  • 一次代码修复过程可能产生数千行日志
  • 错误堆栈、测试输出、代码 diff……每一项都在消耗上下文

Harness 的第一个职责,就是在这个有限空间内,动态维护一个"最有价值的上下文状态"。

2.2 上下文分层策略

一个成熟的 Harness 通常将上下文分为以下几层:

第一层:系统指令层(System Prompt)

这一层包含 Agent 的角色定义、行为规范、工具定义。这一层的内容相对稳定,但也会根据任务类型动态调整。

class SystemPromptManager:
    """系统提示词管理器,支持动态组合"""

    def __init__(self):
        self.base_instructions = """
你是一个专业的软件工程师,擅长代码分析、问题诊断和修复。
你的工作风格是:先理解问题,再制定计划,最后精确执行。
遇到不确定的问题时,你会先做假设,然后通过实验验证假设。
"""
        self.task_specific_rules = []

    def build_system_prompt(self, task_type: str, tools: list[str]) -> str:
        """构建完整的系统提示词"""
        rules = "\n".join(self.task_specific_rules)
        tool_defs = self._render_tool_definitions(tools)

        return f"""{self.base_instructions}

## 任务类型
{task_type}

## 行为规则
{rules}

## 可用工具
{tool_defs}

## 输出格式
当你需要使用工具时,必须输出以下格式:
<tool_call>
name: <工具名称>
arguments: <JSON格式的参数>
</tool_call>

当你完成任务时,输出:
<done>
summary: <任务总结>
result: <最终结果>
</done>
"""

第二层:任务上下文层(Task Context)

这一层包含当前任务的目标、历史操作、关键发现。这一层是动态变化的,也是 Harness 管理的核心区域。

from dataclasses import dataclass, field
from typing import Any
from enum import Enum
import time

class ContextPriority(Enum):
    """上下文片段的优先级"""
    CRITICAL = 3   # 必须保留(如关键决策点)
    HIGH = 2       # 高价值(如操作结果)
    MEDIUM = 1     # 中等价值(如日志片段)
    LOW = 0        # 可丢弃(如重复信息)

@dataclass
class ContextSegment:
    """上下文片段"""
    content: str
    priority: ContextPriority
    token_count: int
    created_at: float = field(default_factory=time.time)
    source: str = ""  # 来源:code/log/error/plan
    tags: set[str] = field(default_factory=set)

class ContextWindowManager:
    """上下文窗口管理器——Harness 的核心组件"""

    def __init__(self, max_tokens: int = 100000, reserve_tokens: int = 5000):
        """
        max_tokens: 模型上下文窗口上限
        reserve_tokens: 预留给输出的空间
        """
        self.max_tokens = max_tokens
        self.reserve_tokens = reserve_tokens
        self.available_tokens = max_tokens - reserve_tokens

        # 上下文片段存储(按优先级排序)
        self.segments: list[ContextSegment] = []

        # 当前 token 计数
        self._current_tokens = 0

    def add(self, content: str, priority: ContextPriority,
            source: str = "", tags: set[str] = None) -> None:
        """添加新的上下文片段"""
        # 粗略估算 token 数(中文约 1.5 tokens/字,英文约 4 chars/token)
        estimated_tokens = self._estimate_tokens(content)

        segment = ContextSegment(
            content=content,
            priority=priority,
            token_count=estimated_tokens,
            source=source,
            tags=tags or set()
        )

        self.segments.append(segment)
        self._current_tokens += estimated_tokens

        # 如果超过限制,触发压缩
        if self._current_tokens > self.available_tokens:
            self._compact()

    def _estimate_tokens(self, text: str) -> int:
        """估算 token 数量"""
        chinese_chars = sum(1 for c in text if '\u4e00' <= c <= '\u9fff')
        other_chars = len(text) - chinese_chars
        return int(chinese_chars * 1.5 + other_chars / 4)

    def _compact(self) -> None:
        """上下文压缩:当空间不足时,智能丢弃低优先级内容"""
        # 按优先级和新鲜度排序
        self.segments.sort(key=lambda s: (
            s.priority.value,
            -s.created_at  # 新鲜度:越新越重要
        ))

        # 目标:腾出 30% 的空间
        target_tokens = self.available_tokens * 0.7
        removed_tokens = 0
        new_segments = []

        for segment in self.segments:
            if self._current_tokens - removed_tokens <= target_tokens:
                new_segments.append(segment)
            else:
                removed_tokens += segment.token_count

        self.segments = new_segments
        self._current_tokens -= removed_tokens

    def get_context_for_model(self) -> str:
        """生成发送给模型的完整上下文"""
        # 按时间顺序排列(确保连贯性)
        self.segments.sort(key=lambda s: s.created_at)

        return "\n\n".join(seg.content for seg in self.segments)

    def get_summary(self) -> dict:
        """获取当前上下文状态摘要"""
        return {
            "total_tokens": self._current_tokens,
            "available_tokens": self.available_tokens,
            "usage_ratio": self._current_tokens / self.available_tokens,
            "segment_count": len(self.segments),
            "segments_by_priority": {
                p.name: len([s for s in self.segments if s.priority == p])
                for p in ContextPriority
            }
        }

2.3 代码库的智能索引

当 Agent 需要处理大型代码库时,完整加载所有代码不现实。一个成熟的 Harness 会建立代码索引,按需加载:

import subprocess
import json
from pathlib import Path
from dataclasses import dataclass

@dataclass
class FileIndex:
    """文件索引条目"""
    path: str
    file_type: str
    size: int
    summary: str  # AI 生成的摘要
    key_definitions: list[str]  # 关键函数/类定义

class CodebaseIndexer:
    """代码库索引器——让 Agent 按需加载代码"""

    def __init__(self, repo_path: str):
        self.repo_path = Path(repo_path)
        self.index: dict[str, FileIndex] = {}
        self._build_index()

    def _build_index(self) -> None:
        """构建代码库索引"""
        # 使用 tree + wc 快速获取文件结构
        result = subprocess.run(
            ["find", str(self.repo_path), "-type", "f",
             "-name", "*.py", "-o", "-name", "*.go",
             "-o", "-name", "*.ts", "-o", "-name", "*.js"],
            capture_output=True, text=True
        )

        for file_path in result.stdout.strip().split("\n"):
            if not file_path:
                continue

            path = Path(file_path)
            try:
                size = path.stat().st_size
                self.index[str(path)] = FileIndex(
                    path=str(path),
                    file_type=path.suffix,
                    size=size,
                    summary="",  # 后续由 LLM 生成摘要
                    key_definitions=[]
                )
            except Exception:
                continue

    def get_relevant_files(self, query: str, top_k: int = 10) -> list[str]:
        """
        基于查询返回最相关的文件列表。
        实际生产中这里会使用 embedding 相似度匹配,
        这里简化使用关键词匹配演示。
        """
        query_keywords = set(query.lower().split())
        scored = []

        for path, idx in self.index.items():
            # 简单评分:路径名 + 文件类型匹配
            path_lower = path.lower()
            score = sum(1 for kw in query_keywords if kw in path_lower)
            if score > 0:
                scored.append((score, path))

        scored.sort(reverse=True)
        return [path for _, path in scored[:top_k]]

    def load_file_content(self, path: str, max_lines: int = 500) -> str:
        """加载单个文件的内容(带行号,便于引用)"""
        try:
            with open(path, 'r', encoding='utf-8') as f:
                lines = f.readlines()

            # 大文件只加载前后部分
            if len(lines) > max_lines:
                half = max_lines // 2
                content_lines = (
                    lines[:half] +
                    [f"\n... [{len(lines) - max_lines} lines omitted] ...\n\n"] +
                    lines[-half:]
                )
            else:
                content_lines = lines

            numbered = [f"{i+1:4d} | {line}" for i, line in enumerate(content_lines)]
            return f"// File: {path}\n" + "".join(numbered)

        except Exception as e:
            return f"// Failed to load {path}: {e}"

三、工具调用:让模型"行动"而非"空谈"

3.1 工具定义的艺术

工具(Tools)是 Agent 与外部世界交互的接口。工具定义的质量直接决定了 Agent 的行动能力。

一个工具的描述需要包含:

  1. 功能描述:这个工具做什么(模型据此决定何时调用)
  2. 参数 schema:每个参数的类型、含义、是否必需
  3. 返回值说明:成功和失败时分别返回什么
  4. 使用示例:帮助模型理解正确的调用方式
from typing import Any, Callable
from dataclasses import dataclass
import json

@dataclass
class ToolDefinition:
    """工具定义"""
    name: str
    description: str
    parameters: dict  # JSON Schema 格式
    handler: Callable[..., Any]
    examples: list[dict] = None

    def to_schema(self) -> dict:
        """导出为 MCP 协议格式的工具 schema"""
        return {
            "name": self.name,
            "description": self.description,
            "inputSchema": {
                "type": "object",
                "properties": self.parameters.get("properties", {}),
                "required": self.parameters.get("required", [])
            }
        }

# 示例:定义一个"搜索代码"工具
search_code_tool = ToolDefinition(
    name="search_code",
    description="""在指定的代码库中搜索包含特定模式的内容。
支持正则表达式,可以搜索函数名、变量名、注释等。
适用于:当你不确定某个功能在哪里实现,或者需要找到包含特定关键词的代码时使用。""",
    parameters={
        "type": "object",
        "properties": {
            "query": {
                "type": "string",
                "description": "搜索查询,可以是函数名、变量名、或正则表达式"
            },
            "file_pattern": {
                "type": "string",
                "description": "文件匹配模式,如 '*.py'、'src/**/*.go',默认为 '*'(搜索所有文件)"
            },
            "max_results": {
                "type": "integer",
                "description": "最多返回多少条结果,默认为 20"
            }
        },
        "required": ["query"]
    },
    handler=lambda query, file_pattern="*", max_results=20: search_code(query, file_pattern, max_results),
    examples=[
        {
            "description": "搜索处理用户认证的函数",
            "call": {"query": "def authenticate", "file_pattern": "*.py"}
        },
        {
            "description": "搜索包含 'error' 关键词的日志语句",
            "call": {"query": "logger.error", "file_pattern": "*.go", "max_results": 10}
        }
    ]
)

# 示例:定义一个"执行命令"工具
execute_command_tool = ToolDefinition(
    name="execute_command",
    description="""在终端中执行 shell 命令。
适用于:运行测试、构建项目、git 操作、文件操作等。
注意:
- 这个工具会等待命令完成,超时时间为 60 秒
- STDERR 会和 STDOUT 一起返回
- 如果命令需要交互式输入,请使用 execute_command 中的 stdin 参数
- 危险命令(如 rm -rf)会被记录但不会阻止执行""",
    parameters={
        "type": "object",
        "properties": {
            "command": {
                "type": "string",
                "description": "要执行的命令(完整的 shell 命令字符串)"
            },
            "cwd": {
                "type": "string",
                "description": "命令执行的工作目录,默认为项目根目录"
            },
            "timeout": {
                "type": "integer",
                "description": "超时时间(秒),默认为 60"
            }
        },
        "required": ["command"]
    },
    handler=lambda command, cwd=None, timeout=60: execute_cmd(command, cwd, timeout),
    examples=[
        {
            "description": "运行项目的测试套件",
            "call": {"command": "pytest tests/ -v", "timeout": 120}
        },
        {
            "description": "查看 git 状态",
            "call": {"command": "git status"}
        }
    ]
)

3.2 工具调用的生命周期

当模型决定调用工具时,Harness 需要管理完整的调用生命周期:

import asyncio
from typing import Any, Optional
from dataclasses import dataclass
from enum import Enum
import time

class ToolCallStatus(Enum):
    PENDING = "pending"
    RUNNING = "running"
    SUCCESS = "success"
    FAILED = "failed"
    TIMEOUT = "timeout"

@dataclass
class ToolCall:
    """工具调用记录"""
    call_id: str
    tool_name: str
    arguments: dict
    status: ToolCallStatus = ToolCallStatus.PENDING
    result: Any = None
    error: str = None
    started_at: float = 0
    completed_at: float = 0
    retries: int = 0

class ToolExecutor:
    """工具执行器——管理工具调用的完整生命周期"""

    def __init__(self, tools: list[ToolDefinition]):
        self.tools = {t.name: t for t in tools}
        self.call_history: list[ToolCall] = []

    async def execute(
        self,
        tool_name: str,
        arguments: dict,
        call_id: str = None,
        max_retries: int = 3
    ) -> ToolCall:
        """执行工具调用,带重试机制"""
        import uuid
        call_id = call_id or str(uuid.uuid4())[:8]

        call = ToolCall(
            call_id=call_id,
            tool_name=tool_name,
            arguments=arguments
        )

        if tool_name not in self.tools:
            call.status = ToolCallStatus.FAILED
            call.error = f"Unknown tool: {tool_name}"
            return call

        tool = self.tools[tool_name]
        call.status = ToolCallStatus.RUNNING
        call.started_at = time.time()

        try:
            # 支持同步和异步 handler
            handler = tool.handler
            if asyncio.iscoroutinefunction(handler):
                result = await asyncio.wait_for(
                    handler(**arguments),
                    timeout=arguments.get("timeout", 60)
                )
            else:
                result = handler(**arguments)

            call.status = ToolCallStatus.SUCCESS
            call.result = result

        except asyncio.TimeoutError:
            call.status = ToolCallStatus.TIMEOUT
            call.error = f"Tool execution timed out after {arguments.get('timeout', 60)}s"

        except Exception as e:
            if call.retries < max_retries:
                # 重试逻辑
                call.retries += 1
                await asyncio.sleep(2 ** call.retries)  # 指数退避
                return await self.execute(tool_name, arguments, call_id, max_retries)
            else:
                call.status = ToolCallStatus.FAILED
                call.error = str(e)

        call.completed_at = time.time()
        self.call_history.append(call)
        return call

    def format_tool_result(self, call: ToolCall) -> str:
        """将工具调用结果格式化为字符串,供模型理解"""
        if call.status == ToolCallStatus.SUCCESS:
            result_str = str(call.result)
            # 截断过长的输出
            if len(result_str) > 3000:
                result_str = result_str[:3000] + f"\n... [truncated, {len(result_str)-3000} chars omitted]"
            return f"[Tool: {call.tool_name}] Success\n{result_str}"
        elif call.status == ToolCallStatus.TIMEOUT:
            return f"[Tool: {call.tool_name}] Timeout: {call.error}"
        else:
            return f"[Tool: {call.tool_name}] Error: {call.error}"

四、错误恢复:让 Agent 从失败中学习

4.1 错误分类与应对策略

Agent 在执行任务时遇到的错误,大致可以分为三类,每类需要不同的恢复策略:

第一类:工具执行错误

工具调用失败(超时、网络错误、参数错误等)。这类错误通常可以通过重试解决。

def handle_tool_error(call: ToolCall, max_retries: int = 3) -> str:
    """生成针对工具执行错误的恢复提示"""
    if call.status == ToolCallStatus.TIMEOUT:
        return f"""工具 {call.tool_name} 执行超时({call.arguments.get('timeout', 60)}s)。
可能的原因:
1. 命令执行时间过长,可以增加 timeout 参数
2. 系统负载高,重试可能成功
3. 命令在等待某些永远不会发生的事件

建议操作:检查命令本身是否正确,如果是合法的长时间任务,增加 timeout 后重试。"""

    elif "not found" in str(call.error).lower():
        return f"""工具 {call.tool_name} 执行失败:命令不存在。
可能的原因:
1. 命令拼写错误
2. 缺少必要的依赖工具
3. PATH 环境变量问题

建议操作:检查命令是否正确安装,或者使用其他工具达到同样目的。"""

    elif call.retries >= max_retries:
        return f"""工具 {call.tool_name} 重试 {max_retries} 次后仍然失败。
错误信息:{call.error}

建议操作:考虑换一个思路解决这个问题。当前的错误可能表明这个方向走不通。"""

    return f"工具 {call.tool_name} 执行失败:{call.error},正在重试..."

第二类:业务逻辑错误

代码执行失败、测试不通过、API 返回错误状态等。这类错误需要更深入的分析。

def analyze_business_error(error_output: str, context: str) -> str:
    """分析业务逻辑错误,生成诊断提示"""
    # 提取错误类型
    error_type = classify_error(error_output)

    analysis_prompts = {
        "test_failure": f"""测试失败分析:

错误输出:
{error_output}

上下文:
{context}

分析思路:
1. 首先理解哪个测试失败了——从错误信息中找到 TEST_NAME
2. 理解测试的预期行为——查看测试代码,搞清楚这个测试在验证什么
3. 定位失败原因——通常在 "AssertionError" 或 "Error" 之后的部分
4. 制定修复方案——错误可能是:
   - 代码逻辑错误(需要修改实现)
   - 测试本身有问题(需要修改测试)
   - 环境问题(需要修复测试环境)

请先仔细阅读测试代码,理解它在验证什么,再看实际的错误信息。""",

        "compilation_error": f"""编译错误分析:

错误输出:
{error_output}

分析思路:
1. 编译器会报告第一个错误,后面的错误可能是连锁反应
2. 优先修复第一个错误
3. 常见编译错误类型:
   - 语法错误:缺少分号、括号不匹配、关键字拼写错误
   - 类型错误:类型不匹配、参数数量不对
   - 引用错误:使用了未定义的变量或函数

请仔细阅读编译器的错误信息,定位到具体的文件和行号。""",

        "runtime_error": f"""运行时错误分析:

错误输出:
{error_output}

分析思路:
1. 查看错误类型(TypeError、ValueError、NullPointerException 等)
2. 查看错误发生的调用栈,找到导致错误的关键代码行
3. 分析错误原因:
   - 变量未初始化
   - 类型不匹配
   - 边界条件未处理
   - 并发问题

请从调用栈的底部开始分析,通常最后一行才是真正出问题的地方。"""
    }

    return analysis_prompts.get(error_type, f"遇到错误:{error_output}")

def classify_error(output: str) -> str:
    """分类错误类型"""
    output_lower = output.lower()
    if "test" in output_lower and ("fail" in output_lower or "error" in output_lower):
        return "test_failure"
    elif any(x in output_lower for x in ["compilation error", "syntax error", "error:"]):
        return "compilation_error"
    elif any(x in output_lower for x in ["exception", "traceback", "stack trace"]):
        return "runtime_error"
    return "unknown"

第三类:目标迷失

Agent 在执行过程中偏离了原始目标,或者反复尝试同样的失败路径。

class GoalTracker:
    """目标追踪器——检测并纠正目标迷失"""

    def __init__(self, original_goal: str):
        self.original_goal = original_goal
        self.steps: list[dict] = []
        self.consecutive_failures = 0

    def record_step(self, action: str, result: str, success: bool) -> None:
        """记录执行步骤"""
        self.steps.append({
            "action": action,
            "result_preview": result[:200] if result else "",
            "success": success,
            "timestamp": time.time()
        })

        if not success:
            self.consecutive_failures += 1
        else:
            self.consecutive_failures = 0

    def should_reassess(self) -> bool:
        """判断是否需要重新评估任务方向"""
        # 连续失败超过 5 次,需要重新思考
        if self.consecutive_failures >= 5:
            return True

        # 步骤数量异常多(正常任务不应超过 50 步)
        if len(self.steps) > 50:
            return True

        return False

    def generate_reassess_prompt(self) -> str:
        """生成重新评估提示"""
        steps_summary = "\n".join(
            f"{i+1}. [{'✓' if s['success'] else '✗'}] {s['action']}"
            for i, s in enumerate(self.steps[-10:])  # 最近 10 步
        )

        return f"""你已经执行了 {len(self.steps)} 步操作,但尚未完成任务。

## 原始目标
{self.original_goal}

## 最近的操作记录
{steps_summary}

## 连续失败次数
{self.consecutive_failures}

你可能已经陷入了"局部最优"——在一个方向上反复尝试,但始终无法成功。

请暂停当前的操作,重新思考:
1. 这些失败是否有共同的模式?——如果是,说明方向本身有问题
2. 是否遗漏了什么关键信息?——可能需要补充上下文
3. 是否有更简单的解决路径?——有时候绕路反而更快
4. 任务是否真的可行?——如果缺少必要的权限或依赖,可能需要先解决前置条件

请花一点时间整理思路,然后给出一个明确的新计划。不要重复已经失败的策略。"""

五、记忆系统:让 Agent 记住"不该重蹈的覆辙"

5.1 记忆系统的分层架构

人类解决问题时,会自然地复用过去的经验。Agent 也需要类似的记忆能力。一个完整的 Agent 记忆系统通常分为三层:

感觉记忆(Working Memory):当前任务内的上下文,已经在前文的 ContextWindowManager 中讨论过。

短时记忆(Session Memory):当前会话内的经验教训,比如"这个 API 曾经返回 403,所以需要先刷新 token"。

长时记忆(Long-term Memory):跨会话积累的知识,比如"在这个代码库里,所有的配置都在 config.yaml 中"。

from dataclasses import dataclass, field
from typing import Any
import time
import json
from pathlib import Path

@dataclass
class MemoryEntry:
    """记忆条目"""
    content: str
    tags: list[str]
    created_at: float = field(default_factory=time.time)
    last_accessed: float = field(default_factory=time.time)
    access_count: int = 0
    source: str = "agent"  # agent / user / auto
    relevance_scores: dict[str, float] = field(default_factory=dict)

class AgentMemory:
    """Agent 记忆系统——跨任务知识积累"""

    def __init__(self, storage_path: str = "~/.agent_memory"):
        self.storage_path = Path(storage_path).expanduser()
        self.storage_path.mkdir(parents=True, exist_ok=True)

        self.short_term: list[MemoryEntry] = []  # 当前会话
        self.long_term: list[MemoryEntry] = []   # 持久化存储

        self._load_long_term_memory()

    def remember(self, content: str, tags: list[str],
                 source: str = "agent") -> None:
        """将信息存入记忆"""
        entry = MemoryEntry(
            content=content,
            tags=tags,
            source=source
        )
        self.short_term.append(entry)

        # 如果是重要知识,同步写入长时记忆
        if any(tag in tags for tag in ["important", "lesson", "pattern", "fix"]):
            self.long_term.append(entry)
            self._save_long_term_memory()

    def recall(self, query: str, max_results: int = 5) -> list[MemoryEntry]:
        """检索相关记忆"""
        query_lower = query.lower()
        query_keywords = set(query_lower.split())

        all_memories = self.short_term + self.long_term
        scored = []

        for entry in all_memories:
            # 基于标签匹配
            tag_match = sum(1 for tag in entry.tags if tag in query_keywords)

            # 基于内容关键词匹配
            content_words = set(entry.content.lower().split())
            content_match = len(query_keywords & content_words)

            score = tag_match * 3 + content_match  # 标签权重更高

            if score > 0:
                entry.access_count += 1
                entry.last_accessed = time.time()
                scored.append((score, entry))

        scored.sort(reverse=True)
        return [entry for _, entry in scored[:max_results]]

    def _load_long_term_memory(self) -> None:
        """从磁盘加载长时记忆"""
        memory_file = self.storage_path / "long_term.json"
        if memory_file.exists():
            try:
                with open(memory_file, 'r', encoding='utf-8') as f:
                    data = json.load(f)
                    self.long_term = [MemoryEntry(**e) for e in data]
            except Exception:
                self.long_term = []

    def _save_long_term_memory(self) -> None:
        """持久化长时记忆"""
        memory_file = self.storage_path / "long_term.json"
        # 只保留最近 100 条最重要的记忆
        important = sorted(
            self.long_term,
            key=lambda e: (e.access_count, e.last_accessed),
            reverse=True
        )[:100]

        with open(memory_file, 'w', encoding='utf-8') as f:
            json.dump([vars(e) for e in important], f, ensure_ascii=False, indent=2)

    def format_memory_for_context(self, memories: list[MemoryEntry]) -> str:
        """将记忆格式化为上下文片段"""
        if not memories:
            return ""

        formatted = ["\n## 相关历史经验\n"]
        for entry in memories:
            formatted.append(
                f"- **[{'×' + str(entry.access_count) if entry.access_count > 1 else 'NEW'}]** "
                f"{entry.content}\n  "
                f"标签: {', '.join(entry.tags)}"
            )
        return "\n".join(formatted)

5.2 自动从失败中提取经验

一个成熟的 Harness 会自动从失败中提取经验,存入记忆:

def extract_lesson_from_failure(
    task: str,
    attempted_approaches: list[str],
    failure_reason: str
) -> MemoryEntry:
    """从失败中提取可复用的经验教训"""
    lesson_content = f"""任务:{task}
失败的尝试:{', '.join(attempted_approaches)}
失败原因:{failure_reason}

教训:不要重复同样的失败路径。"""
    return MemoryEntry(
        content=lesson_content,
        tags=["lesson", "failure", "pattern"],
        source="auto"
    )

六、执行状态管理:让长时间任务"断点续传"

6.1 为什么需要状态持久化

一个复杂的代码修复任务可能持续数小时。在此期间,可能发生:

  • 网络中断导致会话丢失
  • 开发者切换到其他任务
  • Agent 被重启
  • 模型上下文窗口耗尽

如果没有状态持久化,所有进度都会丢失。Harness 需要支持"断点续传"——保存执行状态,随时可以恢复。

import pickle
import uuid
from dataclasses import dataclass, field, asdict
from typing import Any, Optional
import time

@dataclass
class ExecutionState:
    """执行状态快照"""
    state_id: str
    task_description: str
    current_step: int
    context_snapshot: str
    memory_snapshot: dict
    tool_call_history: list[dict]
    recent_results: list[str]
    created_at: float = field(default_factory=time.time)
    updated_at: float = field(default_factory=time.time)
    metadata: dict = field(default_factory=dict)

class StateManager:
    """状态管理器——支持任务中断恢复"""

    def __init__(self, state_dir: str = "~/.agent_state"):
        self.state_dir = Path(state_dir).expanduser()
        self.state_dir.mkdir(parents=True, exist_ok=True)

        self.current_state: Optional[ExecutionState] = None

    def save_checkpoint(
        self,
        task: str,
        context_mgr: ContextWindowManager,
        memory: AgentMemory,
        executor: ToolExecutor,
        step: int,
        metadata: dict = None
    ) -> str:
        """保存执行状态快照"""
        state_id = str(uuid.uuid4())[:12]

        state = ExecutionState(
            state_id=state_id,
            task_description=task,
            current_step=step,
            context_snapshot=context_mgr.get_context_for_model(),
            memory_snapshot={
                "short_term": [vars(e) for e in memory.short_term],
                "long_term_access_count": {str(i): e.access_count
                    for i, e in enumerate(memory.long_term)}
            },
            tool_call_history=[asdict(c) for c in executor.call_history[-20:]],
            recent_results=[r for r in context_mgr.segments[-5:]],
            metadata=metadata or {}
        )

        state_file = self.state_dir / f"state_{state_id}.pkl"
        with open(state_file, 'wb') as f:
            pickle.dump(state, f)

        self.current_state = state
        return state_id

    def restore_checkpoint(self, state_id: str) -> ExecutionState:
        """恢复执行状态"""
        state_file = self.state_dir / f"state_{state_id}.pkl"
        if not state_file.exists():
            raise FileNotFoundError(f"Checkpoint {state_id} not found")

        with open(state_file, 'rb') as f:
            state = pickle.load(f)

        self.current_state = state
        return state

    def list_checkpoints(self) -> list[dict]:
        """列出所有保存的检查点"""
        checkpoints = []
        for state_file in self.state_dir.glob("state_*.pkl"):
            try:
                with open(state_file, 'rb') as f:
                    state = pickle.load(f)
                checkpoints.append({
                    "state_id": state.state_id,
                    "task": state.task_description[:50],
                    "step": state.current_step,
                    "created_at": state.created_at,
                    "file": str(state_file)
                })
            except Exception:
                continue

        return sorted(checkpoints, key=lambda x: x["created_at"], reverse=True)

6.2 恢复后的"热身"机制

恢复状态后,Agent 需要一个"热身"过程,重新建立对当前状态的认知:

def generate_warmup_prompt(restored_state: ExecutionState) -> str:
    """生成恢复后的热身提示"""
    recent_actions = "\n".join(
        f"- {h['tool_name']}: {h['arguments']}"
        for h in restored_state.tool_call_history[-5:]
    )

    return f"""## 任务恢复

你正在恢复一个之前中断的任务。以下是你之前的进度:

**任务目标**:{restored_state.task_description}

**当前进度**:第 {restored_state.current_step} 步

**最近的操作**:
{recent_actions}

**最近的结果摘要**:
{chr(10).join(restored_state.recent_results[-3:])}

## 恢复后的第一件事

请不要立即继续操作。首先:
1. 理解当前状态——回顾上下文快照,搞清楚现在卡在哪里
2. 确认目标不变——任务目标是否仍然有效
3. 制定下一步计划——基于已有进度,明确接下来该做什么

只有在完全理解当前状态后,才继续执行。避免重复已经失败的尝试。"""

七、自适应 Harness:让执行策略"自己进化"

7.1 核心思路

最前沿的 Harness 研究方向是"自适应"——让 Harness 本身能够根据任务表现动态调整执行策略。这包括:

  • 动态工具选择:根据任务类型决定使用哪些工具
  • 策略路由:不同类型的任务使用不同的执行策略
  • 自我评估:让 Harness 评估自己的表现,并据此调整
from dataclasses import dataclass
from typing import Callable
from enum import Enum

class ExecutionStrategy(Enum):
    """执行策略枚举"""
    CONSERVATIVE = "conservative"   # 保守:每步验证,小步快跑
    AGGRESSIVE = "aggressive"       # 激进:多步并行,快速试错
    PLANNING = "planning"           # 规划优先:先制定计划再执行
    EXPLORATORY = "exploratory"     # 探索:先理解代码库再行动

@dataclass
class StrategyPerformance:
    """策略表现追踪"""
    strategy: ExecutionStrategy
    success_count: int = 0
    failure_count: int = 0
    avg_steps_to_success: float = 0
    total_tokens_used: int = 0

    @property
    def success_rate(self) -> float:
        total = self.success_count + self.failure_count
        return self.success_count / total if total > 0 else 0.0

class AdaptiveHarness:
    """自适应 Harness——根据任务类型和历史表现动态选择策略"""

    def __init__(self):
        self.strategies = {
            ExecutionStrategy.CONSERVATIVE: self._conservative_strategy,
            ExecutionStrategy.AGGRESSIVE: self._aggressive_strategy,
            ExecutionStrategy.PLANNING: self._planning_strategy,
            ExecutionStrategy.EXPLORATORY: self._exploratory_strategy,
        }

        self.strategy_performance: dict[ExecutionStrategy, StrategyPerformance] = {
            s: StrategyPerformance(strategy=s)
            for s in ExecutionStrategy
        }

    def select_strategy(self, task_type: str, task_complexity: float) -> ExecutionStrategy:
        """
        根据任务类型和复杂度选择最佳策略。

        策略选择规则:
        - 简单任务 → CONSERVATIVE(快速完成)
        - 复杂任务 → PLANNING(先规划再执行)
        - 代码库探索 → EXPLORATORY(先理解再行动)
        - 快速试错场景 → AGGRESSIVE(多路径并行尝试)
        """
        # 基于任务类型的启发式选择
        if "explore" in task_type.lower() or "understand" in task_type.lower():
            base_strategy = ExecutionStrategy.EXPLORATORY
        elif "fix" in task_type.lower() or "debug" in task_type.lower():
            base_strategy = ExecutionStrategy.PLANNING
        else:
            base_strategy = ExecutionStrategy.CONSERVATIVE

        # 根据历史表现调整
        base_perf = self.strategy_performance[base_strategy]

        # 如果基础策略历史成功率低于 40%,尝试其他策略
        if base_perf.success_rate < 0.4:
            candidates = [s for s in ExecutionStrategy if s != base_strategy]
            best_alt = max(
                candidates,
                key=lambda s: self.strategy_performance[s].success_rate
            )
            if self.strategy_performance[best_alt].success_rate > base_perf.success_rate:
                base_strategy = best_alt

        # 复杂度调整:高复杂度任务倾向于 PLANNING
        if task_complexity > 0.7 and base_strategy == ExecutionStrategy.CONSERVATIVE:
            base_strategy = ExecutionStrategy.PLANNING

        return base_strategy

    def record_outcome(
        self,
        strategy: ExecutionStrategy,
        success: bool,
        steps: int,
        tokens_used: int
    ) -> None:
        """记录策略执行结果,用于后续优化"""
        perf = self.strategy_performance[strategy]

        if success:
            perf.success_count += 1
            # 增量更新平均步数
            n = perf.success_count
            perf.avg_steps_to_success = (
                (perf.avg_steps_to_success * (n - 1) + steps) / n
            )
        else:
            perf.failure_count += 1

        perf.total_tokens_used += tokens_used

    def _conservative_strategy(self) -> dict:
        """保守策略:每步验证,确保质量"""
        return {
            "max_steps_per_iteration": 1,
            "verify_each_step": True,
            "parallel_tools": False,
            "checkpoint_frequency": 3,
        }

    def _aggressive_strategy(self) -> dict:
        """激进策略:多步并行,快速试错"""
        return {
            "max_steps_per_iteration": 5,
            "verify_each_step": False,
            "parallel_tools": True,
            "checkpoint_frequency": 10,
        }

    def _planning_strategy(self) -> dict:
        """规划优先:先制定详细计划再执行"""
        return {
            "require_plan_before_action": True,
            "plan_verification": True,
            "max_plan_steps": 20,
            "checkpoint_frequency": 5,
        }

    def _exploratory_strategy(self) -> dict:
        """探索策略:先全面理解再行动"""
        return {
            "initial_exploration_steps": 10,
            "codebase_indexing": True,
            "require_understanding_summary": True,
            "checkpoint_frequency": 5,
        }

    def get_strategy_report(self) -> str:
        """生成策略表现报告"""
        lines = ["## 策略表现报告\n"]
        for strategy, perf in self.strategy_performance.items():
            total = perf.success_count + perf.failure_count
            if total == 0:
                continue
            lines.append(
                f"- **{strategy.value}**: "
                f"成功率 {perf.success_rate:.1%} ({perf.success_count}/{total}), "
                f"平均 {perf.avg_steps_to_success:.1f} 步完成, "
                f"总消耗 {perf.total_tokens_used:,} tokens"
            )
        return "\n".join(lines)

八、实战:构建一个完整的 Agent Harness

8.1 整体架构

把以上所有模块组合起来,我们得到一个完整的 Agent Harness:

import asyncio
from typing import Optional

class AgentHarness:
    """
    完整的 Agent Harness 实现

    整合了:
    - 上下文管理(ContextWindowManager)
    - 工具执行(ToolExecutor)
    - 记忆系统(AgentMemory)
    - 状态管理(StateManager)
    - 自适应策略(AdaptiveHarness)
    - 错误恢复(GoalTracker)
    """

    def __init__(
        self,
        model_client,  # 模型客户端(支持 OpenAI / Anthropic 等格式)
        tools: list[ToolDefinition],
        config: dict = None
    ):
        self.model = model_client
        self.config = config or {}

        # 核心组件初始化
        max_tokens = self.config.get("max_context_tokens", 100000)
        self.context = ContextWindowManager(max_tokens=max_tokens)
        self.tools = ToolExecutor(tools)
        self.memory = AgentMemory()
        self.state_manager = StateManager()
        self.adaptive = AdaptiveHarness()
        self.goal_tracker: Optional[GoalTracker] = None

        # 配置
        self.max_iterations = self.config.get("max_iterations", 100)
        self.auto_checkpoint = self.config.get("auto_checkpoint", True)
        self.checkpoint_interval = self.config.get("checkpoint_interval", 10)

    async def run(self, task: str) -> dict:
        """运行 Agent 完成指定任务"""
        print(f"[Harness] Starting task: {task[:80]}...")

        # 初始化目标追踪
        self.goal_tracker = GoalTracker(task)
        self.context.add(task, ContextPriority.CRITICAL, source="task", tags={"task"})

        # 策略选择
        strategy = self.adaptive.select_strategy(task, task_complexity=0.6)
        strategy_config = self.adaptive.strategies[strategy]()
        print(f"[Harness] Using strategy: {strategy.value}")

        for iteration in range(self.max_iterations):
            # 检查点保存
            if self.auto_checkpoint and iteration % self.checkpoint_interval == 0:
                state_id = self.state_manager.save_checkpoint(
                    task=task,
                    context_mgr=self.context,
                    memory=self.memory,
                    executor=self.tools,
                    step=iteration
                )
                print(f"[Harness] Checkpoint saved: {state_id}")

            # 检查目标迷失
            if self.goal_tracker.should_reassess():
                reassess = self.goal_tracker.generate_reassess_prompt()
                self.context.add(reassign, ContextPriority.CRITICAL, source="system")
                print("[Harness] Goal reassessment triggered")

            # 构建 prompt
            prompt = self._build_prompt(strategy_config)

            # 调用模型
            response = await self.model.generate(prompt)

            # 解析响应
            if response.type == "tool_call":
                # 执行工具
                call = await self.tools.execute(
                    response.tool_name,
                    response.arguments
                )
                result_str = self.tools.format_tool_result(call)
                self.context.add(result_str, ContextPriority.HIGH, source="tool")

                self.goal_tracker.record_step(
                    response.tool_name, result_str, call.status == ToolCallStatus.SUCCESS
                )

                # 自动记忆重要发现
                if call.status == ToolCallStatus.SUCCESS:
                    self.memory.remember(
                        f"工具 {call.tool_name} 在此任务中成功执行,结果:{result_str[:100]}",
                        tags=["tool_success", call.tool_name]
                    )

            elif response.type == "done":
                # 任务完成
                print(f"[Harness] Task completed in {iteration + 1} iterations")
                self.adaptive.record_outcome(strategy, True, iteration, self.context._current_tokens)
                return {"success": True, "result": response.content}

            elif response.type == "text":
                # 普通文本响应,添加到上下文
                self.context.add(response.content, ContextPriority.MEDIUM, source="model")

            else:
                self.context.add(str(response), ContextPriority.LOW, source="unknown")

        # 达到最大迭代次数
        print(f"[Harness] Max iterations ({self.max_iterations}) reached")
        self.adaptive.record_outcome(strategy, False, self.max_iterations, self.context._current_tokens)
        return {"success": False, "reason": "max_iterations_reached"}

    def _build_prompt(self, strategy_config: dict) -> str:
        """构建发送给模型的 prompt"""
        parts = []

        # 系统提示
        parts.append(self._build_system_prompt())

        # 任务相关记忆
        recent_memories = self.memory.recall(
            self.goal_tracker.original_goal, max_results=3
        )
        if recent_memories:
            parts.append(self.memory.format_memory_for_context(recent_memories))

        # 当前上下文
        parts.append("\n## 当前状态\n")
        parts.append(self.context.get_context_for_model())

        # 策略特定指令
        if strategy_config.get("require_plan_before_action"):
            parts.append("\n请先制定详细的执行计划,再开始操作。")

        if strategy_config.get("initial_exploration_steps"):
            parts.append("\n请先探索代码库,理解整体结构后再开始修复。")

        return "\n\n".join(parts)

    def _build_system_prompt(self) -> str:
        """构建系统提示词"""
        tool_schemas = [t.to_schema() for t in self.tools.tools.values()]
        return f"""你是一个专业的 AI Agent,在 {self.config.get('task_domain', 'software engineering')} 领域执行任务。

## 核心原则
1. **先理解,再行动**:在执行任何操作前,确保理解了问题的本质
2. **小步快跑**:每次操作后验证结果,不要一次性做太大改动
3. **透明思考**:在调用工具前,先解释你的思路
4. **持续学习**:记录重要的发现和教训,供后续使用

## 工具使用规范
你可以通过调用工具与外部世界交互。每个工具都有明确的功能描述和参数定义。

{json.dumps(tool_schemas, ensure_ascii=False, indent=2)}

## 输出格式
调用工具:<tool_call>...<tool_call>
完成任务:<done>...<done>
"""

8.2 使用示例

async def main():
    # 初始化模型客户端(以 Anthropic 为例)
    model = AnthropicClient(api_key="sk-...")

    # 注册工具
    tools = [
        search_code_tool,
        execute_command_tool,
        read_file_tool,
        write_file_tool,
    ]

    # 初始化 Harness
    harness = AgentHarness(
        model_client=model,
        tools=tools,
        config={
            "max_context_tokens": 100000,
            "max_iterations": 100,
            "auto_checkpoint": True,
            "checkpoint_interval": 10,
            "task_domain": "code repair"
        }
    )

    # 运行任务
    result = await harness.run(
        "修复 GitHub issue #1234:用户上传大文件时内存溢出"
    )

    print(result)

if __name__ == "__main__":
    asyncio.run(main())

九、性能优化与最佳实践

9.1 上下文压缩的艺术

上下文压缩不是简单地截断。好的压缩策略需要:

结构化摘要:不保留原始日志,而是生成结构化的摘要:

def summarize_log_batch(logs: list[str]) -> str:
    """将一批日志压缩为结构化摘要"""
    error_lines = [l for l in logs if "error" in l.lower() or "fail" in l.lower()]
    success_operations = [l for l in logs if "success" in l.lower() or "completed" in l.lower()]

    summary_parts = []

    if error_lines:
        summary_parts.append(f"发现 {len(error_lines)} 条错误记录")
        # 保留前 3 条错误
        for err in error_lines[:3]:
            summary_parts.append(f"  - {err[:150]}")

    if success_operations:
        summary_parts.append(f"成功完成 {len(success_operations)} 项操作")

    summary_parts.append(f"日志批次总计 {len(logs)} 行")

    return "\n".join(summary_parts)

增量压缩:不是每次超限才压缩,而是在达到 70% 容量时就开始主动压缩,避免突然的大规模丢弃:

class ProactiveContextManager(ContextWindowManager):
    """带主动压缩功能的上下文管理器"""

    def add(self, content: str, priority: ContextPriority, source: str = "", tags: set = None):
        super().add(content, priority, source, tags)

        # 超过 70% 容量时主动压缩
        if self._current_tokens > self.available_tokens * 0.7:
            # 使用 summarizer 压缩低优先级内容
            self._smart_compact()

    def _smart_compact(self):
        """智能压缩:生成摘要而非直接丢弃"""
        low_priority = [s for s in self.segments
                       if s.priority in (ContextPriority.LOW, ContextPriority.MEDIUM)
                       and s.source in ("log", "tool_output")]

        if not low_priority:
            return

        # 按来源分组
        by_source = {}
        for seg in low_priority:
            by_source.setdefault(seg.source, []).append(seg.content)

        # 对每组生成摘要
        new_segments = [s for s in self.segments if s not in low_priority]
        for source, contents in by_source.items():
            summary = summarize_log_batch(contents)
            new_segments.append(ContextSegment(
                content=f"[压缩摘要 - {source}]\n{summary}",
                priority=ContextPriority.HIGH,  # 摘要保留较高优先级
                token_count=self._estimate_tokens(summary),
                source=source,
                tags={"compressed", source}
            ))

        self.segments = new_segments

9.2 工具并行化

对于相互独立的工具调用,可以并行执行以加速:

async def execute_parallel(
    self,
    tool_calls: list[tuple[str, dict]],
    max_concurrent: int = 3
) -> list[ToolCall]:
    """并行执行多个工具调用"""
    semaphore = asyncio.Semaphore(max_concurrent)

    async def bounded_execute(tool_name: str, args: dict):
        async with semaphore:
            return await self.execute(tool_name, args)

    tasks = [
        bounded_execute(name, args)
        for name, args in tool_calls
    ]

    return await asyncio.gather(*tasks)

9.3 工具调用超时设计

合理的超时设计能防止 Agent 被单个慢操作卡死:

class TieredTimeoutExecutor(ToolExecutor):
    """分层超时执行器——不同类型的工具有不同超时配置"""

    DEFAULT_TIMEOUTS = {
        "search_code": 30,
        "execute_command": 60,
        "read_file": 10,
        "write_file": 30,
        "api_call": 20,
    }

    async def execute(self, tool_name: str, arguments: dict, **kwargs) -> ToolCall:
        timeout = arguments.get(
            "timeout",
            self.DEFAULT_TIMEOUTS.get(tool_name, 60)
        )
        return await super().execute(tool_name, arguments, timeout=timeout, **kwargs)

十、未来展望:Harness 的演进方向

10.1 自我优化的 Harness

2026年最激动人心的研究方向是"让 Harness 自己学会优化自己":

  • 基于强化学习的策略调整:Harness 的各个参数(压缩时机、重试次数、策略选择)作为可学习的参数,通过历史任务表现持续优化
  • 工具自动发现:Harness 能根据任务需求,自动组合和生成新的工具,而不是依赖预先定义的工具集
  • 跨任务知识迁移:在一个项目中学习到的模式,能否迁移到另一个项目

10.2 多 Agent 协作的 Harness

当一个 Agent 无法独立完成任务时,Harness 需要支持多 Agent 协作:

  • 任务分解:将复杂任务分配给不同的专业 Agent
  • 结果聚合:整合多个 Agent 的输出,形成完整解决方案
  • 冲突解决:当不同 Agent 的建议冲突时,Harness 需要有能力判断哪个更可靠

10.3 安全与可控性

随着 Agent 能力的增强,Harness 的安全边界变得越来越重要:

  • 权限分级:不同的工具调用需要不同级别的确认
  • 操作审计:所有操作都需要完整的审计日志
  • 回滚机制:任何破坏性操作都应该可以快速回滚

结语:Harness 是 Agent 工程化的主战场

回到最初的问题:为什么同样的模型,换一个 Harness,效果能差出十几个百分点?

因为模型提供的是"智能",Harness 提供的是"执行力"。没有 Harness,模型只是一个强大的推理引擎,无法稳定地完成真实任务。有了好的 Harness,模型的能力才能被充分释放。

2026年的 AI Agent 领域,正在经历一个范式转变:人们开始意识到,模型能力的边际收益在递减,而 Harness 工程的边际收益在递增。当所有人都能访问同样的模型时,Harness 的质量就成了决定性的竞争优势。

这意味着,对于今天的工程师来说,学习如何构建高质量的 Agent Harness,是和学会使用大模型本身一样重要的技能。本文所讨论的上下文管理、工具调用、错误恢复、记忆系统、状态持久化和自适应策略,构成了 Harness 工程的核心知识体系。

掌握这些,你就不只是"在使用 AI",而是真正在"构建 AI-native 的系统"。这才是 2026 年工程师最核心的竞争力。


相关标签:AI Agent|Harness|运行时|上下文管理|工具调用|错误恢复|记忆系统|状态管理|自适应策略|Agent架构

推荐文章

Golang在整洁架构中优雅使用事务
2024-11-18 19:26:04 +0800 CST
程序员茄子在线接单