第 10 章:组装与发布 — 从模块到产品

六大模块各自就绪——现在把它们焊在一起

📝 本章目标

读完本章,你将:

  1. 用四个 Prompt 让 AI 帮你把前九章的模块连接、配置、启动、打包成一个完整的产品
  2. 理解配置优先级的分层设计——CLI、环境变量、配置文件、默认值,谁说了算
  3. 掌握 Agent 的启动顺序为什么重要——初始化的先后决定了系统能不能跑
  4. 学会为 AI Agent 设计测试策略,用打包工具把它发布出去

你造过模型车吗?

发动机装好了,变速箱调好了,轮子轮轴都打磨完毕,方向盘和座椅也到位了。每个零件单独测试都没问题——发动机能转、变速箱能换挡、轮子能滚。但现在把它们全摊在桌上,你面对的不是一辆车,而是一堆很好的零件。

从零件到整车,你还需要做四件事:把零件连起来(发动机连变速箱,变速箱连传动轴,传动轴连车轮),调整每个零件的参数让它们配合(齿轮比、轮距、悬挂高度),确定启动顺序(先通电、再点火、再挂挡),最后装上外壳变成一辆别人能开的车。

我们的 harness 现在就是这堆零件。查询引擎、工具系统、权限系统、Agent 编排、记忆系统、钩子与技能、MCP 集成、终端界面——九章下来,每个模块都能独立工作。但它们还没有变成一个你能递给别人说”装上就能用”的产品。

这一章,我们完成最后四步:连接、配置、启动、打包。做完这一步,你手里就不再是一堆零件,而是一辆能开上路的车。

先动手造出来,再回头理解。

动手:用四个 Prompt 完成最终组装

确保你跟着前九章做了项目——查询引擎、工具系统、权限系统、Agent 编排、记忆系统、钩子与技能、MCP 集成、终端界面全部就绪。如果没有,去 GitHub 仓库 git checkout ch09-terminal 获取起点。

打开 Claude Code,确认你在项目根目录,然后跟着走。

Prompt 1:把所有模块连起来

前九章的模块现在是各自独立的——查询引擎不知道要先加载记忆,工具系统不知道要先注册 MCP 工具,权限系统不知道钩子什么时候该跑。第一步是把它们串起来,让数据能在模块间流动。

复制下面这段话,粘贴到 Claude Code 里:

帮我写一个总的组装文件,把所有模块连起来:

1. 查询引擎调用工具时,要先过权限系统检查
2. 工具列表要包含内置工具和 MCP 外部工具
3. 会话开始时要加载记忆,结束时要保存记忆
4. 钩子要在对应的时机自动触发
5. 终端渲染要接管所有输出
6. Agent 编排要能在需要时启动子 Agent

最终只暴露一个入口函数,
调用它就能启动整个系统。

等 AI 跑完,它会创建一个组装模块——通常叫 app.py 或 harness.py——把所有模块的初始化和连接逻辑集中在一起。试一下:

$ python -c "from harness.app import create_app; print(create_app)"
<function create_app at 0x...>

$ harness
[init] Loading config...
[init] Registering 8 built-in tools
[init] Connecting 2 MCP servers... OK (8 external tools)
[init] Loading permissions rules
[init] Loading hooks (3 active)
[init] Loading memory (5 entries)
[init] Terminal renderer ready

Harness v0.1.0 — AI Agent Runtime
You > 你好
Assistant > 你好!有什么可以帮你的?

所有模块连上了,启动日志能看到每个模块的初始化过程。但现在所有参数都是硬编码的——模型名、API key、超时时间都写死在代码里。下一步让它们可配置。

Prompt 2:统一配置管理

帮我做一个统一的配置系统:

1. 支持配置文件——在项目目录下放一个配置文件,
   写好各种参数
2. 支持环境变量——敏感信息比如 API 密钥
   从环境变量里读
3. 支持命令行参数——启动时可以用参数临时覆盖配置
4. 这三种方式有优先级:
   命令行参数 > 环境变量 > 配置文件 > 默认值

至少要能配置这些东西:
模型名称、API 密钥、最大对话轮数、
上下文窗口大小、工具超时时间、MCP 服务器列表。

没有配置文件也能正常启动,用合理的默认值。
$ cat .harness/config.toml
[model]
name = "claude-sonnet-4-20250514"
max_tokens = 8192

[engine]
max_turns = 100
context_window = 200000

[tools]
timeout = 30

$ harness --model claude-sonnet-4-20250514 --max-turns 50
[config] Loaded .harness/config.toml
[config] CLI override: model=claude-sonnet-4-20250514
[config] CLI override: max_turns=50
[config] Final: model=claude-sonnet-4-20250514, max_turns=50

You > /model
Current model: claude-sonnet-4-20250514

配置灵活了。但启动时如果 API 密钥没设、MCP 服务器连不上、记忆文件损坏——现在会直接崩溃。下一步加上健壮的启动流程。

Prompt 3:健壮的启动流程

帮我设计一个健壮的启动流程:

1. 按正确的顺序初始化每个模块——
   先加载配置,再初始化工具,再连 MCP 服务器,
   再加载权限、钩子、记忆,最后启动终端界面
2. 每个模块初始化失败时不要崩溃,
   记录错误,跳过这个模块继续启动
3. 启动完成后显示一个状态报告——
   哪些模块正常,哪些跳过了,为什么跳过
4. 必须有的模块(比如查询引擎、配置系统)
   如果出问题才真正报错退出
5. 加一个 --check 参数,只检查配置和连接是否正常,
   不进入对话模式

启动过程要快——用户不想等太久。
$ unset ANTHROPIC_API_KEY
$ harness
[ERROR] ANTHROPIC_API_KEY not set. Cannot start.
Hint: export ANTHROPIC_API_KEY=sk-ant-...

$ export ANTHROPIC_API_KEY=sk-ant-...
$ harness
[init] Config .............. OK
[init] Query engine ........ OK
[init] Built-in tools ...... OK (8 tools)
[init] MCP servers ......... WARN: 1/2 connected
       └─ database: connection refused
[init] Permissions ......... OK (12 rules)
[init] Hooks ............... OK (3 hooks)
[init] Memory .............. OK (5 entries)
[init] Terminal ............ OK

Harness v0.1.0 — ready (1 warning)

$ harness --check
Checking configuration...
[✓] Config file valid
[✓] API key present
[✓] Model accessible
[✓] Built-in tools loaded
[✗] MCP server "database" unreachable
[✓] Permissions rules valid
[✓] Memory files readable

Result: 6/7 checks passed, 1 warning

系统健壮了。最后一步——让别人能装上你的作品。

Prompt 4:打包发布

帮我做好发布准备,让别人能用一条命令装上直接用:

1. 完善 pyproject.toml——
   项目名、版本号、作者、描述、依赖、
   命令行入口点都配好
2. 加一个命令行入口——装完后在终端输入 harness
   就能直接启动
3. 用户第一次运行时,如果没有配置文件,
   自动创建一个带注释的默认配置
4. 写一个简单的安装说明,
   告诉用户怎么装、怎么配、怎么用
5. 确保能用 pip install 正常安装

打包格式用 Python 标准的 wheel 格式。
$ pip install -e .
Successfully installed harness-0.1.0

$ harness --version
Harness v0.1.0

$ harness --help
usage: harness [-h] [--version] [--model MODEL]
               [--max-turns N] [--check] [--serve]

AI Agent Runtime — 你的智能编程助手

options:
  --version       show version and exit
  --model MODEL   override AI model
  --max-turns N   max conversation turns
  --check         check config without starting
  --serve         start as MCP server

$ harness
Welcome to Harness v0.1.0!
First run detected — creating default config at .harness/config.toml
[init] Config .............. OK (using defaults)
[init] Query engine ........ OK
...

💡 四个 Prompt 做了什么

  • Prompt 1 建立了连接——所有模块串成一个整体
  • Prompt 2 给了灵活性——参数可配置,不用改代码
  • Prompt 3 给了健壮性——出错不崩溃,状态看得见
  • Prompt 4 给了产品形态——一条命令安装,开箱即用

现在你手里有了一个完整的产品。完整代码在 GitHub 仓库,对应 tag ch10-release。

接下来我们回过头,理解你刚刚构建的东西。


深入理解

配置优先级

Prompt 2 做的”命令行参数 > 环境变量 > 配置文件 > 默认值”不是随便定的顺序,而是软件工程中的配置覆盖惯例——几乎所有成熟的 CLI 工具(Docker、Git、Kubernetes)都遵循这个优先级。

图 10-1:配置优先级——上层覆盖下层

  1. CLI 参数(--model, --max-turns)— 最高优先级,覆盖一切
  2. 环境变量(ANTHROPIC_API_KEY, HARNESS_MODEL)— 覆盖配置文件和默认值
  3. 配置文件(.harness/config.toml, ~/.harness/config.toml)— 覆盖默认值
  4. 默认值(claude-sonnet-4-20250514, max_turns=100)— 兜底配置

为什么是这个顺序?因为每一层对应不同的使用场景和持久性:

默认值是开发者预设的合理配置,保证”零配置也能跑”。它们硬编码在代码里,用户不需要操心。

配置文件是用户的日常偏好——“我这个项目一直用这个模型、这个超时、这些 MCP 服务器”。写一次,每次启动自动读取。

环境变量是敏感信息和部署环境的载体——API 密钥不应该写在配置文件里(它会被提交到版本控制),而应该放在环境变量里。不同的部署环境(开发、测试、生产)通过环境变量切换。

命令行参数是临时覆盖——“这次我想试试另一个模型""这次多跑几轮”。不影响配置文件,下次启动就恢复原样。

配置合并的实现很直接:

# harness/config.py — 配置合并逻辑
def load_config(cli_args: dict) -> Config:
    """按优先级合并配置:CLI > env > file > defaults"""
    # 1. 从默认值开始
    config = DEFAULT_CONFIG.copy()

    # 2. 叠加配置文件
    config_file = find_config_file()
    if config_file:
        file_config = toml.load(config_file)
        config = deep_merge(config, file_config)

    # 3. 叠加环境变量
    env_config = load_env_config()
    config = deep_merge(config, env_config)

    # 4. 叠加 CLI 参数(最高优先级)
    config = deep_merge(config, cli_args)

    return Config(**config)

deep_merge 是关键——它不是简单的字典覆盖,而是递归合并。如果配置文件里定义了 [tools] timeout = 30,CLI 传了 --model xxx,合并后 tools.timeout 保留 30,model 被覆盖为 xxx。互不干扰。

配置文件的位置

配置文件去哪里找?按照惯例,搜索顺序是:

  1. 项目级——当前目录下的 .harness/config.toml,只对这个项目生效
  2. 用户级——~/.harness/config.toml,对这个用户的所有项目生效
  3. 系统级——/etc/harness/config.toml,对这台机器的所有用户生效

找到第一个就用,不再往下找。这和 Git 的 .gitconfig 搜索逻辑一致——先看项目级(.git/config),再看用户级(~/.gitconfig),再看系统级(/etc/gitconfig)。

Claude Code 也遵循同样的模式:项目级 .claude/settings.json 覆盖用户级 ~/.claude/settings.json。

启动顺序

Prompt 3 要求”按正确的顺序初始化”。为什么顺序重要?因为模块之间有依赖关系——权限系统需要知道有哪些工具才能匹配规则,钩子需要在查询引擎开始前就注册好,记忆加载需要在第一次对话之前完成。

图 10-2:Harness 启动顺序——每一步都依赖前一步的结果

  1. 加载配置 → 读取 CLI 参数、环境变量、配置文件,合并为最终配置
  2. 初始化查询引擎 → 创建 API 客户端,验证 API 密钥和模型可用性
  3. 注册内置工具 → 把 file_read、bash、grep 等工具注册到 ToolRegistry
  4. 连接 MCP 服务器 → 启动外部服务器进程,发现工具,合并到 ToolRegistry
  5. 加载权限规则 → 读取规则文件,绑定到 ToolRegistry 的工具列表
  6. 注册钩子与技能 → 加载钩子配置,注册到对应的生命周期事件
  7. 加载记忆 → 读取热记忆文件,准备注入系统提示词
  8. 启动终端界面 → 初始化 Rich 渲染器,显示启动报告,进入对话循环

注意第 4 步(连接 MCP 服务器)必须在第 3 步(注册内置工具)之后——因为 MCP 工具要合并到同一个 ToolRegistry。第 5 步(权限规则)必须在第 4 步之后——因为权限规则可能匹配 MCP 工具。第 6 步(钩子)必须在第 7 步(记忆)之前——因为 session_start 钩子可能会触发记忆加载。

这种**有向无环图(DAG)**的依赖关系在所有复杂系统的启动过程中都存在:操作系统先启动内核再启动用户服务、Web 框架先加载路由再接受请求、数据库先恢复日志再打开端口。

优雅降级

“MCP 服务器连不上”不应该阻止整个系统启动。设计原则是区分关键依赖和可选依赖:

模块级别失败时的行为
配置系统关键报错退出——没有配置什么都跑不了
API 客户端关键报错退出——没有 API 密钥就没法对话
内置工具关键报错退出——没有工具的 Agent 是残废的
MCP 服务器可选记录警告,跳过,继续启动
权限规则可选使用默认规则(全部需要确认)
钩子可选记录警告,跳过,功能不受影响
记忆可选从空白记忆开始,不影响对话
终端渲染降级回退到纯文本输出

关键依赖失败就退出并给出清晰的错误信息。可选依赖失败就降级运行——少了几个 MCP 工具,Agent 还是能对话、能用内置工具。这种优雅降级的设计让系统在各种环境下都能尽可能地工作。

测试策略

发布前要测试。但 AI Agent 的测试和普通软件不一样——AI 的回复是非确定性的,你没法写一个测试断言”AI 一定会说这句话”。那怎么测?

答案是分层测试——不同层面用不同的测试方法:

层级测什么怎么测确定性
单元测试工具注册、配置解析、权限匹配等纯逻辑标准 pytest,mock 外部依赖100%
集成测试模块间的连接——工具调用过权限、MCP 工具合并启动真实模块,mock API 调用高
端到端测试完整的对话流程——启动、对话、工具调用、退出真实 API + 录制回放中等
行为测试AI 是否正确使用工具、是否遵守权限、输出是否合理人工审查 + 模式匹配低

单元测试:确定性的部分

系统中大量的逻辑是确定性的——不涉及 AI。这些可以用标准的单元测试覆盖:

# tests/test_config.py — 配置优先级测试
def test_cli_overrides_file():
    file_config = {"model": "haiku", "max_turns": 100}
    cli_args = {"model": "sonnet"}
    result = merge_config(file_config, cli_args)
    assert result["model"] == "sonnet"       # CLI 胜出
    assert result["max_turns"] == 100         # 文件保留

def test_permission_rule_matching():
    rule = Rule(tool="bash", command="rm *", action="deny")
    assert rule.matches("bash", {"command": "rm -rf /"})
    assert not rule.matches("file_read", {"path": "x"})

这类测试跑得快、结果稳定、覆盖面广。你的 Agent 里有大量这样的纯逻辑——配置解析、权限匹配、工具注册、钩子触发条件、命令解析、记忆文件格式。先把确定性的部分测到 90% 以上覆盖率。

端到端测试:录制与回放

涉及 AI 的测试用录制回放模式:第一次跑测试时真正调用 API,把请求和响应录下来存成文件。以后跑测试时回放录制的响应,不再调 API——既省钱又确定。

# tests/test_e2e.py — 录制回放测试
@pytest.fixture
def recorded_session():
    """加载录制好的会话"""
    return load_recording("tests/recordings/basic_chat.json")

def test_basic_conversation(recorded_session):
    app = create_app(config=test_config)
    result = app.replay(recorded_session)
    assert result.exit_code == 0
    assert result.turns >= 1
    assert "error" not in result.output.lower()

行为测试:模式匹配

AI 的输出虽然不确定,但可以验证模式——“AI 应该调用了某个工具""AI 不应该执行危险命令""AI 的回复应该包含某些关键信息”:

# tests/test_behavior.py — 行为模式验证
def test_ai_uses_file_read_for_code_questions():
    response = run_session("帮我看看 main.py 里写了什么")
    assert any(
        call.tool == "file_read"
        for call in response.tool_calls
    ), "AI should use file_read for code questions"

def test_ai_respects_permission_denial():
    response = run_session(
        "删除所有测试文件",
        permission_response="deny",
    )
    assert not any(
        call.tool == "bash" and "rm" in call.args.get("command", "")
        for call in response.tool_calls
    ), "AI should not execute rm after denial"

完整架构回顾

十章走下来,让我们站远一点,看看整个系统的全貌。

图 10-3:Harness 完整架构——从用户输入到模块协作的全景

                    ┌──────────┐
                    │   用户   │
                    └────┬─────┘
                         │
                         ▼
              ┌─────────────────────┐
              │     终端界面        │
              │ Rich 渲染·命令·多行  │
              └────────┬────────────┘
                       │
                       ▼
              ┌─────────────────────┐
              │     查询引擎        │
              │ while(true)·流式·压缩│
              └──┬─────┬─────┬──────┘
                 │     │     │
         ┌───────┘     │     └───────┐
         ▼             ▼             ▼
   ┌──────────┐  ┌──────────┐  ┌──────────┐
   │ 工具系统 │  │Agent 编排│  │ 权限系统 │
   │定义·注册 │  │委托·后台 │  │分级·规则 │
   └────┬─────┘  └────┬─────┘  └────┬─────┘
        │             │             │
        ▼             ▼             ▼
   ┌──────────┐  ┌──────────┐  ┌──────────┐
   │ MCP 集成 │  │钩子与技能│  │ 记忆系统 │
   │客户端·服端│  │生命周期  │  │热记忆·冷 │
   └────┬─────┘  └────┬─────┘  └────┬─────┘
        │             │             │
        └─────────────┼─────────────┘
                      ▼
        ┌───────────────────────────┐
        │        配置系统           │
        │ CLI·环境变量·配置文件·默认值│
        └───────────────────────────┘

从上往下看:

用户通过终端界面输入(第 9 章),终端把输入交给查询引擎(第 2 章)。查询引擎是核心循环——它调用 LLM,LLM 返回工具调用请求时,引擎通过工具系统(第 3 章)执行。执行前要过权限系统(第 4 章)的检查。工具列表包含内置工具和通过MCP 集成(第 8 章)接入的外部工具。

复杂任务由Agent 编排(第 5 章)拆分给子 Agent。跨会话的上下文由记忆系统(第 6 章)持久化。整个流程中,钩子与技能(第 7 章)在关键时刻插入自定义逻辑。所有模块的行为由底层的配置系统(本章)控制。

这不是一个理论架构图——这是你在过去十章中亲手构建的系统。

💡 核心概念:模块化的代价与收益

九个模块、九章内容——为什么要分这么细?直接写一个大文件不行吗?

行。但只能行一次。

短期看,一个大文件更快——不用想模块边界,不用定义接口,想到哪写到哪。但当你想加一个新的 MCP 服务器、改一条权限规则、换一种终端渲染方式时,你必须在一团纠缠的代码里小心翼翼地修改,祈祷不会弄坏别的功能。

长期看,模块化的收益是变更的局部性——改权限规则不影响终端渲染,加 MCP 工具不影响记忆系统。每个模块有清晰的边界和接口,修改一个模块时你只需要理解这一个模块的代码。

这正是 Claude Code 的做法:五万行代码分成 core/、tools/、permissions/、hooks/、memory/、skills/ 等目录,每个目录独立演进。它能从最初的版本迭代到今天的复杂度,靠的就是这种模块化纪律。

Claude Code 的产品化

我们从九个模块组装出了一个可运行的 Agent。Claude Code 做了同样的事——但从”可运行”到”每天被数百万开发者使用的产品”,它还多走了很多步。

分发方式

Claude Code 通过 npm 分发——npm install -g @anthropic-ai/claude-code,一条命令全球可用。npm 是 JavaScript/TypeScript 生态的包管理器,安装后在 PATH 里注册 claude 命令。

为什么不用独立安装包?因为 npm 解决了依赖管理和跨平台两个难题。Node.js 运行在 macOS、Linux、Windows 上,npm 自动处理平台差异。

我们的 harness 用 pip——Python 生态的等价物。pip install harness 安装后注册 harness 命令。原理完全一样,只是生态不同。

版本管理

Claude Code 遵循语义化版本(semver):MAJOR.MINOR.PATCH。

  • PATCH(0.0.x)——修 bug,不改接口
  • MINOR(0.x.0)——加功能,向后兼容
  • MAJOR(x.0.0)——改接口,可能不兼容

每次发版都有 changelog 记录变更。用户可以锁定版本(npm install @anthropic-ai/claude-code@1.2.3)避免意外升级。

自动更新

Claude Code 在启动时检查是否有新版本——如果有,提示用户更新。这个检查是非阻塞的:在后台发一个 HTTP 请求查最新版本号,和启动初始化并行进行。如果网络不通或者超时,就跳过,不影响正常使用。

遥测与反馈

产品需要知道用户怎么用它。Claude Code 收集匿名使用数据——用了哪些功能、平均对话轮数、最常用的工具——帮助团队做产品决策。关键原则:

  • 可选退出——用户可以关闭遥测
  • 匿名化——不收集对话内容和代码
  • 透明——文档里明确说明收集了什么

从 Harness 到产品

你现在手里有了一个完整的 Agent Harness。接下来往哪走?取决于你想用它做什么。

图 10-4:从 Harness 到产品的演进路线

  1. [已完成] 核心功能 — 查询引擎 · 工具 · 权限 · 编排 · 记忆 · 钩子 · MCP · 终端
  2. [已完成] 产品化 — 配置 · 启动 · 测试 · 打包 ← 当前位置
  3. [下一步] 领域定制 — 针对特定场景定制 Prompt · 工具 · 技能
  4. [进阶] Web 界面 — 事件驱动已就绪,加 WebSocket 前端
  5. [远期] 多用户部署 — 认证 · 隔离 · 计费 · 监控

领域定制

Harness 是通用框架,但真正的价值在领域定制。几个方向:

代码审查 Agent——预装 code-review 技能,配置只读工具权限,加上 Git 集成钩子,专门做代码审查。

运维 Agent——接入服务器监控的 MCP 工具,配置严格的权限规则(只能查看不能修改),专门做故障排查。

文档 Agent——预装文档生成技能,接入 Markdown/Typst 渲染工具,专门帮团队写和维护文档。

每种定制都不需要改核心代码——通过配置文件、技能包、钩子、MCP 工具就能完成。这就是模块化架构的回报。

Web 界面

第 9 章我们用事件驱动架构解耦了业务逻辑和终端渲染。要做 Web 界面,只需要写一个新的事件消费者——监听同样的事件,通过 WebSocket 推送到浏览器:

图 10-5:同一套事件驱动架构适配多种界面

  1. 业务逻辑 → yield Event(…)
  2. 事件分发器 → 路由到消费者
  3. 终端 / Web / API → 各自渲染

核心循环一行不改,换个渲染器就从终端应用变成了 Web 应用。

多用户部署

如果要把你的 Agent 部署为服务——多个用户同时使用——还需要考虑:

  • 认证——谁能用?用户身份怎么验证?
  • 隔离——A 用户的对话不能泄露给 B 用户
  • 计费——每个用户用了多少 token、该收多少钱
  • 监控——系统健康状况、错误率、响应时间

这些超出了本书的范围,但架构已经为此做好了准备——配置系统支持多租户、权限系统支持角色、事件系统支持审计日志。


延伸思考

这是本书的最后三个问题。不急着回答,带着它们去实践:

  1. 我们的配置系统用了”CLI > 环境变量 > 配置文件 > 默认值”的优先级。但如果有些配置不应该被 CLI 参数覆盖呢——比如安全相关的权限规则,你不希望有人用 --no-permissions 就绕过整个权限系统。你会怎么设计”不可覆盖的配置”?
  2. 你现在有了一个完整的 Agent Harness,也看了 Claude Code 的架构。如果让你从零重新设计,你会做哪些不同的决策?哪些模块你会合并,哪些你会进一步拆分?
  3. AI Agent 的能力边界在快速扩张——从文本对话到代码编写到工具使用到多 Agent 协作。作为 Harness 的构建者,你觉得下一个需要加入的”模块”是什么?为什么?

章节小结

这是本书的最后一章,也是整个旅程的终点。让我们回顾走过的路:

  • 第 1 章我们认识了 Harness——它不是 wrapper,不是 prompt engineering,而是 AI Agent 的运行时编排系统
  • 第 2 章我们造出了心脏——一个 while(true) 循环驱动的查询引擎,支持流式输出和上下文压缩
  • 第 3 章我们装上了手脚——工具系统让 Agent 能读文件、写文件、跑命令、搜代码
  • 第 4 章我们装上了刹车——权限系统用风险分级和规则引擎确保 Agent 不会失控
  • 第 5 章我们学会了派活——Agent 编排让复杂任务拆给多个 AI 分头完成
  • 第 6 章我们赋予了记忆——热记忆和冷记忆让 Agent 跨会话保持上下文
  • 第 7 章我们打开了扩展——钩子和技能让 Agent 的行为可以无限定制
  • 第 8 章我们连接了生态——MCP 协议让 Agent 既能借用别人的工具,也能暴露自己的能力
  • 第 9 章我们打磨了体验——彩色输出、进度反馈、命令系统、多行输入让 Agent 用着舒服
  • 第 10 章我们完成了组装——配置、启动、测试、打包,从一堆模块变成了一个产品

十章,三十多个 Prompt,一个完整的 AI Agent Runtime。

你不只是读了一本关于 AI Agent 的书——你造了一个。它能对话、能动手、有权限、会记忆、可扩展、连生态、体验好、一条命令安装。

这个 Harness 是你的。拿它去定制、去部署、去改造。把它变成代码审查助手、运维诊断专家、文档写作伙伴——或者任何你能想到的东西。

AI Agent 的时代刚刚开始。你现在不只是用户,你是构建者。

English EN 简体中文 ZH