跳到主要内容

handler 型 · 子进程(Python CLI / SHELL / NODE / RUBY / GO)

什么时候读:技能是现成脚本、用别的语言写、或需要 argparse。 先确认接受这三条代价:拿不到 db、拿不到 call_skill、默认 60 秒超时。 需要落库的,把「取数」和「落库」拆成两个技能,落库那个写成进程内 async Python。

判定为哪种 ExecType​

ExecType触发条件输入来源上下文来源
PYTHON(CLI).py 同时含 argparse 与 __main__,或运行中抛 SystemExitargvSKILL_CONTEXT 环境变量
SHELL / INLINE_SHELL / NODE / RUBY / GO按 frontmatter exec.primary.typeargv + SKILL_INPUTSKILL_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:

  1. 整个 stdout 是 JSON → 作为返回
  2. 最后一行是 JSON → 作为返回
  3. 是媒体文件路径行 → 作为产物
  4. 兜底包成 {"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。