handler 型 · 子进程(Python CLI / SHELL / NODE / RUBY / GO)
什么时候读:技能是现成脚本、用别的语言写、或需要 argparse。 先确认接受这三条代价:拿不到
db、拿不到call_skill、默认 60 秒超时。 需要落库的,把「取数」和「落库」拆成两个技能,落库那个写成进程内 async Python。
判定为哪种 ExecType
| ExecType | 触发条件 | 输入来源 | 上下文来源 |
|---|---|---|---|
| PYTHON(CLI) | .py 同时含 argparse 与 __main__,或运行中抛 SystemExit | argv | SKILL_CONTEXT 环境变量 |
| SHELL / INLINE_SHELL / NODE / RUBY / GO | 按 frontmatter exec.primary.type | argv + SKILL_INPUT | SKILL_CONTEXT |
取输入与上下文
import json, os, sys
input_data = json.loads(os.environ.get("SKILL_INPUT") or "{}")
ctx = json.loads(os.environ.get("SKILL_CONTEXT") or "{}")
SKILL_CONTEXT 是序列化后的 runtime_context:
- 没有
db/db_factory/call_skill/abort_signal/request/channel_registry(不可序列化)。 - 以
_开头的键(如_meta)不注入。 - 其余固定上下文段、平台注入段、配置段都在,键表见
references/runtime-context.md。
子命令与 argv
技能声明了 cli_commands 时,平台把 input["_subcommand"] 放到 argv[0](argparse 的硬要求),
其余参数按 schema 转为 argv 或放进 SKILL_INPUT。见 references/input-schema.md §子命令。
stdout / stderr 约定
stdout 只打最终结果,日志一律走 stderr。 平台按顺序解析 stdout:
- 整个 stdout 是 JSON → 作为返回
- 最后一行是 JSON → 作为返回
- 是媒体文件路径行 → 作为产物
- 兜底包成
{"output": "<原始 stdout>"}
退出码非 0 判为技术失败。所以:
- 业务失败(参数错、查无数据)也要 退出码 0 + JSON 里
success: false+error,这样模型能自纠。只有崩溃才非 0。 - 不要在 stdout 打进度条、debug 行,会把 JSON 淹掉。
返回信封字段同进程内,见 references/output-envelope.md。
凭证
子进程/容器型的凭证走环境变量。frontmatter 里声明:
metadata:
openclaw:
primaryEnv: XXX_API_KEY
requires:
env: [XXX_API_KEY]
bins: [curl]
requires 在执行前校验,缺 env 直接返回 needs_config,不进入执行。
声明了 exec_mode: shell 或 runtime 的技能不校验 bins(在容器里跑)。
文档中只用 $VAR 引用,不展开、不打印。
超时
子进程默认 60 秒。超过的要么优化,要么改进程内 async(技能墙钟默认 600 秒,可声明 wall_sec 放宽到 1800),要么声明 async: true。
argv 拼法、位置参数、占位符、依赖自动安装
True → --flag、list 展开、dict 转 JSON、key_name → --key-name、x-cli-positional、{baseDir} / {workspace} 占位符、
PEP 723 / requirements.txt 自动建 venv、MEDIA: / MEDIA_URL: 产物行、SKILL_WORKSPACE / SKILL_DIR 环境变量——
全部见 code-facts.md §3.3。
文件参数
平台已把约定字段名的值解析成绝对路径(见 references/input-schema.md §文件参数),
脚本直接用,不要再拼目录。产物写到会话工作区顶层——SKILL_CONTEXT 里的 workspace_dir,或环境变量 SKILL_WORKSPACE
(两者同值,executor / compat 注入)。平台兜底采集;中间文件放其子目录。技能自身目录是 SKILL_DIR。