docs(delegation): clarify long-task acceptance

This commit is contained in:
mateaix 2026-08-30 14:47:40 +08:00
parent 701b99b3e9
commit 97125b991e
6 changed files with 70 additions and 0 deletions

View File

@ -123,6 +123,33 @@ Three delegation tools, one per cadence:
- **`delegateParallel`** — fan out. Delegate to several children at once; each runs in its own isolated session and the results are collected together.
- **`delegateAsync`** — background. Returns a `task_id` immediately while the child runs in the background; fetch the result later with **`taskOutput`**. Background runs have a bounded execution budget (default 3600 seconds, configurable with `mateclaw.delegation.async-timeout-seconds`, or per call with `timeoutSeconds`, max 86400). On timeout MateClaw stops the child session and persists a failed result instead of leaving an orphan run. `taskOutput` has an **attribution gate** — only the **same conversation + the same user** that spawned the task can read its result, preventing cross-conversation / cross-user leakage.
#### Async long tasks: scheduling, polling, and acceptance
`delegateAsync` uses the shared async-task pool. A user can currently run at most **3** async tasks at once; delegation, image, video, and other async workloads share that allowance. For a batch, start at most three tasks, poll until one reaches a terminal state, and then refill the free slot. A call rejected by the concurrency limit returns no `task_id` and must not be counted as started.
`taskOutput` parameters and response semantics:
| Field | Meaning |
|---|---|
| `taskId` | Required; pass the `task_id` returned by `delegateAsync` |
| `block` | Optional, default `false`; when `true`, wait for a terminal state within this call |
| `timeoutSeconds` | Controls only one blocking poll, default 30 seconds and max 120; it does not change the child's execution budget |
| `status` | `pending` / `running` / `succeeded` / `failed` |
| `progress` | Lifecycle progress; local delegation currently usually stays at 0 while running and becomes 100 at termination, so it is not content-completion percentage |
| `duration_ms` | Wall-clock duration, returned only for a terminal task |
::: warning `succeeded` does not mean the deliverable passed acceptance
`succeeded` only means that the child did not finish with a runtime exception or timeout. A model may return only an outline, a required tool may have failed, or a quantitative target may be missed while the task still becomes `succeeded`. The parent must verify business evidence before aggregating the result or completing a goal.
:::
Use at least these acceptance gates:
1. Required files, links, or structured results actually exist and are readable; do not rely only on a claim that they were generated.
2. Word, chapter, scenario, and similar quantitative targets have reproducible counts.
3. No plan or checklist items remain, and the final answer contains no “continue later” or “remaining work” declaration.
4. Critical write, read, and execution tools succeeded; if content was returned inline after an artifact failure, record that fallback explicitly.
5. Put this evidence into the [goal checklist](./goals), and complete the goal only when every criterion passes.
Children deny a default set of tools so the tree can't run away:
- `delegateToAgent` / `delegateParallel` / `listAvailableAgents` (recursion guard — children can't launch their own synchronous/parallel delegations and can't enumerate sibling agents)

View File

@ -49,6 +49,10 @@ Long tasks (multi-step plans, multi-agent collaboration) used to mean scrolling
The rail **collapses to a badged strip**; below 1280px it degrades to a **floating drawer** so it never squeezes the conversation column. It's pure frontend with zero new endpoints, reusing the existing SSE event stream — so the delegation tree still appears inline in the message too; the rail just lifts the "current / active" overview into a persistent place.
::: tip Observing long tasks
Run Overview is a live projection of SSE events, not the authoritative async-task store. After a refresh, reconnect, or for a background delegation started earlier, a child may be temporarily absent from the tree; confirm terminal state with `taskOutput(taskId)` from the spawning conversation. Running `progress` may also remain at 0 and jump directly to 100 at termination, so use tool calls, plan checklists, and final artifacts to judge actual completion.
:::
---
## Thinking, tool calls, and what to trust

View File

@ -179,6 +179,10 @@ Both modes use **structured output** — the evaluator returns a typed object (c
**Completion is deterministic.** Only when **every criterion passes** is the goal done. 19 of 20 passed (a 0.95 score) is still "continue" — miss one and one is missing, no fuzzy threshold.
::: warning Verify deliverable evidence for long tasks
An async child task's `status=succeeded` and `progress=100` are lifecycle terminal signals, not evidence that a criterion passed. For files, long-form writing, test cases, and similar deliverables, make criteria reproducible: for example, “the target file exists and can be read back,” “body text contains at least N characters,” or “at least N independent scenarios can be enumerated.” If a write or execution tool failed, only an outline was produced, or work remains pending, keep that criterion unpassed.
:::
**Three ways to add a checklist:**
- **At creation** — pass `criteria: ["DNS resolves", "SSL valid", "tests green"]` to the `setGoal` tool, or `criteria` to `POST /api/v1/goals`. Skips the bootstrap round.

View File

@ -123,6 +123,33 @@ head:
- **`delegateParallel`** —— 扇出委派。同时派给多个子员工,各自在隔离会话里跑,结果统一收集回来。
- **`delegateAsync`** —— 后台委派。立刻返回一个 `task_id`,子员工在后台跑;之后用 **`taskOutput`** 取结果。后台任务默认有 3600 秒执行预算,可通过 `mateclaw.delegation.async-timeout-seconds` 配置,或在单次调用中用 `timeoutSeconds` 调整(最大 86400 秒);超时后 MateClaw 会停止子会话并持久化失败结果,避免遗留孤儿任务。`taskOutput` 带**归属闸门**——只有最初发起委派的**同一个会话 + 同一个用户**才能读到结果,防止跨会话/跨用户泄露。
#### 异步长任务:调度、轮询与验收
`delegateAsync` 走通用异步任务池。当前每个用户最多同时运行 **3 个**异步任务,这个额度由委派、图片、视频等异步任务共享。批量任务应按“最多启动 3 个 → 轮询到至少一个终态 → 再补位”的方式滚动执行;触发并发上限的调用不会返回 `task_id`,不能把它计入已启动任务。
`taskOutput` 的参数与返回语义:
| 项 | 语义 |
|---|---|
| `taskId` | 必填,使用 `delegateAsync` 返回的 `task_id` |
| `block` | 可选,默认 `false`;设为 `true` 时在本次调用里等待终态 |
| `timeoutSeconds` | 只控制一次阻塞轮询,默认 30 秒、最大 120 秒;不改变子任务的执行预算 |
| `status` | `pending` / `running` / `succeeded` / `failed` |
| `progress` | 运行态的生命周期进度;本地委派目前通常保持 0终态变为 100不代表内容完成百分比 |
| `duration_ms` | 仅终态返回的墙钟耗时 |
::: warning `succeeded` 不等于交付验收通过
`succeeded` 只表示子任务没有以运行时异常或超时结束。模型可能只返回提纲、工具调用可能失败、目标字数可能未达到,任务仍会进入 `succeeded`。父员工在汇总或完成目标前,必须再次检查业务证据。
:::
建议至少设置以下验收门禁:
1. 要求的文件、链接或结构化结果真实存在并且可读;不要只相信回答中的“已生成”。
2. 字数、章节数、场景数等量化要求有可复核计数。
3. 计划或清单没有待办项,最终回答没有“后续继续”“其余待补”等未完成声明。
4. 关键写入、读取、执行工具没有失败;若工具失败后改为正文交付,要明确记录降级方式。
5. 父员工把上述证据写进[目标清单](./goals),只有全部准则通过后才完成目标。
子员工默认被拒绝一组工具,保证树不失控:
- `delegateToAgent` / `delegateParallel` / `listAvailableAgents`(递归护栏——子员工不能再发起同步/并行委派,也不能枚举兄弟员工)

View File

@ -49,6 +49,10 @@ Segment 是**渐进到达**的。每个 segment 一落盘就立刻持久化到
侧栏可**折叠为带角标的竖条**;窄屏(< 1280px自动降级为**浮层抽屉**不挤占对话区它纯前端实现零新增接口完全复用现有 SSE 事件流所以委派树也仍会内联在消息里侧栏只是把当前 / 活跃的总览拎出来常驻
::: tip 长任务观测建议
运行总览是 SSE 事件的实时投影,不是异步任务记录的权威查询面。刷新、重连或较早启动的后台委派可能暂时不在子 Agent 树中;需要确认终态时,仍以发起会话里的 `taskOutput(taskId)` 为准。运行态 `progress` 也可能保持 0 到终态后直接变成 100请结合工具调用、计划清单和最终工件判断真实完成度。
:::
---
## 思考、工具调用、以及"该不该信"

View File

@ -177,6 +177,10 @@ Plan-Execute 模式下,单个步骤可能**抛异常**,也可能陷入**停
**完成判定是确定性的。** 只有当**每一条准则都通过**才判完成。20 条里过了 19 条0.95 分)依然是"继续"——差一条就还差一条,没有模糊阈值。
::: warning 长任务要验证交付证据
异步子任务的 `status=succeeded`、`progress=100` 只是运行生命周期终态,不能直接作为准则通过的证据。对文件、长文、测试场景等交付,准则应写成可复核形式,例如“目标文件存在且回读成功”“正文字符数不少于 N”“至少有 N 条独立场景并可枚举”。若写文件或执行工具失败、只生成了提纲、仍有待办项,对应准则必须保持未通过。
:::
**怎么给目标加清单——三种途径:**
- **创建时直接带**——`setGoal` 工具传 `criteria: ["DNS 解析正确", "SSL 有效", "测试全绿"]`,或 `POST /api/v1/goals``criteria`。省去 bootstrap 那一轮。