mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-13 03:13:41 +08:00
docs(runtime): document restart-safe long tasks
This commit is contained in:
parent
dd4db18ed8
commit
d8976ddf1e
@ -88,6 +88,13 @@ You hire coworkers, not chat boxes. Each one has a **Role**, a **Goal**, a **Bac
|
||||
### Agent Runtime: native or DSH (2.2.0+)
|
||||
The `AgentRuntimeProvider` contract separates an employee from the engine that runs its turn. The **native runtime** keeps ReAct, Plan-and-Execute, persistent Goals, and Team Runs inside MateClaw. The **DSH runtime** manages `dsh-jsonrpc-agent` as an authenticated child process and streams thinking, text, tool calls, usage, completion, and cancellation back as normalized runtime events. DSH owns the external Agent loop; MateClaw still owns the session, workspace, credentials, tools, approvals, messages, and UI projection. Runtime availability and capabilities are validated before startup, and DSH can be installed, verified, connection-tested, enabled, or disabled from the console. [Configure DeepSeek Harness →](https://claw.mate.vip/docs/en/deepseek-harness)
|
||||
|
||||
### Durable long tasks: checkpoint, restart, continue (2.2.0+)
|
||||
Persistent Goals turn work that takes hours into bounded, recoverable segments. The database preserves the goal checklist, continuation state, attempts, cooldowns, leases, and user input accepted while the worker is busy. After a single backend instance restarts, the supervisor reconciles the interrupted attempt, reads persisted checkpoints and artifacts, and schedules the next safe segment instead of asking you to repeat the task.
|
||||
|
||||
For file-producing work, ask the employee to keep a progress ledger, append small verifiable units, inspect the existing tail after recovery, and complete the Goal only after reproducible acceptance checks pass. The runtime does not promise exactly-once behavior for arbitrary external side effects; payments, sends, publishes, and destructive calls still need provider idempotency or review. [Run and verify durable Goals →](https://claw.mate.vip/docs/en/goals)
|
||||
|
||||
> Prompt pattern: “Create a persistent Goal first. Save the plan and progress in the workspace, write in small checkpoints, resume from existing evidence after errors or restart, and call `completeGoal` only after every criterion has verifiable evidence.”
|
||||
|
||||
### Team Runs (2.1.0+)
|
||||
One request, one durable **Team Run**. A stable `runId` links the user's objective, task DAG, worker executions, final synthesis, and deliverables. Chat is the outcome surface, Agents Live groups the workers for real-time observation, and Teams owns history and governance — all three consume the same server projection. Worker conversations no longer flood the normal sidebar; summaries and files lead, while tasks, evidence, approvals, and read-only worker records drill down on demand. Underneath, the 2.0 shared board still provides dependency orchestration, parallel dispatch, prerequisite hand-off, execution leases, cancel-interrupt, and human approval gates.
|
||||
|
||||
|
||||
@ -88,6 +88,13 @@ MateClaw 的 **LLM Wiki** 把它消化成结构化页面,页面之间自己长
|
||||
### Agent Runtime:Native 或 DSH(2.2.0+)
|
||||
`AgentRuntimeProvider` contract 把员工与实际执行回合的引擎分开。**Native Runtime** 在 MateClaw 内运行 ReAct、Plan-and-Execute、Persistent Goal 与 Team Run;**DSH Runtime** 把 `dsh-jsonrpc-agent` 作为认证子进程管理,并将思考、文本、工具调用、用量、完成与取消统一映射为 runtime event。DSH 掌管外部 Agent loop,MateClaw 继续掌管 session、workspace、凭证、工具、审批、消息和 UI 投影。启动前会校验 runtime 可用性与能力;控制台可完成 DSH 的安装、配置、校验、连接测试和启停。[配置 DeepSeek Harness →](https://claw.mate.vip/docs/zh/deepseek-harness)
|
||||
|
||||
### 持久长任务:检查点、重启、继续(2.2.0+)
|
||||
Persistent Goal 把需要数小时的工作拆成有界、可恢复的执行段。数据库会保存目标清单、continuation 状态、attempt、冷却、lease,以及员工忙碌期间已经接收的用户输入。单后端实例重启后,supervisor 会先核对被中断的 attempt,读取持久检查点和已有产物,再调度下一段安全工作,不要求用户重新描述任务。
|
||||
|
||||
对于写文件的任务,应要求员工维护进度账本、以小块追加可验证内容、恢复时先检查文件尾部,并且只有在可复现验收全部通过后才完成 Goal。运行时不承诺任意外部副作用严格一次;付款、发送、发布和破坏性操作仍需使用服务商幂等键或人工复核。[运行并验证持久目标 →](https://claw.mate.vip/docs/zh/goals)
|
||||
|
||||
> 提示词模板:“第一步创建持续目标;把计划和进度保存在工作区;按小检查点写入;发生错误或重启后从已有证据继续;只有每条验收标准都有可验证证据时才调用 `completeGoal`。”
|
||||
|
||||
### Team Run(2.1.0+)
|
||||
一次请求对应一个持久化的 **Team Run**。稳定的 `runId` 串起用户目标、任务 DAG、成员执行、最终汇总与交付物。Chat 是成果交付面,Agents Live 按运行聚合成员并展示实时状态,Teams 管理历史与治理;三处读取同一份服务端投影。成员子会话不再挤进普通会话列表,摘要和文件优先展示,任务、证据、审批与只读成员记录按需下钻。底层继续使用 2.0 的共享任务板,保留依赖编排、并行派发、前置结果传递、执行租约、取消中断和人工审批卡点。
|
||||
|
||||
|
||||
@ -17,6 +17,66 @@ A durable queue and background supervisor schedule persistent goals across bound
|
||||
|
||||
`GET /api/v1/goals/{id}/execution` exposes the latest scheduling state, reason and due time; the goal API remains authoritative for current goal status. Streams broadcast scheduling changes through `goal_continuation`. V1 supports a single backend instance and the native runtime. External tool effects are not guaranteed exactly once; recovery must check existing artifacts and async handles. Budgets are checked at segment boundaries, not as per-request spending caps.
|
||||
|
||||
## The durable execution contract
|
||||
|
||||
Persistent execution separates a long goal from any one HTTP request or graph run. The database holds the work that must survive process loss:
|
||||
|
||||
| Durable state | Why it matters after a restart |
|
||||
|---|---|
|
||||
| Goal and criteria | The completion bar remains unchanged |
|
||||
| Continuation row | The supervisor knows whether work is queued, cooling down, retrying, paused, or blocked |
|
||||
| Attempt and lease | An interrupted segment can be classified before another segment is claimed |
|
||||
| Accepted-input queue | A message sent while the worker is busy is consumed later instead of being dropped |
|
||||
| Progress ledger and artifacts | The next segment can inspect completed work and continue from evidence |
|
||||
|
||||
One segment claims the goal, consumes at most one queued input, executes a bounded graph run, saves its result, and then either reaches a terminal condition or schedules the next segment. A backend restart releases orphaned input claims and reconciles expired attempts before ordinary dispatch resumes.
|
||||
|
||||
Recovery is deliberately conservative. A safe retry may run again; an already-saved assistant message is reconciled; completed tool evidence is inspected; and a tool that may have produced an uncertain external side effect blocks for review. This avoids silently converting “the process restarted” into “repeat a payment, publication, or deletion.”
|
||||
|
||||
### Inputs accepted while work is running
|
||||
|
||||
When an active persistent goal is already executing, new user input is stored in `mate_conversation_input_queue` before it is handed to a later attempt. Each item moves through queued, claimed, and consumed states. If the process stops after claiming but before consuming it, startup recovery releases the orphaned claim so the same input remains available.
|
||||
|
||||
The queue preserves accepted input; it does not make contradictory instructions safe. A user can still pause or abandon the goal, and an instruction that changes the acceptance criteria should update the goal explicitly rather than relying on an ambiguous follow-up sentence.
|
||||
|
||||
## Designing work that can run for hours
|
||||
|
||||
The runtime can preserve scheduling state, but the task still needs recoverable checkpoints. For long-form writing, code generation, research collections, or data exports:
|
||||
|
||||
1. Create concrete criteria before doing bulk work. Counts, file paths, required sections, tests, and final validation are stronger than “produce a good result.”
|
||||
2. Store a small plan and progress ledger in the workspace. Record the last completed unit, cumulative count, unresolved items, and the exact next action.
|
||||
3. Write in bounded units. For prose, a chapter or 2,000–4,000 Chinese characters per mutation is easier to retry and inspect than an entire volume in one tool call.
|
||||
4. Re-read the checkpoint and the target file tail after recovery. Continue from evidence rather than from the model's recollection of the interrupted turn.
|
||||
5. Prefer retry-safe mutations. `append_file` treats an exact block already present at the file tail as success with `alreadyApplied=true`; `expectedTail` can reject an append when another write changed the file since it was read.
|
||||
6. Pace provider traffic. Set a minimum continuation interval and a provider-wide backoff that match the model's quota. A retry storm is not progress.
|
||||
7. Verify before completion. Recount content, enumerate units, read the ending, rerun tests, and require nonblank evidence for every criterion before calling `completeGoal`.
|
||||
|
||||
### Example: a 500,000-character novel soak test
|
||||
|
||||
A useful soak test asks the General Assistant to create a persistent goal for a ten-volume, roughly 180-chapter novel, save a story bible, outline, and progress ledger, then append one chapter at a time until the body contains at least 500,000 Chinese characters. Each recovery pass must inspect existing headings and the file tail before writing the next chapter.
|
||||
|
||||
In the 2026-08-30 single-instance validation, the backend was stopped during chapter generation. Twelve chapters and 15,342 Chinese characters were present at the recovery checkpoint. After restart, the supervisor reloaded the original goal and conversation context, read the outline, progress ledger, and volume tail, then continued at chapter 13. The observation window reached chapter 17 and 24,628 Chinese characters with zero duplicate chapter headings. Provider rate limits and a transient connection failure entered backoff and later continued. These figures describe that test run; they are not throughput guarantees.
|
||||
|
||||
For a repeatable check, record values before restart and compare them after recovery:
|
||||
|
||||
```bash
|
||||
FILE=data/workspace/novel-ash-sea/volumes/volume-01.md
|
||||
rg -c '^## 第.*章' "$FILE"
|
||||
python3 - <<'PY'
|
||||
import re
|
||||
from pathlib import Path
|
||||
text = Path("data/workspace/novel-ash-sea/volumes/volume-01.md").read_text(encoding="utf-8")
|
||||
print(len(re.findall(r"[\u4e00-\u9fff]", text)))
|
||||
PY
|
||||
rg '^## 第.*章' "$FILE" | sort | uniq -d
|
||||
```
|
||||
|
||||
The last command must produce no output. Also check `GET /actuator/health`, `GET /api/v1/goals/{id}/execution`, the continuation logs, the progress ledger, and the newest artifact timestamp. Recovery has passed only when the worker writes a new unit after restart without losing queued input or duplicating the previous unit.
|
||||
|
||||
::: warning Current boundary
|
||||
Persistent Goal v1 is designed and tested for one backend instance using the native runtime. Database-backed state survives a restart of that instance, but arbitrary external side effects are not exactly once. Use provider idempotency keys, read-before-write reconciliation, or human review for payments, sends, publishes, and destructive actions.
|
||||
:::
|
||||
|
||||
> **You used to repeat the context every turn. Now you set a goal once, the worker follows.**
|
||||
|
||||
You say "deploy this blog to fly.io" in one turn, the worker answers, and stops. Next turn you have to remember to ask "is DNS set? cert signed? tests run?" — you're keeping the goal in your head, not the worker.
|
||||
|
||||
@ -17,6 +17,66 @@ head:
|
||||
|
||||
`GET /api/v1/goals/{id}/execution` 返回独立的调度状态、原因和到期时间;它是最近的调度记录,目标当前状态以 goal API 为准。流中通过 `goal_continuation` 广播调度变化。第一版支持单后端实例的原生 runtime,不保证外部工具副作用恰好一次;恢复先检查已有产物与异步句柄。预算在片段边界检查,不是逐请求的硬费用限制。
|
||||
|
||||
## 持久执行契约
|
||||
|
||||
持续执行把长目标和任何一次 HTTP 请求或图执行解耦。数据库保存进程退出后仍必须存在的工作状态:
|
||||
|
||||
| 持久状态 | 重启后的作用 |
|
||||
|---|---|
|
||||
| 目标与验收清单 | 完成标准不会改变 |
|
||||
| Continuation 记录 | Supervisor 知道任务正在排队、冷却、重试、暂停还是阻塞 |
|
||||
| Attempt 与 lease | 新片段认领前可以先判断上一次中断的位置与安全性 |
|
||||
| 已接收输入队列 | 员工忙碌期间收到的消息稍后消费,不会被丢弃 |
|
||||
| 进度账本与工作区产物 | 下一片段可以根据证据继续,而不是靠模型猜测 |
|
||||
|
||||
每个片段会认领目标,最多消费一条排队输入,执行一次有界图运行,保存结果,然后进入终态或排队下一片段。后端重启后,会先释放孤立的输入认领并核对过期 attempt,再恢复普通调度。
|
||||
|
||||
恢复策略偏保守:安全调用可以重试;已经保存的 assistant 消息会进入核对;工具完成证据会被重新读取;可能产生了不确定外部副作用的工具则会阻塞并等待复核。这样不会把“进程重启”悄悄变成“再付一次款、再发布一次或再删除一次”。
|
||||
|
||||
### 执行期间接收的新输入
|
||||
|
||||
持续目标正在运行时,新用户输入会先写入 `mate_conversation_input_queue`,再交给后续 attempt。输入项依次处于 queued、claimed、consumed 状态。如果进程在认领后、消费前退出,启动恢复会释放孤立认领,使同一条输入仍可继续处理。
|
||||
|
||||
队列保证已经接收的输入不会丢失,但不会自动消除相互冲突的指令。用户仍可暂停或放弃目标;如果新输入改变验收标准,应明确更新目标,而不是依赖一句含义不清的跟进消息。
|
||||
|
||||
## 让任务稳定运行数小时
|
||||
|
||||
运行时可以保存调度状态,但任务本身仍需设计成可恢复的检查点。对于长篇写作、代码生成、研究资料汇总或数据导出:
|
||||
|
||||
1. 批量执行前先建立具体标准。字数、文件路径、必备章节、测试和最终校验,比“产出高质量结果”更可验证。
|
||||
2. 在工作区保存简短计划与进度账本,记录最后完成单元、累计数量、未解决事项以及下一步动作。
|
||||
3. 使用有界写入。写作任务每次追加一章或 2,000–4,000 个汉字,比一次工具调用塞入整卷更易重试和检查。
|
||||
4. 恢复后先重读检查点与目标文件尾部,根据已有证据续写,不依赖被中断回合里的模型记忆。
|
||||
5. 优先使用可安全重试的变更。`append_file` 发现文件尾部已经存在完全相同的内容时,会返回 `alreadyApplied=true` 而不重复写入;`expectedTail` 可在文件已被其他写入改变时拒绝追加。
|
||||
6. 控制模型请求节奏。根据模型配额设置最小 continuation 间隔和 provider 全局退避;重试风暴不等于任务进度。
|
||||
7. 完成前重新验收:重算内容数量、枚举完成单元、读取结尾、重跑测试;所有标准都有非空证据后才能调用 `completeGoal`。
|
||||
|
||||
### 示例:50 万字小说稳定性测试
|
||||
|
||||
一个有代表性的稳定性用例,是让通用助手为十卷、约 180 章的玄幻小说创建持续目标,保存设定圣经、全书大纲和进度账本,然后逐章追加,直至正文不少于 500,000 个中文汉字。每次恢复都必须先检查已有章节标题和文件尾部,再写下一章。
|
||||
|
||||
在 2026-08-30 的单实例验证中,后端在生成章节时被停止。恢复检查点已有 12 章、15,342 个中文汉字。重启后,supervisor 恢复原始目标和会话上下文,读取大纲、进度账本和卷尾,从第 13 章继续;观察窗口内写到第 17 章、24,628 个中文汉字,重复章节标题为 0。期间发生的 provider 限流和一次短暂连接错误进入退避后继续运行。这些数字只记录该次测试,不代表吞吐量承诺。
|
||||
|
||||
复测时可在重启前后记录以下值:
|
||||
|
||||
```bash
|
||||
FILE=data/workspace/novel-ash-sea/volumes/volume-01.md
|
||||
rg -c '^## 第.*章' "$FILE"
|
||||
python3 - <<'PY'
|
||||
import re
|
||||
from pathlib import Path
|
||||
text = Path("data/workspace/novel-ash-sea/volumes/volume-01.md").read_text(encoding="utf-8")
|
||||
print(len(re.findall(r"[\u4e00-\u9fff]", text)))
|
||||
PY
|
||||
rg '^## 第.*章' "$FILE" | sort | uniq -d
|
||||
```
|
||||
|
||||
最后一条命令应无输出。同时检查 `GET /actuator/health`、`GET /api/v1/goals/{id}/execution`、continuation 日志、进度账本和最新产物时间。只有重启后能写入新的工作单元,并且没有丢失排队输入或重复上一个单元,才算恢复验证通过。
|
||||
|
||||
::: warning 当前边界
|
||||
Persistent Goal 第一版面向单后端实例和 Native Runtime 设计与验证。数据库状态可以跨该实例重启恢复,但任意外部副作用并非严格一次。付款、发送、发布和破坏性操作应使用服务商幂等键、执行前后核对或人工复核。
|
||||
:::
|
||||
|
||||
> **以前你每轮都要把上下文重复一遍。现在你定一个目标,员工自己跟。**
|
||||
|
||||
一次对话里你说"帮我把这个博客部署到 fly.io",员工答完一轮就停了。下一轮你要再问"DNS 配好没?证书呢?测试跑了吗?"——你在替它记目标。
|
||||
|
||||
Loading…
Reference in New Issue
Block a user