Task 输入输出与持久化协议
本页定义 Task 作者、API 使用者与文件消费者共享的基本契约。研究专属字段见研究产物协议;运行语义见任务生命周期。以下示例的时间与 run_id 为演示值。
输入与输出基类
BaseInputParams 使用 extra="forbid" 和赋值校验。每个 Task 的 input_cls 在基类上声明业务字段。
| 基础输入字段 | 类型与默认值 | 约束 |
|---|---|---|
| task_name | string 或 null,默认 null | 1–32 个字母、数字、连字符;空串视为未指定 |
| source_tasks | string,默认空串 | 英文逗号分隔合法 Task ID,拒绝重复 ID |
source_tasks 会去除每项周围空白并重新拼接。source_task(TaskType.X) 要求指定类型恰好一个上游,不会自动验证目录和产物存在。
BaseOutputParams 使用 extra="forbid"、populate_by_name=True,基础字段为 artifacts: dict[str, dict[str, Any]],默认空字典。业务扩展字段应由 output_cls 明确声明。
from axonx.task.core import BaseInputParams, BaseOutputParams
class AddInput(BaseInputParams):
x: int
y: int
class AddOutput(BaseOutputParams):
result: intbuild_output_params() 必须返回 output_cls 实例,返回普通 dict 或错误类型会失败。输出只有在执行完成并 prepare_output 后可读。
TaskContext
TaskContext 是 frozen dataclass,附着在 Task 上,提供运行时拥有的值:
| 字段 | 类型 | 用途 |
|---|---|---|
| workspace_path | Path | 已解析工作区根 |
| registration_name | string | 定义注册名 |
| task_id | string | 目录身份 |
| run_id | string | 执行身份 |
| created_at | datetime | 本轮创建时刻 |
| logger | 日志对象 | 记录步骤执行 |
插件应读取这些值,不修改运行身份。task.task_dir 是 <workspace>/<type>/<task_id>;source_task_dir(id) 定位同工作区的上游目录。
TaskDefinition 与 TaskHandle
TaskDefinition 描述可执行定义,字段为 name、source(native/plugin)、plugin(可空)、task_type、description、input_schema、output_schema。description 来自 Task 类的详细 docstring;没有有效说明的定义会被拒绝。
TaskHandle 是 submit 返回的 immutable dataclass:
{
"task_id": "base#demo#contract-01",
"run_id": "a9f248807a0a496abf3738422b379a51",
"task": "demo"
}字段 task 是注册名。这里没有 task_name 字段,也没有自动路由到远端的地址。客户端需保留执行机器信息,并以 task_id + run_id 等待这一轮。
TaskStatus
| 字段 | 类型/默认 | 含义 |
|---|---|---|
| task_id | string,必需 | 必须与目录 ID 一致 |
| run_id | 非空 string,必需 | 当前执行身份 |
| task_type | TaskType,必需 | 必须与 ID 中类型一致 |
| task_name | string,默认空串 | 当前实现写入注册名 |
| config | object,默认 {} | typed input 的 JSON 表示,含实例 task_name |
| state | TaskState,默认 queued | 当前执行状态 |
| pid | integer 或 null | 当时运行进程标识 |
| created_at / started_at / finished_at | datetime 或 null | 创建、开始和结束时刻 |
| steps | TaskStepStatus[],默认 [] | 已开始步骤快照 |
| result | object,默认 {} | 构建后的 typed output |
| error | string,默认空串 | 错误说明 |
| exit_code | integer,默认 0 | 0–255 |
| log_path | string,默认空串 | 独立日志文件位置 |
TaskStepStatus 包含非空 name、可空 started_at/finished_at、可空 percentage(0–100)。百分比描述当前步骤,不是整项研究进度。
成功状态的简化完整例子:
{
"task_id": "base#demo#contract-01",
"run_id": "a9f248807a0a496abf3738422b379a51",
"task_type": "base",
"task_name": "demo",
"config": {
"task_name": "contract-01",
"source_tasks": "",
"x": 1,
"y": 2,
"fail": false
},
"state": "succeeded",
"pid": 12345,
"created_at": "2026-01-05T09:00:00+08:00",
"started_at": "2026-01-05T01:00:00Z",
"finished_at": "2026-01-05T01:00:01Z",
"steps": [
{
"name": "finish",
"started_at": "2026-01-05T01:00:00Z",
"finished_at": "2026-01-05T01:00:01Z",
"percentage": 100
}
],
"result": {
"artifacts": {},
"result": 3,
"branch": "different",
"operands": ["x", "y"]
},
"error": "",
"exit_code": 0,
"log_path": ""
}steps 仅展示最后一个步骤,实际 demo 包含更多步骤。日志为空只为避免绑定某个部署路径,真实值由日志系统给出。
失败时关键差异如下,不是独立完整 TaskStatus:
{
"state": "failed",
"result": {},
"error": "RuntimeError: Demo failure requested",
"exit_code": 1
}非零自定义退出码也进入 failed,但可能已有 result;失败不必然意味着 output 从未构建。取消由管理器记录 cancelled,通常使用退出码 130。
TaskMetadata
metadata 顶层严格表达成功任务的输入与输出:
{
"task_id": "base#demo#contract-01",
"reg_name": "demo",
"created_at": "2026-01-05T09:00:00+08:00",
"task_type": "base",
"input_params": {
"task_name": "contract-01",
"source_tasks": "",
"x": 1,
"y": 2,
"fail": false
},
"output_params": {
"artifacts": {},
"result": 3,
"branch": "different",
"operands": ["x", "y"]
}
}metadata 没有顶层 run_id、state、result 或 error。TaskStatus.result 与 metadata.output_params 对应;任务身份注册名在 metadata.reg_name。
成功过程先构建输出、确定退出码,再写 metadata,然后发布成功 status。非有限浮点数在 metadata 写入时递归转换成 null,以便被 JSON 消费者读取。
Artifact 记录
{
"artifacts": {
"dataset": {
"path": "data/dataset.parquet",
"size": 10240,
"sha256": "<64 位十六进制校验和>"
}
}
}基类只规定 artifacts 为嵌套映射;path、size、sha256 是标准产物工具生成的记录,研究插件应使用它们。artifact_path() 要求 path 非空、相对 Task 目录且不越界。
不要把工作区根路径写进 artifact path。消费者组合 <type>/<task_id>/<artifact.path>,并核对生产插件约定的逻辑名称,例如 dataset、model 或 daily。
兼容读取与事件
TaskStatus 读取兼容历史字段 execution_id 作为 run_id 的 validation alias。新写入仍使用 run_id;不要同时写两个身份字段或将 execution_id 当成新接口字段。
工作区读取会拒绝非法 JSON、错误 task_id/type 和不安全目录,表现为记录缺失。容错读取旨在隔离坏记录,不保证自动修复旧数据。
events.jsonl 是追加进度记录;普通日志在 log_path。写入端先记录进度,再发布匹配 status,终态消费者有机会读取先前事件。其传输投影和最终 result 规则见事件协议。
Job 与 Task · Task API · 研究产物协议