0

ch-16

约 15000 字DraftOpenClaw Book

第 16 章 · Agent 高级模式

到目前为止,你看到的 Agent 模式都是"一对一"——一条消息进来,一个 Agent 处理,一个回复出去。但真实的复杂任务往往需要 Agent 分身术、浏览器自动化、Web 集成、记忆检索。这一章解锁 Agent 的高级能力,让它从"单兵作战"进化到"团队协作"。

本章你将学到:

  • 子 Agent 嵌套——如何让 Agent 派生"分身"并行工作
  • 浏览器自动化——Agent 如何像人一样操作网页
  • Web 搜索与抓取——让 Agent 接入互联网信息流
  • 记忆系统——从短期对话到长期知识的跃迁
  • 思考模式、打字指示器、反应等高级交互能力

16.1 子 Agent:让 Agent 拥有"分身术"

子 Agent(Sub-agents)是 OpenClaw 中最强大的并发模式。它允许主 Agent 在处理任务时派生独立的"分身"去并行执行子任务,完成后自动汇报结果。

16.1.1 为什么需要子 Agent

想象一个场景:用户说"帮我同时查一下三个项目的 GitHub Stars 数和最近一周的提交数"。

没有子 Agent 时,Agent 只能串行执行——查完项目 A,再查项目 B,再查项目 C。每次查询都需要模型调用,总耗时可能是 30 秒。

有了子 Agent,Agent 可以同时派生三个分身,每个负责一个项目。并行执行,总耗时缩短到 10 秒。

没有子 Agent:
  用户 → [查 A] → [查 B] → [查 C] → 回复
  总耗时:30s

有子 Agent:
  用户 → [查 A] ─┐
        [查 B] ─┤→ 汇总 → 回复
        [查 C] ─┘
  总耗时:10s

16.1.2 子 Agent 的生命周期

主 Agent 调用 sessions_spawn
    │
    ▼
[1] Gateway 创建子会话
    │ 会话键:agent:<agentId>:subagent:<uuid>
    │ 队列:subagent(独立于主队列)
    │
    ▼
[2] 子 Agent 开始运行
    │ 独立的上下文、独立的工具调用
    │ 默认继承父 Agent 的模型
    │
    ▼
[3] 子 Agent 完成(或超时/失败)
    │
    ▼
[4] 汇报(Announce)
    │ 结果注入父 Agent 的会话上下文
    │ 包含:结果文本、状态、Token 用量
    │
    ▼
[5] 父 Agent 综合所有子 Agent 的结果
    │ 生成最终回复
    ▼
[6] 用户收到回复

16.1.3 基本用法

子 Agent 通过 sessions_spawn 工具调用:

// Agent 内部调用 sessions_spawn
{
  task: "查询项目 A 的 GitHub Stars 和最近一周提交数",
  label: "project-a-research",
  model: "anthropic/claude-sonnet-4-6",  // 可选,覆盖默认模型
  thinking: "low",                       // 可选,使用轻量思考
  runTimeoutSeconds: 300,                // 可选,超时时间
}

工具立即返回 { status: "accepted", runId, childSessionKey }——非阻塞。

你也可以通过命令行手动派生:

/subagents spawn main "分析这个日志文件中的错误模式" --model sonnet
/subagents list              # 查看当前会话的所有子 Agent
/subagents log 1             # 查看子 Agent #1 的日志
/subagents kill all          # 终止所有子 Agent

16.1.4 成本控制

每个子 Agent 有独立的上下文和 Token 用量。这意味着三个子 Agent 并行运行,Token 消耗是三倍。

省钱策略:给子 Agent 用便宜模型,主 Agent 用高质量模型。

{
  agents: {
    defaults: {
      subagents: {
        model: "anthropic/claude-sonnet-4-6",  // 子 Agent 用 Sonnet
        thinking: "low",                       // 子 Agent 用轻量思考
        runTimeoutSeconds: 300,                // 默认超时 5 分钟
      },
    },
  },
}

主 Agent 可以用 Opus 做决策和综合,子 Agent 用 Sonnet 做具体的检索和分析工作。这种"重指挥、轻执行"的模式在大多数场景下既省钱又高效。

16.1.5 嵌套子 Agent:编排者模式

默认情况下,子 Agent 不能再派生子 Agent(maxSpawnDepth: 1)。你可以开启二级嵌套,实现"编排者-工人"模式:

{
  agents: {
    defaults: {
      subagents: {
        maxSpawnDepth: 2,          // 允许子 Agent 再派生子 Agent
        maxChildrenPerAgent: 5,    // 每个 Agent 最多 5 个活跃子级
        maxConcurrent: 8,          // 子 Agent 全局并发上限
        runTimeoutSeconds: 900,
      },
    },
  },
}
主 Agent(Depth 0)
  │
  ├─ 编排者子 Agent(Depth 1)
  │    ├─ 工人子子 Agent A(Depth 2)
  │    ├─ 工人子子 Agent B(Depth 2)
  │    └─ 工人子子 Agent C(Depth 2)
  │
  ├─ 编排者子 Agent(Depth 1)
  │    ├─ 工人子子 Agent D(Depth 2)
  │    └─ 工人子子 Agent E(Depth 2)
  │
  └─ 独立子 Agent(Depth 1)

结果汇报遵循链条:Depth-2 工人 → Depth-1 编排者 → 主 Agent。每一层只看到直接子级的汇报。

⚠️ 注意:最大嵌套深度是 5(maxSpawnDepth 范围 1-5)。但 Depth 2 对大多数场景已经足够,更深的嵌套容易失控且调试困难。

16.1.6 工具策略隔离

子 Agent 默认不获得会话工具(sessions_listsessions_sendsessions_spawn)。这防止了子 Agent 意外操作其他会话。

你可以通过配置覆盖:

{
  tools: {
    subagents: {
      tools: {
        deny: ["gateway", "cron"],  // 禁止子 Agent 访问 Gateway 和 Cron
        // allow: ["read", "exec", "process"]  // 或者白名单模式
      },
    },
  },
}

deny 始终优先于 allow。即使你设了 allow: ["*"]deny 中的工具仍然不可用。

16.1.7 自动归档

子 Agent 会话在完成后不会永远保留。默认 60 分钟后自动归档:

{
  agents: {
    defaults: {
      subagents: {
        archiveAfterMinutes: 60,  // 默认 60 分钟
      },
    },
  },
}

归档操作会删除会话条目,但保留转录文件(重命名为 *.deleted.<timestamp>)。如果你需要立即清理,可以在 sessions_spawn 时设置 cleanup: "delete"

16.1.8 Discord 线程绑定

在 Discord 中,子 Agent 可以绑定到一个线程,让线程中的后续消息自动路由到同一个子 Agent 会话:

// Agent 调用 sessions_spawn 时启用线程绑定
{
  task: "分析这段代码的性能瓶颈",
  thread: true,        // 启用线程绑定
  mode: "session",      // 持久会话模式(而非一次性 run)
}

用户在线程中的后续消息会自动路由到这个子 Agent,而不需要回到主 Agent。使用 /unfocus 可以解除绑定。

{
  session: {
    threadBindings: {
      enabled: true,
      idleHours: 4,         // 4 小时无活动自动解除绑定
      maxAgeHours: 24,      // 最长绑定 24 小时
    },
  },
}

16.2 浏览器自动化:让 Agent 操作网页

OpenClaw 内置了一个完整的浏览器自动化系统。Agent 可以像人一样打开网页、点击按钮、填写表单、截取屏幕。

16.2.1 两种浏览器模式

openclaw 配置文件(隔离):
  → 独立的浏览器实例,不影响你的个人浏览器
  → Agent 可以自由操作,不会干扰你的登录状态
  → 适合:自动化任务、数据采集、测试

user 配置文件(已有会话):
  → 附加到你已登录的 Chrome/Brave 浏览器
  → 可以使用你的登录态
  → 适合:需要在已登录状态下操作的场景

默认使用 openclaw 隔离配置文件。切换到 user 配置文件:

{
  browser: {
    defaultProfile: "openclaw",  // 默认隔离模式
  },
}

16.2.2 浏览器架构

┌─────────────────────────────────────────────┐
│              Gateway                         │
│                                              │
│  Agent ──→ browser 工具 ──→ 浏览器控制服务   │
│                                  │          │
│                           CDP 协议           │
│                                  │          │
│                          ┌───────┴───────┐   │
│                          │  Chromium      │   │
│                          │  (Chrome/Brave)│   │
│                          └───────────────┘   │
└─────────────────────────────────────────────┘

CDP = Chrome DevTools Protocol
浏览器控制服务只监听 loopback(127.0.0.1)

浏览器控制服务是一个轻量级 HTTP 服务,只绑定到 loopback。它通过 CDP(Chrome DevTools Protocol)控制 Chromium 内核浏览器。高级操作(点击、输入、快照)通过 Playwright 实现。

16.2.3 快照(Snapshot):Agent "看到"网页的方式

Agent 不是"看"网页截图,而是通过"快照"理解页面结构。快照是页面的无障碍树(Accessibility Tree)的文本表示:

snapshot 输出示例:
  [1] heading: "登录"
  [2] textbox: "邮箱"
  [3] textbox: "密码"
  [4] button: "登录"
  [5] link: "忘记密码?"

Agent 使用数字引用(ref)来操作元素:

Agent: "我看到登录表单了"
  → 调用 browser({ action: "snapshot" })
  → 收到快照,识别出 ref 2 是邮箱输入框
  → 调用 browser({ action: "act", ref: 2, kind: "type", text: "user@example.com" })
  → 调用 browser({ action: "act", ref: 4, kind: "click" })

引用不是跨导航稳定的——每次导航后需要重新获取快照。

16.2.4 远程浏览器

浏览器不一定在 Gateway 所在的机器上。OpenClaw 支持三种远程方案:

1. Node 代理(零配置默认)
   → 在有浏览器的机器上运行 Node Host
   → Gateway 自动将浏览器操作代理到该 Node
   → 适合:Gateway 在 VPS 上,浏览器在本地

2. 远程 CDP
   → 直接连接到远程 Chromium 的调试端口
   → 适合:Browserless、Browserbase 等托管浏览器服务

3. 浏览器即服务
   → Browserless: wss://production-sfo.browserless.io?token=<key>
   → Browserbase: wss://connect.browserbase.com?apiKey=<key>
   → 适合:需要无头浏览器、CAPTCHA 解决、住宅代理

Browserless 配置示例:

{
  browser: {
    enabled: true,
    defaultProfile: "browserless",
    profiles: {
      browserless: {
        cdpUrl: "wss://production-sfo.browserless.io?token=<BROWSERLESS_API_KEY>",
      },
    },
  },
}

16.2.5 SSRF 防护

浏览器自动化有一个安全风险:SSRF(Server-Side Request Forgery)。Agent 可能通过浏览器访问内网资源。

OpenClaw 默认启用信任网络模式(dangerouslyAllowPrivateNetwork: true),允许访问内网。如果需要严格限制:

{
  browser: {
    ssrfPolicy: {
      dangerouslyAllowPrivateNetwork: false,
      hostnameAllowlist: ["*.example.com"],
      allowedHostnames: ["localhost"],
    },
  },
}

16.2.6 安全注意事项

⚠️ 浏览器控制的安全边界:

1. openclaw 配置文件可能包含登录会话 → 视为敏感数据
2. browser evaluate 可以在页面上下文中执行任意 JS → 可被 Prompt 注入利用
   → 如果不需要,设 browser.evaluateEnabled = false
3. user 配置文件操作你的真实登录态 → 仅在用户在场时使用
4. 远程 CDP 端点非常强大 → 使用加密端点(HTTPS/WSS)和短期 Token

16.3 Web 搜索:接入互联网信息流

OpenClaw 的 web_search 工具让 Agent 能搜索互联网。它是一个轻量级 HTTP 工具,不是浏览器自动化——适合快速搜索,不适合需要 JS 渲染的页面。

16.3.1 搜索提供商选择

结构化结果(推荐):
  Brave Search     → 有免费层,支持 llm-context 模式
  Perplexity       → 支持域名过滤和内容控制
  Tavily           → 支持搜索深度和主题过滤

AI 综合结果:
  Gemini           → Google Search 作为基础,返回 AI 综合答案
  Grok             → xAI Web Grounding,返回 AI 综合答案
  Kimi             → Moonshot Web Search,返回 AI 综合答案

免密钥(回退):
  DuckDuckGo       → 无需 API Key,非官方 HTML 解析

深度提取:
  Exa              → 神经搜索 + 关键词搜索,支持内容提取
  Firecrawl        → 结构化结果 + 深度抓取

16.3.2 自动检测

如果没配置 provider,OpenClaw 按以下顺序检测 API Key,用第一个找到的:

Brave → Gemini → Grok → Kimi → Perplexity → Firecrawl → Tavily

检测逻辑:检查环境变量(如 BRAVE_API_KEY)和配置文件中的 Key。

# 快速配置(自动检测)
openclaw configure --section web

16.3.3 配置

{
  tools: {
    web: {
      search: {
        enabled: true,
        provider: "brave",
        maxResults: 5,
        timeoutSeconds: 30,
        cacheTtlMinutes: 15,  // 相同查询 15 分钟内使用缓存
      },
    },
  },
}

16.3.4 搜索 vs 抓取 vs 浏览器

web_search(搜索)
  → 关键词搜索,返回结果列表
  → 适合:"最近的 AI 新闻"
  → 不执行 JS

web_fetch(抓取)
  → 获取特定 URL 的内容
  → 适合:"帮我读一下这篇文章"
  → 不执行 JS,支持 Readability 提取

browser(浏览器)
  → 完整浏览器自动化
  → 适合:"帮我登录这个网站并导出数据"
  → 执行 JS,支持登录态

16.3.5 Web Fetch:HTTP 抓取

web_fetch 是 OpenClaw 默认启用的工具。它做三件事:

1. HTTP GET 请求
   → 使用类 Chrome 的 User-Agent
   → 阻止私有/内部主机名
   → 检查重定向

2. Readability 提取
   → 从 HTML 中提取主要内容
   → 转换为 Markdown 或纯文本

3. Firecrawl 回退(可选)
   → 如果 Readability 失败,通过 Firecrawl API 重试
   → 支持 bot 规避模式
{
  tools: {
    web: {
      fetch: {
        enabled: true,
        maxChars: 50000,          // 最大输出字符数
        maxResponseBytes: 2000000, // 最大下载大小
        timeoutSeconds: 30,
        cacheTtlMinutes: 15,
        readability: true,        // 使用 Readability 提取
      },
    },
  },
}

Firecrawl 回退配置:

{
  tools: {
    web: {
      fetch: {
        firecrawl: {
          enabled: true,
          apiKey: "fc-...",       // 或使用 FIRECRAWL_API_KEY 环境变量
          onlyMainContent: true,
        },
      },
    },
  },
}

16.3.6 LLM Task:结构化 LLM 输出

llm-task 是一个可选的插件工具,专门用于在自动化工作流中获取结构化的 JSON 输出:

// 启用插件
{
  plugins: {
    entries: {
      "llm-task": { enabled: true },
    },
  },
}

// 允许工具
{
  agents: {
    list: [
      { id: "main", tools: { allow: ["llm-task"] } },
    ],
  },
}

使用示例——给定一封邮件,返回意图和草稿:

{
  prompt: "Given the input email, return intent and draft.",
  thinking: "low",
  input: {
    subject: "关于下周的会议",
    body: "我们能不能把会议改到周三?",
  },
  schema: {
    type: "object",
    properties: {
      intent: { type: "string" },
      draft: { type: "string" },
    },
    required: ["intent", "draft"],
  },
}

llm-task 是 JSON-only 的——模型只输出 JSON,没有代码围栏、没有评论。如果提供了 schema,输出会通过 JSON Schema 验证。

⚠️ 安全提示llm-task 不暴露任何工具给模型。输出应该被视为不受信任的——除非通过 schema 验证。

16.4 记忆系统:从对话到知识的跃迁

Agent 的上下文窗口是有限的。当对话被压缩或会话被重置时,没有写入磁盘的信息就会丢失。记忆系统就是解决"信息持久化"的机制。

16.4.1 记忆 = Markdown 文件

OpenClaw 的记忆系统极其简单——就是工作空间中的 Markdown 文件:

~/.openclaw/workspace/
├── MEMORY.md              # 长期记忆(策展的、重要的信息)
└── memory/
    ├── 2026-03-27.md      # 每日日志
    ├── 2026-03-28.md      # 今天的日志
    └── ...

两层记忆:

层级 文件 内容 加载时机
长期 MEMORY.md 重要的决策、偏好、事实 每次会话启动时(仅私聊)
短期 memory/YYYY-MM-DD.md 日常笔记、运行上下文 读取今天 + 昨天

关键原则:模型只"记住"写入磁盘的内容。如果用户说"记住我喜欢深色主题",Agent 应该写入 MEMORY.md,而不是只在对话中说"好的我记住了"。

16.4.2 记忆工具

Agent 有两个记忆相关的工具:

memory_search → 语义搜索已索引的记忆片段
  → 适合:"我之前说过什么关于部署的?"

memory_get → 读取特定的 Markdown 文件/行范围
  → 适合:"看看昨天的日记"

memory_get 在文件不存在时不会报错——它返回空文本,让 Agent 可以优雅处理"还没有记录"的情况。

16.4.3 自动记忆刷盘

当会话接近自动压缩时,OpenClaw 会触发一个静默的 Agent 轮次,提醒 Agent 把重要信息写入磁盘:

{
  agents: {
    defaults: {
      compaction: {
        reserveTokensFloor: 20000,
        memoryFlush: {
          enabled: true,
          softThresholdTokens: 4000,
          // 软阈值 = contextWindow - reserveTokensFloor - softThresholdTokens
          // 当剩余空间低于 softThresholdTokens 时触发刷盘
          systemPrompt: "Session nearing compaction. Store durable memories now.",
          prompt: "Write any lasting notes to memory/YYYY-MM-DD.md; reply with NO_REPLY if nothing to store.",
        },
      },
    },
  },
}

刷盘默认是静默的——提示中包含 NO_REPLY,所以用户不会看到这个轮次。每个压缩周期只刷盘一次。

16.4.4 向量记忆搜索

OpenClaw 可以在 MEMORY.mdmemory/*.md 上构建向量索引,支持语义搜索:

用户说:"上次讨论的那个数据库方案叫什么?"
  → memory_search("数据库方案")
  → 向量索引找到语义相关的记忆片段
  → 即使措辞不同也能匹配

混合搜索(BM25 + 向量)结合了语义匹配和精确关键词查找。默认的 memory-core 插件支持多种嵌入提供商:

OpenAI、Gemini、Voyage、Mistral、Ollama、本地 GGUF 模型

以及可选的 QMD 后端,提供 MMR 多样性重排序和时间衰减等高级功能。

16.5 思考模式:控制模型的"深度思考"

OpenClaw 支持通过指令控制模型的推理深度。不同级别的思考模式适合不同复杂度的任务。

16.5.1 思考级别

/think off     → 不使用推理(最快,最便宜)
/think minimal → 轻度推理(别名:think)
/think low     → 基础推理(别名:think hard)
/think medium  → 中度推理(别名:think harder)
/think high    → 深度推理(别名:ultrathink,最大预算)
/think xhigh   → 超深度推理(仅 GPT-5.2 + Codex)
/think adaptive → 自适应推理(仅 Claude 4.6,Provider 管理预算)

16.5.2 优先级解析

1. 消息内联指令(/think:high 这条消息用深度推理)
2. 会话覆盖(发送 /think:medium 设为会话默认)
3. Agent 级默认(agents.list[].thinkingDefault)
4. 全局默认(agents.defaults.thinkingDefault)
5. 回退:Claude 4.6 → adaptive,其他推理模型 → low,非推理模型 → off

你可以发送一条只有指令的消息来设置会话默认:

用户:/think:high
Agent:Thinking level set to high.

用户:分析这段代码的时间复杂度
Agent:[使用 high 级别推理分析]

16.5.3 快速模式

/fast 切换快速模式——低延迟、低成本的回复模式:

/fast on  → 启用快速模式
  → OpenAI: service_tier=priority + 低推理 + 低冗长
  → Anthropic: service_tier=auto(仅 API Key)

/fast off → 关闭快速模式
  → OpenAI: 标准模式
  → Anthropic: service_tier=standard_only

16.5.4 推理可见性

模型在推理时产生的"思考过程"默认是隐藏的。你可以控制是否展示:

/reasoning off    → 隐藏推理过程(默认)
/reasoning on     → 作为独立消息展示(前缀 "Reasoning:")
/reasoning stream → 实时流式展示(仅 Telegram)

16.5.5 Verbose 模式

/verbose 控制工具调用的可见性:

/verbose off  → 默认,只显示工具失败摘要
/verbose on   → 每个工具调用作为独立消息展示(元数据级)
/verbose full → 完整模式,包含工具输出

Verbose 模式在调试 Agent 行为时特别有用——你可以看到每一步工具调用的输入和输出。

16.6 交互细节:打字指示器、反应与 Markdown 格式化

这些看似微小的交互细节,实际上对用户体验有显著影响。

16.6.1 打字指示器

用户发消息后,"正在输入..."提示能让他们知道 Agent 在工作。OpenClaw 提供了多种触发时机:

{
  agents: {
    defaults: {
      typingMode: "thinking",      // 在第一个推理 Delta 时开始
      typingIntervalSeconds: 6,    // 每 6 秒刷新一次
    },
  },
}
模式 触发时机 适用场景
never 从不显示 静默 Agent
message 第一个非静默文本 Delta 避免静默回复的假指示器
thinking 第一个推理 Delta 需要流式推理时
instant 模型循环一开始就显示 最快反馈

thinking 模式在模型使用流式推理(reasoningLevel: "stream")时才有意义。如果模型不产生推理 Delta,打字指示器不会启动。

16.6.2 反应(Reactions)

Agent 可以在消息上添加或移除 Emoji 反应:

{
  "action": "react",
  "messageId": "msg-123",
  "emoji": "thumbsup"
}
添加反应:emoji 设为具体的 emoji(如 "thumbsup")
移除所有反应:emoji 设为空字符串 ""
移除特定反应:设 remove: true + 具体 emoji

不同通道的反应行为:

通道 移除所有 移除特定
Discord / Slack emoji: "" remove: true
Telegram emoji: "" remove: true
WhatsApp emoji: "" remove: true(映射为空 emoji)
Signal 仅通知控制(reactionNotifications

Signal 的入站反应通知通过配置控制:"off" 禁用,"own"(默认)仅在用户对 Bot 消息反应时通知,"all" 对所有反应通知。

16.6.3 Markdown 格式化管线

Agent 输出 Markdown,但不同聊天通道支持不同的格式语法。OpenClaw 用一个统一的格式化管线解决这个问题:

Agent 输出 Markdown
    │
    ▼
[1] 解析为中间表示(IR)
    → IR = 纯文本 + 样式范围(加粗/斜体/删除/代码/剧透)+ 链接范围
    → 偏移量使用 UTF-16 代码单元(Signal 兼容)
    │
    ▼
[2] 在 IR 上分块(format-first)
    → 内联格式不会跨块断裂
    → 代码围栏作为完整块保留
    │
    ▼
[3] 按通道渲染
    → Slack:  mrkdwn 令牌(*bold*、_italic_、~strike~、`code`)
    → Telegram: HTML 标签(<b>、<i>、<s>、<code>、<a href>)
    → Signal:  纯文本 + text-style 范围

"一次解析,多次渲染"的设计保证了格式在不同通道上的一致性。

表格处理:不同通道对 Markdown 表格的支持程度不同:

{
  channels: {
    signal: { markdown: { tables: "bullets" } },    // Signal: 转为列表
    discord: { markdown: { tables: "code" } },       // Discord: 转为代码块
    whatsapp: { markdown: { tables: "bullets" } },   // WhatsApp: 转为列表
  },
}

选项:code(代码块,默认)、bullets(列表项)、off(不转换,原文透传)。

16.7 时间处理:让 Agent 知道"现在几点"

Agent 需要知道当前时间来做出合理的回复——比如"早上好"还是"晚上好",或者判断一个截止日期是否已过。

16.7.1 消息信封中的时间

每条入站消息都会被包装在一个信封中,包含时间戳:

[Signal Alice +1555 2026-01-18 00:19 PST] hello

时间戳的时区可以配置:

{
  agents: {
    defaults: {
      envelopeTimezone: "local",   // "utc" | "local" | "user" | IANA 时区
      envelopeTimestamp: "on",      // 显示绝对时间
      envelopeElapsed: "on",        // 显示相对时间(+2m)
    },
  },
}
  • local:使用 Gateway 主机的本地时区(默认)
  • utc:使用 UTC
  • user:使用 userTimezone 配置(回退到主机时区)
  • IANA 时区:使用固定时区(如 "Asia/Shanghai"

16.7.2 系统提示词中的时间

系统提示词包含一个"Current Date & Time"部分,告诉模型当前时间和用户时区:

{
  agents: {
    defaults: {
      userTimezone: "America/Chicago",
      timeFormat: "auto",  // "auto" | "12" | "24"
    },
  },
}

timeFormat: "auto" 自动检测用户的习惯(12 小时制或 24 小时制)。你也可以强制指定。

16.8 Presence:在线状态管理

OpenClaw 维护一个轻量级的"在场"(Presence)系统,追踪 Gateway 和所有连接的客户端。

16.8.1 数据来源

在场信息来自四个来源:

1. Gateway 自身
   → 启动时创建一个 "self" 条目
   → 即使没有客户端连接也显示

2. WebSocket 连接
   → 每个成功握手的 WS 客户端创建/更新在场条目
   → CLI 短连接不创建条目(避免刷屏)

3. system-event 信标
   → 客户端可以定期发送信标
   → macOS 应用用这个报告主机名、IP、最后输入时间

4. Node 连接
   → role: node 的连接和普通客户端一样创建在场条目

16.8.2 去重与 TTL

在场条目存储在内存中,使用 instanceId 作为键去重。没有稳定 instanceId 的客户端重连可能显示为重复行。

TTL:5 分钟(超过 5 分钟的条目自动清理)
最大条目数:200(超出后删除最旧的)

SSH 隧道连接的客户端可能显示 127.0.0.1——Gateway 会忽略回环地址的远程 IP,避免覆盖客户端自己报告的真实 IP。

16.9 实战:构建一个研究型 Agent

把本章学到的能力组合起来,构建一个能并行研究、自动记忆、操作网页的研究型 Agent。

16.9.1 工作空间配置

# AGENTS.md
你是一个研究助手。你的工作流程:
1. 理解用户的研究需求
2. 使用 web_search 搜索相关信息
3. 如果需要,使用 web_fetch 获取详细内容
4. 如果需要操作网页(登录、表单),使用 browser 工具
5. 对于复杂研究,使用 sessions_spawn 并行派生子任务
6. 所有重要发现写入 memory/ 目录
7. 使用 /think:medium 进行深度分析

安全规则:
- 不执行任何破坏性操作
- 不在 browser 中输入敏感凭证
- 研究结果标注来源

16.9.2 配置

{
  agents: {
    defaults: {
      thinkingDefault: "medium",
      subagents: {
        model: "anthropic/claude-sonnet-4-6",
        maxSpawnDepth: 2,
        maxChildrenPerAgent: 3,
        maxConcurrent: 4,
        runTimeoutSeconds: 300,
      },
      compaction: {
        memoryFlush: {
          enabled: true,
          softThresholdTokens: 4000,
        },
      },
    },
  },
  tools: {
    web: {
      search: {
        enabled: true,
        provider: "brave",
        maxResults: 5,
      },
      fetch: {
        enabled: true,
        maxChars: 50000,
      },
    },
  },
  browser: {
    enabled: true,
    defaultProfile: "openclaw",
    ssrfPolicy: {
      dangerouslyAllowPrivateNetwork: false,
    },
  },
}

16.9.3 使用示例

用户:帮我研究一下 2026 年最流行的三个 AI Agent 框架,对比它们的功能、定价和社区活跃度

Agent 的执行过程:
1. [思考 medium] 分析需求 → 需要并行研究三个框架
2. [sessions_spawn] 派生三个子 Agent:
   - 子 Agent A:研究框架 A(搜索 + 抓取文档)
   - 子 Agent B:研究框架 B
   - 子 Agent C:研究框架 C
3. [等待] 三个子 Agent 并行执行(各约 30 秒)
4. [汇报] 三个子 Agent 完成后汇报结果
5. [综合] 主 Agent 对比分析,生成表格
6. [记忆] 将关键发现写入 memory/2026-03-28.md
7. [回复] 输出结构化的对比报告

本章小结

  • 子 Agent 让 Agent 能并行执行任务——通过 sessions_spawn 派生,通过 Announce 汇报
  • 子 Agent 有独立的上下文和 Token 消耗——用便宜模型做子任务,用贵模型做综合
  • 编排者模式(maxSpawnDepth: 2)支持"编排者-工人"两层嵌套
  • 浏览器自动化通过 CDP + Playwright 控制 Chromium——支持隔离配置文件和已有会话
  • 远程浏览器(Browserless、Browserbase)适合无头场景和 CAPTCHA 解决
  • Web 搜索(web_search)和 Web 抓取(web_fetch)覆盖了大部分信息获取需求
  • 记忆系统是工作空间中的 Markdown 文件——长期记忆(MEMORY.md)+ 短期日志(memory/*.md)
  • 自动记忆刷盘在压缩前触发,防止信息丢失
  • 思考模式(/think)控制推理深度,快速模式(/fast)降低延迟和成本
  • Markdown 格式化管线实现"一次解析,多次渲染",保证跨通道一致性
  • 在场系统追踪 Gateway 和客户端状态,TTL 5 分钟自动清理

下一步

Agent 有了高级模式(子 Agent、浏览器、Web 集成、记忆),但它的能力边界仍然由 OpenClaw 核心代码决定。下一章进入插件生态与 SDK 开发——通过编写插件和自定义通道/模型提供商,彻底打破能力的边界。