中文EN
ResearchX Docs
中文

Agent / Action / Runtime / Visualizer 管理

管理员维护全局资产仓库,manager 与 owner 安装项目级 agent、action、runtime,并管理项目内 visualizer 插件

Agent / Action / Runtime / Visualizer 管理

两层管理

当前系统将 agent 资产管理拆成两层:

  • 全局资产仓库管理:管理员维护共享 agentactionruntime 来源
  • 项目内资产安装:manager 与 owner 将这些资产安装到当前项目

这里的“资产”特指:

  • agent
  • action
  • runtime

visualizer 目前采用项目本地插件模式,不走全局资产仓库安装链路。

管理员全局 Agent 管理

入口:

  • Workspace 左下角菜单中的 Agents
  • 页面路径:/workspace/admin/assets

你可以做什么:

  • 添加 Git 或 GitHub 资产仓库
  • 指定仓库分支
  • 手动同步单个仓库
  • 删除整个仓库
  • 搜索仓库与资产
  • 在线编辑资产 definition 文件
  • 对 action 在线编辑 entry 脚本
  • 对全局 agent 执行“启用全局”或“停用全局”

Mixed Repository 模型

当前资产仓库不再按 actions / agents / runtimes 分开添加。

一个仓库可以同时包含多种资产,系统会自动识别并聚合展示:

  • actions
  • agents
  • runtimes

页面上看到的是一个 mixed repository 视图:

  • 一个 Git 仓库只显示一张卡片
  • 卡片内部按资产类型分组展示
  • 同步、删除、编辑都按这一个仓库视图操作

仓库同步与扫描

当管理员添加资产仓库后,系统会:

  1. 拉取仓库到本地资产存储目录
  2. 自动扫描仓库内的 ACTION.yamlAGENT.yamlRUNTIME.yaml
  3. 建立全局资产索引
  4. 在管理页中显示解析出的资产列表

说明:

  • 一个目录中包含 ACTION.yaml 会被识别为一个 action
  • 一个目录中包含 AGENT.yaml 会被识别为一个 agent
  • 一个目录中包含 RUNTIME.yaml 会被识别为一个 runtime
  • builtin 资产也会出现在该页面中,但 builtin repository 不能删除

在线编辑

当前管理页已支持最小文本编辑能力:

  • 点击 Edit 后以弹层方式打开编辑器
  • agent / runtime 可编辑 definition
  • action 可编辑:
    • 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.gpuconfig.resources.gpu 都必须是正整数
  • 项目里的 GPU 驱动和显存设置会作为容器 Action 运行时的补充元信息复用

典型组合:

  • runtime.container.default.v1 + config.container.image=python:3.12-slim + entry.command=python3 + entry.path=./main.py
  • runtime.container.default.v1 + config.container.image=node:20-alpine + entry.command=node + entry.path=./main.mjs
  • runtime.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,还可以手动运行:

  1. 在项目工作台顶部点击 Agent 相关入口
  2. 选择要运行的 Agent
  3. 填写必要的参数
  4. 执行后结果会显示在消息区域

适用场景:

  • 需要精确控制 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} 引用的字段名和类型
  • descriptiondefault 从 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 支持在线编辑提示词设置:

操作路径:

  1. 项目工作台顶部点击相关入口
  2. 找到已安装的 Prompt Action(executor_type 为 prompt
  3. 点击 Edit 按钮
  4. 在弹出的编辑器中修改:
    • Output mode: 选择 jsontext
    • Prompt user: 用户提示词内容
    • Prompt system: 系统提示词内容(可选)
  5. 保存后更新到 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 支持在线编辑容器镜像配置:

操作路径:

  1. 项目工作台顶部点击相关入口
  2. 找到已安装的 Action
  3. 点击编辑容器镜像
  4. 修改镜像名称(如 python:3.12-slimpython:3.11-slim
  5. 保存后更新到 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 引用

使用方式

  1. 切换项目到开发模式
  2. 在聊天中描述 Agent 需求
  3. Skill 会把完整的 Agent 定义和 Action 文件直接写入项目安装布局
  4. 文件会保存到 .agent/agents/.agent/actions/ 目录

生成规范

  • Agent 必须至少包含一个可执行步骤
  • Action 的 entry 脚本默认通过 WDL 风格的 entry.args / entry.env 接收输入,并通过声明的 outputs 产出最终结果
  • Process Action 默认省略 runtime_ref,使用项目持久容器;只有需要指定镜像的临时容器时,才使用 runtime.container.default.v1config.container.image
  • 声明的 outputs 应与 action 最终产出的值严格一致
  • 动态文件输出也可以由 manifest 中的路径字段驱动,但声明的输出仍应是 type: filetype: 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 结构,并可引用 inputsteps.<step_id>.outputfile(...)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: 执行器类型(processprompt
  • 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: 1

config.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: filetype: 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_refentry
  • 通过 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 字段表示“一个都不暴露”。这也包括 readbasheditwriteweb_search 这类内置基础 tool。如果要暴露整个类别,请显式设置 expose_all_builtin_toolsexpose_all_skillsexpose_all_actionsexpose_all_agents;如果要精确白名单,则使用 allowed_* 数组。

Capabilities 字段详解

字段类型默认值说明
inherit_project_skillsbooleanfalse是否继承项目已安装的 skills。只有 prompt action 需要看到显式 allowed_skills 之外的项目 skills 时才设为 true
expose_all_builtin_toolsbooleanfalse是否暴露 prompt action 可用的全部内置基础 tools
expose_all_skillsbooleanfalse是否暴露所有项目已安装的 skills(当 inherit_project_skills=true 时生效)
expose_all_actionsbooleanfalse是否暴露所有项目已安装的 actions
expose_all_agentsbooleanfalse是否暴露所有项目已安装的 agents
allowed_builtin_toolsstring[][]精确白名单:允许使用的内置 tool 名称,如 readbasheditwriteweb_search
allowed_skillsstring[][]精确白名单:允许使用的 skill 名称列表
allowed_actionsstring[][]精确白名单:允许调用的 action 名称列表
allowed_agentsstring[][]精确白名单:允许触发的 agent 名称列表

优先级规则

  • inherit_project_skills=false 时,仅使用 allowed_skills 白名单
  • expose_all_builtin_tools=true 时,暴露所有内置基础 tools
  • inherit_project_skills=true + expose_all_skills=true 时,暴露所有项目 skills
  • inherit_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 执行

执行流程

  1. 验证输入参数符合 inputs
  2. 渲染 prompt.systemprompt.user 模板
  3. 基于可选 capabilities 组装受限的共享 chat runtime
  4. 在允许的情况下复用共享 tools、skills 和 agents 调用项目默认模型
  5. 从运行时内部的结构化输出工具中捕获最终结构化结果
  6. 验证输出符合声明的输出形状
  7. 返回结构化结果

适用场景对比

场景processprompt
需要文件系统操作
需要外部 API 调用
需要复杂计算逻辑
纯文本转换/生成
无需编写代码
快速原型验证

注意事项

  • prompt.output_mode: json 下,最终结构化结果通过内部 tool call 提交,而不是从 assistant 文本里解析 JSON
  • 输出结构必须严格匹配声明的输出形状
  • capabilities 允许时,prompt action 可以使用共享 tools、skills 和 agents
  • 不能访问文件系统或外部服务

Action Entry 脚本规范(process 类型)

Entry 脚本应遵循以下约定:

输入:优先使用 entry.argsentry.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 只支持 container runtime。
  • source: 来源标记,例如 system_builtinuser_definedmodel_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.imagecontainer.workdircontainer.mounts 来启动 action。镜像、工作目录和 action 专属容器设置应写在 ACTION.yamlconfig.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
}

在上面的示例中,protocoltimeoutsresources 会影响执行。container.imagecontainer.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 的 titledescription 应写成用户任务语义,不要写成内部技术实现说明
  • 使用 when 条件实现灵活的执行流程控制
  • 使用 merge_from_actions 减少 schema 重复定义

Agent 导入导出

项目已安装的 Agents 支持打包导出与批量导入,方便跨项目迁移与备份。

导出 Agents

在项目 Agents 弹框中,你可以:

  1. 选择要导出的已安装 Agents(支持多选)
  2. 点击导出按钮
  3. 系统将选中的 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:

操作路径:

  1. 在项目 Agents 弹框中点击"从项目导入"按钮
  2. 在弹出的对话框中选择源项目(下拉菜单显示所有可访问项目)
  3. 系统自动加载源项目中已安装的 Agents 列表
  4. 查看 Agent 名称、标题、描述和安装路径
  5. 点击"从项目导入"按钮导入单个 Agent

导入特点:

  • 如果 Agent 名称与当前尝试查找的名称匹配,会显示"名称匹配"标签便于识别
  • 按名称匹配优先、标题字母顺序排列
  • 只显示已安装的 Agents
  • 导入时会自动包含 Agent 依赖的 Actions 和项目本地 Runtimes

适用场景:

  • 快速复制其他项目中已验证的 Agents
  • 避免 Agent、依赖 Actions 和 Runtimes 的重复安装
  • 团队成员共享已配置好的 Agent 组合

注意事项:

  • 如果目标项目已存在同名 Agent 或 Action,导入会失败
  • 导入的 Agent 使用源项目的当前版本快照
  • 需要有源项目的访问权限才能看到其 Agents

导入 Agents

在项目 Agents 弹框中,你可以:

  1. 点击导入按钮
  2. 上传 Agents zip 文件
  3. 系统安装压缩包中的 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 标签页中,你可以:

  1. 勾选要导出的已安装 Actions(支持多选、全选当前可见)
  2. 点击"下载所选 Actions"按钮
  3. 系统将选中的 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:

  1. 在 Actions 标签页中点击"从项目导入"按钮
  2. 选择源项目
  3. 系统加载源项目中已安装的 Actions 列表
  4. 点击导入即可将单个 Action 安装到当前项目

导入 Actions Zip

  1. 点击"导入 Action 压缩包"按钮
  2. 上传之前导出的 Actions zip 文件
  3. 系统自动解析并安装

注意事项:

  • 如果项目中已存在同名 Action,导入会失败并提示冲突
  • Bundled Runtimes 会先于 Actions 安装。目标项目已有同名但内容不同的 runtime 时,会产生导入冲突。
  • 建议在导入前确认资产来源可信