Agent / Action / Runtime / Visualizer 管理
管理员维护全局资产仓库,manager 与 owner 安装项目级 agent、action、runtime,并管理项目内 visualizer 插件
Agent / Action / Runtime / Visualizer 管理
两层管理
当前系统将 agent 资产管理拆成两层:
- 全局资产仓库管理:管理员维护共享
agent、action、runtime来源 - 项目内资产安装:manager 与 owner 将这些资产安装到当前项目
这里的“资产”特指:
agentactionruntime
visualizer 目前采用项目本地插件模式,不走全局资产仓库安装链路。
管理员全局 Agent 管理
入口:
- Workspace 左下角菜单中的
Agents - 页面路径:
/workspace/admin/assets
你可以做什么:
- 添加 Git 或 GitHub 资产仓库
- 指定仓库分支
- 手动同步单个仓库
- 删除整个仓库
- 搜索仓库与资产
- 在线编辑资产 definition 文件
- 对 action 在线编辑 entry 脚本
- 对全局 agent 执行“启用全局”或“停用全局”
Mixed Repository 模型
当前资产仓库不再按 actions / agents / runtimes 分开添加。
一个仓库可以同时包含多种资产,系统会自动识别并聚合展示:
- actions
- agents
- runtimes
页面上看到的是一个 mixed repository 视图:
- 一个 Git 仓库只显示一张卡片
- 卡片内部按资产类型分组展示
- 同步、删除、编辑都按这一个仓库视图操作
仓库同步与扫描
当管理员添加资产仓库后,系统会:
- 拉取仓库到本地资产存储目录
- 自动扫描仓库内的
ACTION.yaml、AGENT.yaml、RUNTIME.yaml - 建立全局资产索引
- 在管理页中显示解析出的资产列表
说明:
- 一个目录中包含
ACTION.yaml会被识别为一个 action - 一个目录中包含
AGENT.yaml会被识别为一个 agent - 一个目录中包含
RUNTIME.yaml会被识别为一个 runtime - builtin 资产也会出现在该页面中,但 builtin repository 不能删除
在线编辑
当前管理页已支持最小文本编辑能力:
- 点击
Edit后以弹层方式打开编辑器 agent/runtime可编辑 definitionaction可编辑:- definition
- entry 脚本
- prompt 提示词设置(仅
executor_type: prompt的 Action)
保存后会:
- 直接回写资产文件
- 重新同步该仓库的资产索引
当前限制:
- 只提供纯文本编辑
- 还没有 schema 校验、diff 或格式化
- 编辑 builtin 资产会直接修改本地 builtin 文件
项目安装语义
项目内安装不是“引用全局定义”,而是复制一份安装快照到当前项目。
安装后会进入项目本地 workspace:
.agent/actions/<installed-name>
.agent/agents/<installed-name>
.agent/runtimes/<installed-name>这意味着:
- 项目只会使用自己已安装的资产
- 聊天中的 agent tool 只会从当前项目已安装 agent 生成
- 后续全局仓库更新后,项目不会自动同步到新版本
- 如需更新,需在项目中重新安装或重新同步安装快照
全局启用 Agent
如果你希望某个全局 agent 在当前项目里可用,但不想复制一份本地安装快照,可以直接使用 启用全局。
启用后的特点:
- 当前项目会保存一条全局启用记录
- 不会在
.agent/agents下生成新的安装目录 - 聊天中的 agent tools 会直接引用全局 agent 定义
- 需要停用时,可在同一位置执行
停用全局
Visualizers(项目本地插件)
visualizer 用来扩展文件预览能力,例如用 Web 插件预览结构文件、表格文件或其他特殊格式。
当前设计和 agent/action/runtime 不同:
- 不从全局资产仓库安装
- 直接放在当前项目的
.agent/visualizers中 - 系统会自动扫描并在项目内发现
- 文件预览时按插件声明的匹配规则决定是否接管预览
推荐目录结构:
.agent/visualizers/
<namespace>/<visualizer-name>/
VISUALIZER.yaml
web/
index.html
...系统识别规则:
- 包含
VISUALIZER.yaml的目录会被视为一个 visualizer VISUALIZER.yaml中的match字段决定它支持哪些文件- 同一文件可命中多个 visualizer 时,宿主会按规则和优先级选择默认插件
项目内 Visualizers 管理
入口:
- 项目工作台顶部的
Agents弹框 - 其中的
Visualizers标签页
你可以做什么:
- 查看当前项目自动发现的 visualizer
- 查看 manifest 路径、web 入口路径与匹配规则
- 多选后打包下载 visualizer zip
- 上传 visualizer zip 重新导入当前项目
- 从其他项目导入已存在的 visualizer
说明:
- 这里展示的是当前项目
.agent/visualizers中已发现的插件 - 它们不是全局资产,不会自动同步到其他项目
- 更适合按项目维护专用预览器
Action / Agent / Runtime 的边界
agent- 描述用户任务语义与 step 编排
action- 描述 step 要执行的业务动作
- 可独立配置容器执行环境
runtime- 只描述运行环境,例如容器环境、远端执行或集群
在 process-first 模型里:
- runtime 回答"在哪里跑"
- action 同时回答"如何启动"和"具体跑什么程序或脚本"
动作级容器配置
容器配置现已支持在 Action 级别定义。在 ACTION.yaml 中可通过 config.container 配置:
config:
container:
image: python:3.12-slim
workdir: /workspace
gpu: 1
mounts:
- source: ./models
target: /workspace/models优先级:
- Action 级别的
config.container配置优先于 Runtime 配置 - 如果 Action 未定义 GPU 数量,则使用 Runtime 默认的
config.resources.gpu - 如果 Action 和 Runtime 都未定义 GPU 数量,则回退到项目保存的 GPU 数量
GPU 说明:
config.container.gpu与config.resources.gpu都必须是正整数- 项目里的 GPU 驱动和显存设置会作为容器 Action 运行时的补充元信息复用
典型组合:
runtime.container.default.v1+config.container.image=python:3.12-slim+entry.command=python3+entry.path=./main.pyruntime.container.default.v1+config.container.image=node:20-alpine+entry.command=node+entry.path=./main.mjsruntime.container.default.v1+config.container.image=python:3.12-slim+entry.command=Rscript+entry.path=./main.R
依赖完整性
聊天并不会把所有已安装 agent 都暴露给模型。
当前只有"依赖完整"的 agent 才会进入 agent tools 列表:
- template agent:依赖的 action 与 runtime 都必须可用
因此如果某个 agent 已安装但没有出现在聊天中,优先检查:
- action 是否已安装
- action 绑定的 runtime 是否已安装
- 容器类 action 的镜像与 entry 脚本是否可实际执行
手动运行 Agent
除了通过聊天触发 Agent,还可以手动运行:
- 在项目工作台顶部点击 Agent 相关入口
- 选择要运行的 Agent
- 填写必要的参数
- 执行后结果会显示在消息区域
适用场景:
- 需要精确控制 Agent 输入参数
- 测试或调试特定 Agent
- 执行不依赖对话上下文的独立任务
单动作执行模式
除了运行完整的 Agent,系统还支持直接执行单个 Action:
- 在聊天中通过特定语法触发单个 Action
- 无需经过完整的 Agent step 编排流程
- 适合简单的单一操作任务
说明:
- 单动作执行模式适用于不需要多步骤编排的简单任务
- 执行结果会直接返回到对话中
- 需要的 Action 必须已在项目中安装
步骤级条件执行(when 表达式)
Agent 步骤支持条件执行,通过 when 字段控制步骤是否运行:
steps:
- step_id: analyze
action_ref: data_analysis
input:
data: "${input.dataset}"
- step_id: generate_report
action_ref: report_generator
when: "input.generate_report === true"
input:
analysis: "${steps.analyze.output}"when 表达式特性:
- 支持 JavaScript 表达式求值
- 上下文包含
input(用户输入)和steps(前序步骤输出) - 支持占位符:
${input.field}和${steps.step_id.output.field} - 表达式在项目持久化容器中执行;容器不可用或求值失败时按
false处理 - 求值为
false时跳过该步骤,状态显示为Skipped - 未声明
when的步骤默认执行
典型场景:
- 根据用户输入决定是否执行可选步骤
- 根据前序步骤输出判断后续流程
- 实现条件分支逻辑
Schema 自动合并(merge_from_actions)
当 Agent 封装现有 Action 且无新增输入时,可通过 merge_from_actions 自动合并 Action 的输入 schema。条目使用与 steps[].action_ref 相同的引用形式:可以是 Action name,也可以是一/二级已安装 Action 路径,例如 repo_a/fetch_abstract。
name: paper-summary-agent
merge_from_actions:
- fetch_abstract
- summarize_abstract
inputs:
doi:
type: string
paper_url:
type: string
optional: true合并规则:
- Agent 的
inputs仅声明被${input.xxx}引用的字段名和类型 description和default从 Action 的inputs自动合并- Agent 自有属性优先,不会被覆盖
- 运行时字段
output_dir可随 ticket input 传入,用于指定本次运行的结果目录;未传入时平台会按 AgentRun 创建日期创建agents-output/<YYYY-MM-DD>/<agent-name>-<ticket-id>
优势:
- 减少重复定义
- 保持 schema 一致性
- Action 更新后自动继承新字段
步骤输出引用
步骤间数据传递支持两种形式:
单字段引用:
input:
analysis_result: "${steps.analyze.output.result}"整段输出引用(RFC-0012):
input:
full_output: "${steps.analyze.output}"整段引用适用于:
- 后续步骤需要完整的前序输出
- 输出结构动态变化
- 简化复杂对象传递
Prompt Action 编辑器
已安装的 Prompt Action 支持在线编辑提示词设置:
操作路径:
- 项目工作台顶部点击相关入口
- 找到已安装的 Prompt Action(executor_type 为
prompt) - 点击
Edit按钮 - 在弹出的编辑器中修改:
- Output mode: 选择
json或text - Prompt user: 用户提示词内容
- Prompt system: 系统提示词内容(可选)
- Output mode: 选择
- 保存后更新到 ACTION.yaml
输出模式说明:
- json: 保持当前声明的输出形状,要求模型返回严格匹配的结构化 JSON
- text: 自动将声明的输出形状重写为
{ content: string },模型返回纯文本并包装到 content 字段
适用场景:
- 快速调整 Prompt Action 的提示词内容
- 切换输出模式(结构化 JSON vs 纯文本)
- 调试或优化生成结果
说明:
- 仅对已安装的 Prompt Action 生效
- 切换到 text 模式会修改声明的输出形状
- 需要重新执行 Action 才能看到新提示词效果
持久化容器执行(免 runtime_ref)
Process Action 现在支持在项目的持久化容器中直接执行,无需显式配置 runtime_ref。
执行模式自动选择:
- 当 Action 未配置
runtime_ref时,系统自动使用项目的持久化容器执行 - 当 Action 配置了
runtime_ref时,按原有逻辑查找并使用指定的 runtime - 当 Action 定义了
config.container.image时,使用临时容器(ephemeral)执行 - 当 Action 未定义
config.container.image时,使用持久化容器(persistent)执行
优势:
- 简化 Action 定义,无需为每个使用持久化容器的 Action 重复配置
runtime_ref - 自动复用项目持久化容器中已安装的依赖和环境
- 保持跨会话的状态连续性
示例 - 无需 runtime_ref 的容器 Action:
name: data-analysis
title: Data Analysis
description: Analyze data using Python in the persistent container.
executor_type: process
# runtime_ref 不再需要 - 自动使用项目持久化容器
config:
container:
image: python:3.12-slim # 定义 image 时使用临时容器
workdir: /workspace
entry:
kind: script
path: ./analyze.py
command: python3
version: 1
inputs:
dataset:
type: string
outputs:
result:
type: string
value: ${read_string("output/result.txt")}示例 - 无 image 时使用持久化容器:
name: run-existing-script
title: Run Existing Script
description: 在持久化容器中运行已有的脚本,复用容器环境。
executor_type: process
# 未定义 runtime_ref 且未定义 config.container.image
# 自动使用项目的持久化容器执行
entry:
kind: script
path: ./scripts/process.py
command: python3
version: 1
inputs:
input_file:
type: string
outputs:
output_file:
type: file
value: ${file("output/output.json")}注意事项:
- 持久化容器执行要求项目已开启持久化容器环境
- 如果持久化容器不可用,执行会失败并提示错误
- 临时容器执行(有 image 时)与原有
docker run --rm行为一致 - 在聊天中,只有带
entry的 Action 才会被暴露为可用工具
容器镜像编辑器
已安装的 Action 支持在线编辑容器镜像配置:
操作路径:
- 项目工作台顶部点击相关入口
- 找到已安装的 Action
- 点击编辑容器镜像
- 修改镜像名称(如
python:3.12-slim→python:3.11-slim) - 保存后更新到 ACTION.yaml 的
config.container.image字段
适用场景:
- 快速切换 Python、Node 等运行环境版本
- 调试时使用不同的基础镜像
- 定制化容器环境
说明:
- 仅对已安装的 Action 生效
- 修改后需重新执行 Action 才会使用新镜像
- 需要 Runtime 支持容器执行
Agent Authoring Skill
开发模式下,系统会暴露内置只读的 agent-authoring skill,用于创建和修改 Agent:
何时使用:
- 创建新的项目 Agent
- 修改或扩展现有 Agent
- 创建新的支撑 Action
核心能力:
- 生成符合安装布局的 Agent 和 Action 文件
- 复用现有 Action,避免重复开发
- 生成可执行的 entry 脚本(支持 Node、Python、R)
- 自动设置容器配置和 runtime 引用
使用方式:
- 切换项目到开发模式
- 在聊天中描述 Agent 需求
- Skill 会把完整的 Agent 定义和 Action 文件直接写入项目安装布局
- 文件会保存到
.agent/agents/和.agent/actions/目录
生成规范:
- Agent 必须至少包含一个可执行步骤
- Action 的 entry 脚本默认通过 WDL 风格的
entry.args/entry.env接收输入,并通过声明的outputs产出最终结果 - Process Action 默认省略
runtime_ref,使用项目持久容器;只有需要指定镜像的临时容器时,才使用runtime.container.default.v1加config.container.image - 声明的 outputs 应与 action 最终产出的值严格一致
- 动态文件输出也可以由 manifest 中的路径字段驱动,但声明的输出仍应是
type: file或type: array[file],例如file(read_json("output/manifest.json").report_path)或glob(read_json("output/manifest.json").chart_pattern)
资产定义格式
Agent 定义
Agent 定义文件 AGENT.yaml 包含以下字段:
必填字段:
name: 机器安全的标识符(小写字母、数字、.、_、-)title: 人类可读的标题description: 一句话描述用户任务语义task_type: 稳定的机器可读任务标签version: 版本号(通常为1)inputs: 输入参数的 JSON Schema(type: object)steps: 有序执行步骤列表result: 声明工作流输出。输出使用与 Action outputs 相同的 WDL 风格type/value结构,并可引用input、steps.<step_id>.output、file(...)、glob(...)、read_string(...)、read_json(...)。不再支持result.step_id。
步骤字段:
step_id: 步骤标识符title: 步骤标题action_ref: 引用的 action 名称input: 输入参数映射(支持占位符)depends_on: 依赖的步骤(可选)timeout_sec: 超时时间(可选)when: 条件表达式(可选)
示例:
name: paper-summary-agent
title: Paper Summary Agent
description: Fetch an abstract for a paper title and return a concise structured summary.
task_type: paper_summary_agent
version: 1
merge_from_actions:
- fetch_abstract
- summarize_abstract
inputs:
paper_title:
type: string
steps:
- step_id: fetch_abstract
title: Fetch abstract
action_ref: fetch_abstract
input:
paper_title: ${input.paper_title}
timeout_sec: 300
- step_id: summarize_abstract
title: Summarize abstract
action_ref: summarize_abstract
input:
paper_title: ${input.paper_title}
abstract_text: ${steps.fetch_abstract.output.abstract_text}
depends_on:
- fetch_abstract
timeout_sec: 300
result:
outputs:
paper_title:
type: string
value: ${steps.summarize_abstract.output.paper_title}
summary:
type: string
value: ${steps.summarize_abstract.output.summary}Action 定义
Action 定义文件 ACTION.yaml 包含以下字段:
必填字段:
name: 机器安全的标识符title: 人类可读的标题description: 业务功能简要说明executor_type: 执行器类型(process或prompt)version: 版本号inputs: 按字段名声明的输入定义outputs: 声明 Action 的最终输出。每个字段同时定义类型以及最终值的生成/收集方式
process 类型额外字段:
runtime_ref: 引用的 runtime 名称entry: 入口配置
prompt 类型额外字段:
prompt: 提示词配置(包含user和可选的system)
executor_type: process(进程执行)
传统的脚本执行模式,需要配置 runtime 和 entry:
入口配置:
entry:
kind: script
path: ./index.mjs
command: node
args:
- ${input.query}
- ${input.days_back}
- ${input.max_results}
env:
OUTPUT_DIR: ${context.files.output_dir}
stdin: none容器配置(可选):
config:
container:
image: python:3.12-slim
workdir: /workspace
gpu: 1config.container.gpu 是可选的 Action 级 GPU 数量覆盖项,必须为正整数。未设置时,容器 Action 会依次回退到 runtime.config.resources.gpu,再回退到项目保存的 GPU 数量。
示例 - 容器执行:
name: fetch_pubmed_container
title: Fetch PubMed Container
description: Generate a normalized recent-literature JSON file and concise summary from a query inside the container runtime.
executor_type: process
runtime_ref: runtime.container.default.v1
config:
container:
image: python:3.12-slim
workdir: /workspace
gpu: 1
entry:
kind: script
path: ./index.mjs
command: node
args:
- ${input.query}
- ${input.days_back}
- ${input.max_results}
env:
OUTPUT_DIR: ${context.files.output_dir}
stdin: none
version: 1
inputs:
query:
type: string
days_back:
type: number
optional: true
max_results:
type: number
optional: true
outputs:
summary:
type: string
value: ${read_json("output/manifest.json").summary}
count:
type: number
value: ${read_json("output/manifest.json").count}
result_file:
type: file
value: ${file("output/pubmed_results.json")}也支持由 manifest 动态驱动的输出:
outputs:
report_file:
type: file
value: ${file(read_json("output/manifest.json").report_path)}
chart_files:
type: array[file]
value: ${glob(read_json("output/manifest.json").chart_pattern)}上面的 manifest 字段只是收集文件时使用的输入;对用户可见的输出仍然是标准文件描述符,因为声明字段是 type: file 和 type: array[file]。
可选输出在无法解析时会回落为 null:
outputs:
has_report:
type: boolean
value: ${exists(read_json("output/manifest.json").report_path)}
report_file:
type: file
optional: true
value: ${file(read_json("output/manifest.json").report_path)}executor_type: prompt(提示词执行)
纯配置定义的模型调用,无需编写脚本文件。适用于:
- 结构化文本生成(营销文案、报告摘要等)
- 数据提取与转换
- 文本分类与打标签
- 内容重写与润色
- 需要受限使用工具、skill 或 agent 的对话式 action
特点:
- 不需要
runtime_ref和entry - 通过
prompt字段定义系统提示词和用户提示词 - 自动使用项目默认模型
- 复用共享的主 chat runtime,而不是一次性模型调用
- 可通过可选的
capabilities限制可见的 skills、actions 和 agents - 默认输出模式是通过运行时内部结构化输出工具提交、并严格匹配声明的
outputs形状的结构化结果 - 也支持
prompt.output_mode: text纯文本模式;运行时会把最终模型文本包装到声明的content字段里
示例 - 营销文案生成:
name: generate_marketing_copy
title: Generate Marketing Copy
description: Generate structured marketing copy for a given topic.
executor_type: prompt
version: 1
inputs:
topic:
type: string
description: The topic or product to generate copy for
outputs:
title:
type: string
description: Main headline for the copy
bullets:
type: array[string]
description: Key selling points
prompt:
system: |
You are a professional marketing copywriter.
Finish by submitting the final structured result through the runtime's structured-output tool.
The submitted fields must match the declared outputs exactly.
user: |
Generate marketing copy for: ${input.topic}
capabilities:
expose_all_builtin_tools: true
expose_all_skills: true
expose_all_actions: true
expose_all_agents: true示例 - 纯文本输出并固定包装到 content:
name: summarize_topic
title: Summarize Topic
description: 生成纯文本摘要,并写入声明的 content 字段。
executor_type: prompt
version: 1
inputs:
topic:
type: string
outputs:
content:
type: string
prompt:
output_mode: text
user: |
为以下主题写一段简洁摘要:${input.topic}默认情况下,省略 capability 字段表示“一个都不暴露”。这也包括 read、bash、edit、write、web_search 这类内置基础 tool。如果要暴露整个类别,请显式设置 expose_all_builtin_tools、expose_all_skills、expose_all_actions 或 expose_all_agents;如果要精确白名单,则使用 allowed_* 数组。
Capabilities 字段详解:
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
inherit_project_skills | boolean | false | 是否继承项目已安装的 skills。只有 prompt action 需要看到显式 allowed_skills 之外的项目 skills 时才设为 true |
expose_all_builtin_tools | boolean | false | 是否暴露 prompt action 可用的全部内置基础 tools |
expose_all_skills | boolean | false | 是否暴露所有项目已安装的 skills(当 inherit_project_skills=true 时生效) |
expose_all_actions | boolean | false | 是否暴露所有项目已安装的 actions |
expose_all_agents | boolean | false | 是否暴露所有项目已安装的 agents |
allowed_builtin_tools | string[] | [] | 精确白名单:允许使用的内置 tool 名称,如 read、bash、edit、write、web_search |
allowed_skills | string[] | [] | 精确白名单:允许使用的 skill 名称列表 |
allowed_actions | string[] | [] | 精确白名单:允许调用的 action 名称列表 |
allowed_agents | string[] | [] | 精确白名单:允许触发的 agent 名称列表 |
优先级规则:
inherit_project_skills=false时,仅使用allowed_skills白名单expose_all_builtin_tools=true时,暴露所有内置基础 toolsinherit_project_skills=true+expose_all_skills=true时,暴露所有项目 skillsinherit_project_skills=true+expose_all_skills=false+allowed_skills有值时,使用白名单expose_all_*与allowed_*同时设置时,expose_all_*优先
UI 显示: 在项目工作台的 Action 详情面板中,可以看到以下 capabilities 信息:
- inherits skills: 显示是否继承项目 skills(
yes/no) - allowed builtin tools: 显示允许使用的内置基础 tools 列表
- allowed skills: 显示允许使用的 skills 列表
- allowed actions: 显示允许调用的 actions 列表
- allowed agents: 显示允许触发的 agents 列表
自引用警告:
如果 prompt action 在 allowed_actions 中包含自身名称,系统会在 Action 详情面板中显示警告,提示可能的递归自调用风险。建议移除自引用或确保有明确的终止条件。
示例 - 文本摘要:
name: summarize_text
title: Summarize Text
description: Generate a concise summary of the input text.
executor_type: prompt
version: 1
inputs:
text:
type: string
description: The text to summarize
max_length:
type: number
description: Maximum summary length in words
optional: true
default: 100
outputs:
summary:
type: string
key_points:
type: array[string]
prompt:
user: |
Summarize the following text in at most ${input.max_length} words.
在最终结构化结果中包含简短摘要和关键点列表。
Text: ${input.text}
capabilities:
allowed_skills: ["summarization"]
allowed_actions: []
allowed_agents: []提示词模板语法:
${input.field_name}: 插入输入参数值${input.nested.field}: 使用点路径读取嵌套对象字段${input.field | json}: 将值格式化为美化后的 JSON- 支持字符串、数字、布尔值自动格式化
- 复杂对象会自动转为 JSON 字符串
- 不支持的
${...}表达式会直接报错,不会作为 JavaScript 执行
执行流程:
- 验证输入参数符合
inputs - 渲染
prompt.system和prompt.user模板 - 基于可选
capabilities组装受限的共享 chat runtime - 在允许的情况下复用共享 tools、skills 和 agents 调用项目默认模型
- 从运行时内部的结构化输出工具中捕获最终结构化结果
- 验证输出符合声明的输出形状
- 返回结构化结果
适用场景对比:
| 场景 | process | prompt |
|---|---|---|
| 需要文件系统操作 | ✓ | ✗ |
| 需要外部 API 调用 | ✓ | ✗ |
| 需要复杂计算逻辑 | ✓ | ✗ |
| 纯文本转换/生成 | ✗ | ✓ |
| 无需编写代码 | ✗ | ✓ |
| 快速原型验证 | ✗ | ✓ |
注意事项:
- 在
prompt.output_mode: json下,最终结构化结果通过内部 tool call 提交,而不是从 assistant 文本里解析 JSON - 输出结构必须严格匹配声明的输出形状
- 在
capabilities允许时,prompt action 可以使用共享 tools、skills 和 agents - 不能访问文件系统或外部服务
Action Entry 脚本规范(process 类型)
Entry 脚本应遵循以下约定:
输入:优先使用 entry.args 和 entry.env 声明 WDL 风格的命令输入。
entry:
kind: script
path: ./index.mjs
command: node
args:
- ${input.paper_title}
env:
OUTPUT_DIR: ${context.files.output_dir}
stdin: none模板表达式支持 ${input.field}、${input.nested.field}、${config.field}、${context.field} 和 | json 过滤器。整个参数解析为数组时会展开成多个 argv。只有脚本需要完整 { input, config, context } payload 时才使用 stdin: json。
输出:
- 把结果文件写入
context.files.output_dir,再由运行时按声明的outputs自动收集 outputs.value中的相对文件表达式以本次运行的输出目录为基准解析;返回的文件描述符仍然是 project workspace 相对路径- 进程成功由退出码和
outputs收集成功共同决定 - 出错时输出可读的 stderr,并以非零退出码结束
Node.js 示例(outputs 优先模式):
import { mkdir, writeFile } from "node:fs/promises";
import path from "node:path";
async function main() {
const title = (process.argv[2] ?? "").trim();
const outputDir = process.env.OUTPUT_DIR || "/workspace";
if (!title) {
throw new Error("paper_title is required.");
}
const resultsDir = path.join(outputDir, "output");
await mkdir(resultsDir, { recursive: true });
await writeFile(path.join(resultsDir, "abstract.txt"), `Abstract for ${title}: ...`, "utf8");
}
main()
.then(() => {
process.stdout.write("ok");
})
.catch((error) => {
process.stderr.write(`${error instanceof Error ? error.message : "Unknown error"}\n`);
process.exit(1);
});Runtime 定义
Runtime 定义文件 RUNTIME.yaml 描述执行环境:
字段说明:
name: Runtime 标识符。Action 通过runtime_ref引用这个值。title: 资产列表中显示的人类可读标题。kind: Runtime 类型。当前 Process Action 只支持containerruntime。source: 来源标记,例如system_builtin、user_defined、model_generated。status: 资产生命周期标记,例如published。当前执行路径不会把它作为强制启停开关。config: Runtime 配置对象。protocol: 通信协议,必须是stdio_json。env: 合并到 process action 执行环境中的环境变量。timeouts.max_execution_sec: 默认墙钟超时时间,单位秒。Agent step 上的timeout_sec会覆盖它。设置为0表示禁用应用层等待超时。resources.cpu: action 执行目标请求的 CPU 数量。resources.memory_mb: 内存大小,单位 MB。resources.disk_gb: 磁盘大小,单位 GB,主要影响临时容器的资源准入。resources.gpu: 该 runtime 的默认 GPU 数量(可选),提供时必须为正整数。container: 当前会被解析以保持兼容,但执行器不会使用 runtime 级别的container.image、container.workdir或container.mounts来启动 action。镜像、工作目录和 action 专属容器设置应写在ACTION.yaml的config.container下。
version: 定义版本标记。
查找顺序:
- 如果 Action 配置了
runtime_ref,ResearchX 会先查项目本地.agent/runtimes/<runtime_ref>/RUNTIME.yaml。 - 如果项目本地没有同名 runtime,再回退到全局 runtime catalog。
- 项目本地 runtime 与全局 runtime 同名时,本地 runtime 会作为项目级覆盖。
- 如果 Action 省略
runtime_ref,它会走项目持久化容器路径,不会读取全局runtime.container.default.v1定义。
示例 - 容器 Runtime:
{
"name": "runtime.container.default.v1",
"title": "Container Runtime",
"kind": "container",
"source": "system_builtin",
"status": "published",
"config": {
"protocol": "stdio_json",
"container": {
"image": "python:3.12-slim",
"workdir": "/workspace"
},
"timeouts": {
"max_execution_sec": 6000
},
"resources": {
"cpu": 2,
"memory_mb": 2048,
"disk_gb": 4,
"gpu": 1
}
},
"version": 1
}在上面的示例中,protocol、timeouts 和 resources 会影响执行。container.image 和 container.workdir 当前主要是信息性/前向兼容字段;实际生效的容器镜像和工作目录应写在每个 process Action 中:
executor_type: process
runtime_ref: runtime.container.default.v1
config:
container:
image: python:3.12-slim
workdir: /workspace文件组织结构
资产文件必须按以下结构组织:
.agent/
├── agents/
│ └── <agent-name>/
│ └── AGENT.yaml
├── actions/
│ ├── <action-name>/
│ │ ├── ACTION.yaml
│ │ └── index.mjs # 或 index.py, main.R 等
│ └── <another-action>/
│ ├── ACTION.yaml
│ └── index.mjs
└── runtimes/
└── <runtime-name>/
└── RUNTIME.yaml规则:
- 每个资产使用独立目录
- 目录名应与资产
name一致 - Action 的
ACTION.yaml和 entry 脚本放在同一目录 - 不要跨 action 目录引用文件
使用建议
- 将共享资产统一维护在 Git 仓库,不要直接在项目
.agent目录里手工长期维护 - 修改全局资产后,先在管理页同步并验证,再到项目中重新安装
- action 的 entry 脚本应放在自己的 action 目录内,不要跨 action 目录引用
- 将 runtime 视为环境定义;启动命令应直接写在 action entry 上
- process 型 action 默认应通过
entry.args/entry.env接收显式命令输入,把产物写入 workspace,再由运行时通过outputs解析最终结果;仅在明确需要完整 payload 时使用 stdin JSON - agent 的
title和description应写成用户任务语义,不要写成内部技术实现说明 - 使用
when条件实现灵活的执行流程控制 - 使用
merge_from_actions减少 schema 重复定义
Agent 导入导出
项目已安装的 Agents 支持打包导出与批量导入,方便跨项目迁移与备份。
导出 Agents
在项目 Agents 弹框中,你可以:
- 选择要导出的已安装 Agents(支持多选)
- 点击导出按钮
- 系统将选中的 Agents、依赖的 Actions 以及项目本地 runtime 依赖打包成 zip 文件下载
导出的 zip 文件结构:
agents-20260401-120000.zip
├── runtimes/ # 被打包 action 引用的项目本地 runtimes
│ └── <runtime-name>/
│ └── RUNTIME.yaml
├── agents/ # Agents 文件目录
│ └── <agent-name>/ # Agent 目录
│ ├── AGENT.yaml
│ └── ...其他文件
└── actions/ # Actions 文件目录
└── <action-name>/ # Action 目录
├── ACTION.yaml
└── index.mjs导出时会自动包含依赖:
- 系统会分析每个 Agent 的 AGENT.yaml 中引用的 Actions
- 自动将相关 Actions 也打包到导出文件中
- 自动将被打包 Actions 引用的项目本地 Runtimes 打包到导出文件中
- 仅存在于全局 catalog 的 runtime 不会复制进 archive,目标项目会继续从全局 catalog 解析
- 确保导入后 Agent 能正常执行
Runtime 导入行为:
- bundled runtimes 会先于 bundled actions 和 agents 安装。
- 如果目标项目已有同名 runtime,且
RUNTIME.yaml内容一致,导入会复用它。 - 如果目标项目已有同名 runtime,但内容不同,导入会以冲突停止,不会静默覆盖。
- 将 Agents 导入管理员资产仓库时,bundled runtimes 会导入到所选仓库组中对应的 runtime repository。
从其他项目导入 Agents
除了导入 zip 文件,还可以直接从其他项目导入已安装的 Agents:
操作路径:
- 在项目 Agents 弹框中点击"从项目导入"按钮
- 在弹出的对话框中选择源项目(下拉菜单显示所有可访问项目)
- 系统自动加载源项目中已安装的 Agents 列表
- 查看 Agent 名称、标题、描述和安装路径
- 点击"从项目导入"按钮导入单个 Agent
导入特点:
- 如果 Agent 名称与当前尝试查找的名称匹配,会显示"名称匹配"标签便于识别
- 按名称匹配优先、标题字母顺序排列
- 只显示已安装的 Agents
- 导入时会自动包含 Agent 依赖的 Actions 和项目本地 Runtimes
适用场景:
- 快速复制其他项目中已验证的 Agents
- 避免 Agent、依赖 Actions 和 Runtimes 的重复安装
- 团队成员共享已配置好的 Agent 组合
注意事项:
- 如果目标项目已存在同名 Agent 或 Action,导入会失败
- 导入的 Agent 使用源项目的当前版本快照
- 需要有源项目的访问权限才能看到其 Agents
导入 Agents
在项目 Agents 弹框中,你可以:
- 点击导入按钮
- 上传 Agents zip 文件
- 系统安装压缩包中的 Runtimes、Actions 和 Agents
导入时会:
- 读取 zip 文件中的
runtimes/、actions/和agents/目录 - 将 bundled Runtimes、Actions 和 Agents 复制到项目的
.agent/下 - 创建数据库安装记录
注意事项:
- 如果项目中已存在同名 Agent 或 Action,导入会失败并提示冲突详情
- 导入后 Runtimes、Actions 和 Agents 立即可用于项目
- 建议在导入前确认资产来源可信
- 导入会一并安装 zip 中包含的所有 Actions,即使某些 Actions 不被 Agent 直接引用
- 开发模式下使用 agent-authoring skill 快速创建和迭代 Agent
Action 导入导出
项目已安装的 Actions 支持打包导出与批量导入,操作方式与 Agents 导入导出一致。
导出 Actions
在项目 Assets 弹框的 Actions 标签页中,你可以:
- 勾选要导出的已安装 Actions(支持多选、全选当前可见)
- 点击"下载所选 Actions"按钮
- 系统将选中的 Actions 和项目本地 runtime 依赖打包成 zip 文件下载
导出的 action archive 可能包含:
actions-20260401-120000.zip
├── runtimes/
│ └── <runtime-name>/
│ └── RUNTIME.yaml
└── actions/
└── <action-name>/
├── ACTION.yaml
└── index.mjs导出的 Actions 引用的项目本地 Runtimes 会被打包。仅存在于全局 catalog 的 runtime 会作为全局依赖保留。
从其他项目导入 Actions
除了导入 zip 文件,还可以直接从其他项目导入已安装的 Actions:
- 在 Actions 标签页中点击"从项目导入"按钮
- 选择源项目
- 系统加载源项目中已安装的 Actions 列表
- 点击导入即可将单个 Action 安装到当前项目
导入 Actions Zip
- 点击"导入 Action 压缩包"按钮
- 上传之前导出的 Actions zip 文件
- 系统自动解析并安装
注意事项:
- 如果项目中已存在同名 Action,导入会失败并提示冲突
- Bundled Runtimes 会先于 Actions 安装。目标项目已有同名但内容不同的 runtime 时,会产生导入冲突。
- 建议在导入前确认资产来源可信