Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

高级功能

本章介绍面向高级用户的功能:工具管理、队列模式、生命周期钩子、沙箱隔离、会话管理和 Web 仪表板。


工具

Octos 在每一轮都把完整的已启用工具集作为可调用的工具规格发送给 LLM。不存在基于使用时近性的延迟加载:工具是否可用由工具策略(allow/deny 列表、命名组)与逐供应商策略控制,而非取决于工具最近是否被使用。

有两类工具会被有意排除在每轮的工具列表之外:

  • spawn_only 工具 —— 后台/发射即忘的技能。它们被自动拦截并在分离的任务中运行,而不作为主会话中的普通可调用规格(它们会向子 agent 暴露)。
  • 内部隐藏工具 —— 分发器目标(如 mofa_make 的逐技能入口),由转发工具在内部调用,但对模型隐藏以保持工具面清爽。

历史: 早期版本采用基于使用时近性的 LRU 方案(约 15 个活跃,其余延迟并通过 activate_tools 元工具重新提升)。该方案在 RFC-0(#1289)中被移除:现代 LLM 能无质量损失地处理完整的约 40–50 个工具集,且始终发送完整列表可保持 prompt 缓存稳定、每个工具都可被发现。

工具配置

可以在运行时通过 /config 斜杠命令配置工具。设置持久化存储在 {data_dir}/tool_config.json 中。

工具设置项类型默认值说明
news_digestlanguage"zh" / "en""zh"新闻摘要的输出语言
news_digesthn_top_stories5-10030Hacker News 抓取的故事数
news_digestmax_rss_items5-10030每个 RSS 源的条目数
news_digestmax_deep_fetch_total1-5020深度抓取的文章总数
news_digestmax_source_chars1000-5000012000每个来源的 HTML 字符上限
news_digestmax_article_chars1000-500008000每篇文章的内容字符上限
deep_crawlpage_settle_ms500-100003000JS 渲染等待时间(毫秒)
deep_crawlmax_output_chars10000-20000050000输出截断上限
web_searchcount1-105默认搜索结果数量
web_fetchextract_mode"markdown" / "text""markdown"内容提取格式
web_fetchmax_chars1000-20000050000内容大小上限
browseraction_timeout_secs30-600300单次操作超时时间
browseridle_timeout_secs60-600300空闲会话超时时间

聊天中的配置命令:

/config                              # 显示所有工具设置
/config web_search                   # 显示 web_search 的设置
/config set web_search.count 10      # 将默认结果数设为 10
/config set news_digest.language en  # 将新闻摘要切换为英文
/config reset web_search.count       # 重置为默认值

优先级顺序(从高到低):

  1. 显式的单次调用参数(工具调用时指定的参数)
  2. /config 覆盖值(存储在 tool_config.json 中)
  3. 硬编码的默认值

工具策略

工具策略控制 Agent 可以使用哪些工具,可在全局、按提供商或按上下文级别进行设置。

全局策略

{
  "tool_policy": {
    "allow": ["group:fs", "group:search", "web_search"],
    "deny": ["shell", "spawn"]
  }
}
  • allow – 如果非空,则只允许使用这些工具。如果为空,则允许所有工具。
  • deny – 始终禁止使用这些工具。deny 优先于 allow。

命名分组

分组展开为
group:fsread_filewrite_fileedit_filediff_edit
group:runtimeshell
group:webweb_searchweb_fetchbrowser
group:searchglobgreplist_dir
group:sessionsspawn

不在命名分组中的工具:send_fileswitch_modelrun_pipelineconfigure_toolcronmessage

通配符匹配

后缀 * 匹配前缀:

{
  "tool_policy": {
    "deny": ["web_*"]
  }
}

这会禁止 web_searchweb_fetch 等工具。

按提供商的策略

为不同的 LLM 模型设置不同的工具集:

{
  "tool_policy_by_provider": {
    "openai/gpt-4o-mini": {
      "deny": ["shell", "write_file"]
    },
    "gemini": {
      "deny": ["diff_edit"]
    }
  }
}

队列模式

队列模式控制 Agent 正在处理上一个请求时,新到达的用户消息如何处理。可通过聊天中的 /queue <mode> 或配置文件中的 queue_mode 设置。

Followup(默认)

顺序处理。每条消息依次等待处理。

  • Agent 处理 A,完成后处理 B,完成后处理 C。
  • 简单且可预测。
  • 当前请求完成前,用户处于等待状态。

Collect

将排队的消息批量合并为一个组合提示。

  • Agent 正在处理 A。用户发送 B,然后 C。
  • A 完成后,B 和 C 合并为一个提示:B\n---\nQueued #1: C
  • 一次 LLM 调用处理整个批次。
  • 适合习惯连续发送多条短消息的用户(在聊天应用中很常见)。

Steer

只保留最新的排队消息,丢弃较旧的。

  • Agent 正在处理 A。用户发送 B,然后 C。
  • A 完成后,B 被丢弃;只处理 C。
  • 适合用户在等待过程中修正或完善问题的场景。
  • 示例:“搜索 X” 然后 “还是搜索 Y 吧” – 只处理 Y。

Interrupt

只保留最新的排队消息并取消正在运行的 Agent。

  • Agent 正在处理 A。用户发送 B,然后 C。
  • A 被取消,B 被丢弃,C 立即开始处理。
  • 对方向修正的响应最快。
  • 当响应速度比完成当前任务更重要时使用。

注意: 当前 Interrupt 和 Steer 共享相同的排空并丢弃行为。不存在飞行中的 Agent 取消——正在运行的 Agent 会在处理最新消息之前完成。真正的飞行中取消功能正在计划中。

Speculative

为每条新消息生成并发的溢出 Agent,同时主 Agent 继续运行。

  • Agent 正在处理 A。用户发送 B,然后 C。
  • B 和 C 各自获得独立的并发 Agent 任务(溢出)。
  • 三者并行运行 – 无阻塞。
  • 最适合 LLM 提供商响应较慢、用户不想等待的场景。
  • 溢出 Agent 使用主 Agent 启动前的会话历史快照。

溢出机制的工作原理

  1. 为第一条消息生成主 Agent。
  2. 主 Agent 运行期间,新消息到达收件箱。
  3. 每条新消息触发 serve_overflow(),生成一个拥有独立流式输出气泡的完整 Agent 任务。
  4. 溢出 Agent 使用主 Agent 启动前的历史快照,避免重复回答主问题。
  5. 所有 Agent 并发运行,结果保存到会话历史中。

已知限制

  • 交互式提示在溢出中无法正常工作:如果 LLM 提出后续问题并返回 EndTurn,溢出 Agent 会退出。用户的回复会生成一个新的溢出,但没有上下文来理解之前的问题。
  • 短回复可能被误分类:“是“或“2“这样的继续确认可能被当作独立的新查询处理。

自动升级

当检测到持续的延迟恶化时,会话 actor 可以自动从 Followup 升级到 Speculative:

  • ResponsivenessObserver 从前 5 次请求中学习中位数基线(对异常值更鲁棒),然后在 20 样本的滚动窗口中跟踪 LLM 响应时间。基线每 20 个样本通过 80/20 EMA 混合当前窗口中位数进行自适应调整,可跟踪渐进漂移。
  • 如果连续 3 次响应超过 3×基线 延迟,同时自动激活 Speculative 队列模式和对冲竞速(Hedge)。
  • 发送用户通知:“检测到响应缓慢,已启用对冲竞速 + 投机队列。”
  • 当提供商恢复(一次正常延迟的响应)时,两者都恢复为 Followup 和静态路由。
  • API 通道(Web 客户端)也会触发自动升级,因为它始终使用投机处理路径。

队列命令

/queue                  -- 显示当前模式
/queue followup         -- 顺序处理
/queue collect          -- 批量合并排队消息
/queue steer            -- 只保留最新消息
/queue interrupt        -- 取消当前任务 + 保留最新消息
/queue speculative      -- 并发溢出 Agent

钩子

钩子是用于执行 LLM 策略、记录指标和审计 Agent 行为的主要扩展点 – 按配置文件定义,无需修改核心代码。

钩子是在 Agent 生命周期事件触发时运行的 shell 命令。每个钩子通过 stdin 接收 JSON 载荷,通过退出码传达决策。

退出码

退出码含义Before 事件After 事件
0允许操作继续执行记录为成功
1拒绝操作被阻止(原因输出到 stdout)视为错误
2+错误记录日志,操作继续执行记录日志

事件

十个生命周期事件。只有三个 before_* 事件可以拒绝(exit 1);其余事件均为只读观察(非零退出会被记录,但不会阻断操作)。

事件触发时机可拒绝
before_tool_call每次工具执行之前
after_tool_call每次工具执行之后
before_llm_call每次 LLM API 调用之前
after_llm_call每次成功的 LLM 响应之后
before_spawn_verify派生子 agent 的验证步骤之前
on_spawn_verify派生子 agent 的验证步骤时
on_spawn_complete派生(后台)任务完成时
on_spawn_failure派生任务失败时
on_turn_end一轮 agent 结束时
on_resume会话/轮次恢复时(如客户端重连后)

四个核心事件携带最丰富的载荷(如下所示);spawn/turn/resume 事件携带相关的任务/会话标识符,外加 eventsession_idprofile_id

before_tool_call

在每次工具执行前触发。可以拒绝(exit 1)。

{
  "event": "before_tool_call",
  "tool_name": "shell",
  "arguments": {"command": "ls -la"},
  "tool_id": "call_abc123",
  "session_id": "telegram:12345",
  "profile_id": "my-bot"
}

after_tool_call

在每次工具执行后触发。仅用于观测。

{
  "event": "after_tool_call",
  "tool_name": "shell",
  "tool_id": "call_abc123",
  "result": "file1.txt\nfile2.txt\n...",
  "success": true,
  "duration_ms": 142,
  "session_id": "telegram:12345",
  "profile_id": "my-bot"
}

注意:result 被截断到 500 个字符。

before_llm_call

在每次 LLM API 调用前触发。可以拒绝(exit 1)。

{
  "event": "before_llm_call",
  "model": "deepseek-chat",
  "message_count": 12,
  "iteration": 3,
  "session_id": "telegram:12345",
  "profile_id": "my-bot"
}

after_llm_call

在每次成功的 LLM 响应后触发。仅用于观测。

{
  "event": "after_llm_call",
  "model": "deepseek-chat",
  "iteration": 3,
  "stop_reason": "EndTurn",
  "has_tool_calls": false,
  "input_tokens": 1200,
  "output_tokens": 350,
  "provider_name": "deepseek",
  "latency_ms": 2340,
  "cumulative_input_tokens": 5600,
  "cumulative_output_tokens": 1800,
  "session_cost": 0.0042,
  "response_cost": 0.0012,
  "session_id": "telegram:12345",
  "profile_id": "my-bot"
}

钩子配置

config.json 或按配置文件的 JSON 中:

{
  "hooks": [
    {
      "event": "before_tool_call",
      "command": ["python3", "~/.octos/hooks/guard.py"],
      "timeout_ms": 3000,
      "tool_filter": ["shell", "write_file"]
    },
    {
      "event": "after_llm_call",
      "command": ["python3", "~/.octos/hooks/cost-tracker.py"],
      "timeout_ms": 5000
    }
  ]
}
字段必填默认值说明
event十种事件类型之一(见上文「事件」)
commandargv 数组(不经过 shell 解释)
timeout_ms5000超时后终止钩子进程
tool_filter全部仅对这些工具名称触发(仅限工具事件)

同一事件可以注册多个钩子。它们按顺序执行;第一个拒绝即生效。

熔断器

钩子在连续 3 次失败(超时、崩溃或退出码 2+)后会被自动禁用。一次成功执行(exit 0 或拒绝 exit 1)即可重置计数器。

安全性

  • 命令使用 argv 数组 – 不经过 shell 解释。
  • 18 个危险环境变量会被移除(LD_PRELOADDYLD_*NODE_OPTIONS 等)。
  • 支持波浪号展开(~/~username/)。

按配置文件的钩子

每个配置文件可以通过配置中的 hooks 字段定义自己的钩子。这允许不同的频道或机器人使用不同的策略。钩子变更需要重启网关。

向后兼容性

  • 载荷中可能会添加新字段。
  • 现有字段永远不会被移除或重命名。
  • 钩子脚本应忽略未知字段(标准 JSON 实践)。

示例:费用预算控制器

#!/usr/bin/env python3
"""Deny LLM calls when session cost exceeds $1.00."""
import json, sys

payload = json.load(sys.stdin)
if payload.get("event") == "before_llm_call":
    try:
        with open("/tmp/octos-cost.json") as f:
            state = json.load(f)
    except FileNotFoundError:
        state = {}
    sid = payload.get("session_id", "default")
    if state.get(sid, 0) > 1.0:
        print(f"Session cost exceeded $1.00 (${state[sid]:.4f})")
        sys.exit(1)

elif payload.get("event") == "after_llm_call":
    cost = payload.get("session_cost")
    if cost is not None:
        sid = payload.get("session_id", "default")
        try:
            with open("/tmp/octos-cost.json") as f:
                state = json.load(f)
        except FileNotFoundError:
            state = {}
        state[sid] = cost
        with open("/tmp/octos-cost.json", "w") as f:
            json.dump(state, f)

sys.exit(0)

示例:审计日志记录器

#!/usr/bin/env python3
"""Log all tool and LLM calls to a JSONL file."""
import json, sys, datetime

payload = json.load(sys.stdin)
payload["timestamp"] = datetime.datetime.utcnow().isoformat()

with open("/var/log/octos-audit.jsonl", "a") as f:
    f.write(json.dumps(payload) + "\n")

sys.exit(0)

沙箱

Shell 命令在沙箱中运行以实现隔离。支持三种后端:

后端平台隔离方式网络控制
bwrapLinux只读绑定 /usr,/lib,/bin,/sbin,/etc;读写绑定工作目录;tmpfs /tmp;unshare-pid禁止网络时使用 --unshare-net
macOSmacOS使用 SBPL 配置的 sandbox-exec:process-exec/forkfile-read*、工作目录 + /private/tmp 写入(allow network*)(deny network*)
Docker任意平台--rm --security-opt no-new-privileges --cap-drop ALL禁止网络时使用 --network none

config.json 中配置:

{
  "sandbox": {
    "enabled": true,
    "mode": "auto",
    "allow_network": false,
    "docker": {
      "image": "alpine:3.21",
      "mount_mode": "rw",
      "cpu_limit": "1.0",
      "memory_limit": "512m",
      "pids_limit": 100
    }
  }
}
  • 模式auto(自动检测最佳可用方案)、bwrapmacosdockernone
  • 挂载模式rw(读写)、ro(只读)、none(不挂载工作区)。
  • Docker 资源限制--cpus--memory--pids-limit
  • Docker 绑定挂载安全docker.sock/proc/sys/dev/etc 被阻止作为绑定挂载源。
  • 路径验证:Docker 拒绝 :\0\n\r;macOS 拒绝控制字符、()\"
  • 环境变量清理:18 个危险环境变量在所有沙箱后端、MCP 服务器启动、钩子和浏览器工具中自动清除:LD_PRELOAD, LD_LIBRARY_PATH, LD_AUDIT, DYLD_INSERT_LIBRARIES, DYLD_LIBRARY_PATH, DYLD_FRAMEWORK_PATH, DYLD_FALLBACK_LIBRARY_PATH, DYLD_VERSIONED_LIBRARY_PATH, NODE_OPTIONS, PYTHONSTARTUP, PYTHONPATH, PERL5OPT, RUBYOPT, RUBYLIB, JAVA_TOOL_OPTIONS, BASH_ENV, ENV, ZDOTDIR
  • 进程清理:Shell 工具在超时时发送 SIGTERM,等待宽限期后发送 SIGKILL 清理子进程。

会话管理

新建与具名会话

发送裸 /new(等同于 /clear)会清空当前会话历史,从头开始:

/new

使用 /new <name> 切换到——或创建——一个具名会话(如 /new research);/new slides <name> / /new site <preset> 则脚手架生成项目会话。会话按发送者/渠道建键;会话存储还带有一个 parent_key 字段,用于内部派生的子会话(如后台 spawn)。

会话持久化

每个 channel:chat_id 对维护各自独立的会话(对话历史)。

  • 存储.octos/sessions/ 中的 JSONL 文件
  • 最大历史:通过 gateway.max_history 配置(默认:50 条消息)
  • 会话:裸 /new 清空当前会话;具名会话按发送者/渠道建键,并带有用于内部派生子会话的 parent_key 字段

配置热重载

网关自动检测配置文件变更:

  • 可热重载(无需重启):系统提示、AGENTS.md、SOUL.md、USER.md
  • 需要重启:提供商、模型、API 密钥、网关频道

变更通过 SHA-256 哈希和防抖机制检测。

消息合并

长响应在发送前会自动拆分为适合频道的分块:

频道每条消息最大字符数
Telegram4000
Discord1900
Slack3900

拆分优先级:段落分隔 > 换行符 > 句号结尾 > 空格 > 硬截断。超过 50 块的消息会被截断并添加标记。


自主运行与会话控制

除一次性对话外,图形客户端(octos-web、octoscode)还通过 UI Protocol 驱动一些更长时运行的行为。其中自主运行与任务产物组由协商的能力标志门控(见能力协商);核心的轮次/会话控制(turn/startturn/interruptsession/rollbacktask/output/read)始终可用。

目标(Goals)

目标是附加到会话上的持久化目标。一旦设定,agent 会持续朝其推进——只要目标策略允许就重新触发轮次——而不是在单次回答后停止。目标跨轮次存续,需显式清除。

  • 协议:session/goal/setsession/goal/getsession/goal/clear(通知 session/goal/updatedsession/goal/cleared)。特性标志:必须同时协商 coding.autonomy.v1 coding.goal_runtime.v1(只声明组标志会得到 method_not_supported)。
  • 适用于「一直做到 X 完成」类工作。清除目标会停止未来的再次触发,但不会中止已在进行中的轮次——要停止正在运行的工作,请调用 turn/interrupt

循环(Loops)

循环是周期性的 agent 运行,有三种模式:固定间隔(每 N 秒触发)、自定步调(模型通过发出 <<loop-next-in: …>> 提示自行决定下次节奏;未指定时默认 15 分钟)或维护(每次触发时重新解析并运行一段维护提示——若找到 loop.md 覆盖文件则用之,否则用内置默认)。循环持续触发,直到被暂停、删除、达到 10,000 次触发上限——或到期:每个循环都会被打上 expires_at_ms = now + 7 天,一旦过期,即使未达触发上限,到期扫描也会跳过它。

  • 协议:loop/createloop/listloop/pauseloop/resumeloop/deleteloop/fire_now请求立即触发——它会经过循环的触发策略,若循环已暂停/耗尽可能被拒绝或去重,因此应检查返回的 fire.queued/错误结果,而非假定一定触发了一次)——通知 loop/firedloop/updated(协议中存在 loop/completed 变体,但正常迭代时当前并不发送——不要等待它)。特性标志:必须同时协商 coding.autonomy.v1 coding.loop_runtime.v1
  • 适用于轮询、监控和自定步调的后台 agent。

回退(Rewind)

session/rollback对话回退到较早的点——它追加一个回退标记,并通过丢弃最近 N 个用户轮次来重建聊天/上下文历史。它不会回滚工作区文件或任务状态。session/snapshot 是当前状态、文件与任务的只读聚合——是一个视图,而非可恢复的检查点。二者仅在对话层面支撑客户端的「回退」UI。

任务与轮次控制

  • 后台任务(派生工作、深度搜索、流水线)可被列出与取消:task/listtask/cancel,输出/产物通过 task/output/readtask/artifact/list。取消也可经 REST 的 POST /api/tasks/{id}/cancel 触达。task/restart_from_node 已被接受但尚不能真正重新执行——生产运行时未接入 relaunch 回调,因此它只会登记一个后继任务,而不会重新运行工作。
  • 运行中的轮次可用 turn/interrupt 中途打断(中止进行中的 LLM 调用与工具)。已提交到会话的消息会保留(可通过回放/hydration 恢复);只有被打断轮次中尚未提交的流式剩余部分会丢失。turn/startturn/interrupt 受能力门控——始终可用。而独立的子 agent 控制(agent/listagent/status/readagent/interruptagent/close)与任务产物(task/artifact/list|read)需要 coding.autonomy.v1 + coding.agent_control.v1

能力协商

客户端在连接时声明它支持哪些协议特性:WebSocket 通过 ui_feature / ui_features 查询参数或 X-Octos-Ui-Features 头;serve --stdio 通过 client_hellosupported_features。服务器对大多数方法按协商集门控,因此旧客户端可继续工作,新能力也能上线。实现客户端时需注意两点:某些方法虽在默认能力列表中被声明,但仍需其具体标志才能被调用(应以协商列表为准,并稳妥处理 method_not_supported);通知投递为尽力而为——当另一个连接触发自主运行事件(session/goal/updatedloop/*agent/*)时,本连接仍可能通过实时转发或回放收到它们。代表性标志:

标志解锁
coding.autonomy.v1自主运行根标志——须下方目标/循环/agent-control 标志一起协商
coding.goal_runtime.v1目标(session/goal/*)——还需 coding.autonomy.v1
coding.loop_runtime.v1循环(loop/*)——还需 coding.autonomy.v1
harness.task_control.v1任务 列出/取消/重启
harness.task_artifacts.v1任务产物(task/artifact/*)——还需 coding.autonomy.v1 + coding.agent_control.v1
coding.agent_control.v1子 agent 控制(agent/*)与任务产物——还需 coding.autonomy.v1
state.session_hydrate.v1session/hydrate 恢复
state.thread_graph.v1线程/轮次图
context.lifecycle.v1上下文压缩事件
approval.typed.v1类型化人工审批卡片
user_question.v1澄清提问卡片
auxiliary.rest_to_ws.v113 个辅助 REST→WS 方法(session/listcontent/listsession/snapshot 等)

上下文压缩

当对话超出 LLM 的上下文窗口时,较旧的消息会被自动压缩:

  • 工具参数被剥离(替换为 "[stripped]"
  • 消息被摘要为首行内容
  • 最近的工具调用/结果对完整保留
  • Agent 无缝继续,不会丢失关键上下文

聊天内命令

斜杠命令

命令说明
/new [name]/new 清空当前会话;/new <name> 切换到(或创建)具名会话;/new slides <name> / /new site <preset> 脚手架生成项目
/clear清空当前会话历史
/s/switch <name>切换到具名会话
/sessions列出本聊天的会话
/back/b切换到上一个活跃会话
/delete/d删除当前会话
/config查看和修改工具配置
/queue查看或更改队列模式
/thinking查看或设置推理强度(取决于传输通道)
/router/adaptive查看或更改路由/自适应模式
/soul查看或编辑 profile 的 SOUL(人格)
/skills内联列出/安装/移除技能
/status显示会话/运行时状态
/help列出当前传输通道可用的命令
/exit/quit:q退出聊天(仅 CLI 模式)

具体命令集因传输通道(CLI、网关渠道、Web、TUI)而异。Matrix 管理房间额外提供定时(/schedule/schedules/unschedule)与多机器人(/createbot/deletebot/listbots/allbots/bothelp)命令——见网关与频道

聊天中切换提供商

switch_model 工具允许用户通过自然对话列出可用的 LLM 提供商并在运行时切换模型。此工具仅在网关模式下可用。

列出可用提供商:

User: What models are available?

Bot: Current model: deepseek/deepseek-chat

     Available providers:
       - anthropic (default: claude-sonnet-4-20250514) [ready]
       - openai (default: gpt-4o) [ready]
       - deepseek (default: deepseek-chat) [ready]
       - gemini (default: gemini-2.5-flash) [ready]
       ...

切换模型:

User: Switch to GPT-4o

Bot: Switched to openai/gpt-4o.
     Previous model (deepseek/deepseek-chat) is kept as fallback.

切换模型时,之前的模型自动成为备选:

  • 如果新模型失败(限流、服务器错误),请求自动回退到原始模型。
  • 回退使用熔断器机制(连续 3 次失败触发故障转移)。
  • 链式结构始终扁平:[new_model, original_model] – 反复切换不会嵌套。

模型切换持久化到配置文件 JSON。网关重启时,机器人以最后选择的模型启动。

记忆系统

Agent 在会话间维护长期记忆:

  • MEMORY.md – 持久化笔记,始终加载到上下文中
  • 每日笔记.octos/memory/YYYY-MM-DD.md,自动创建
  • 近期记忆 – 最近 7 天的每日笔记包含在上下文中
  • 片段记忆 – 任务完成摘要存储在 episodes.redb

混合记忆搜索

记忆搜索结合了 BM25(关键词)和向量(语义)评分:

  • 排名alpha * vector_score + (1 - alpha) * bm25_score(默认 alpha:0.7)
  • 索引:使用 L2 归一化嵌入的 HNSW
  • 降级方案:未配置嵌入提供商时仅使用 BM25

配置嵌入提供商以启用向量搜索:

{
  "embedding": {
    "provider": "openai"
  }
}

嵌入配置支持三个字段:provider(默认:"openai")、api_key_env(可选覆盖)和 base_url(可选自定义端点)。

定时任务(Cron Jobs)

Agent 可以使用 cron 工具调度周期性任务:

User: Schedule a daily news digest at 8am Beijing time

Bot: Created cron job "daily-news" running at 8:00 AM Asia/Shanghai every day.
     Expression: 0 0 8 * * * *

定时任务也可以通过 CLI 管理:

octos cron list                              # 列出活跃任务
octos cron list --all                        # 包含已禁用的
octos cron add --name "report" --message "Generate daily report" --cron "0 0 9 * * * *"
octos cron add --name "check" --message "Check status" --every 3600
octos cron remove <job-id>
octos cron enable <job-id>
octos cron enable <job-id> --disable

Web 仪表板

REST API 服务器包含一个内嵌的 Web 界面:

octos serve                               # 绑定到 127.0.0.1:50080
octos serve --host 0.0.0.0 --port 50080  # 接受外部连接
# 打开 http://localhost:50080

功能:

  • 会话侧边栏
  • 聊天界面
  • UI Protocol WebSocket 流式推送
  • 暗色主题

/metrics 端点提供 Prometheus 格式的指标:

  • octos_tool_calls_total
  • octos_tool_call_duration_seconds
  • octos_llm_tokens_total