Skip to content

Action Runtime

模型要“做事”时,需要一个明确的能力边界。Action Runtime 负责把这些外部能力暴露给模型:本地函数、Search、Browse、MCP、Python、shell、Node.js、SQLite 或自定义执行后端。

先从应用开发入口开始,不要一上来读插件层。

第一个 Action

python
from agently import Agently

agent = Agently.create_agent()


@agent.action_func
async def add(a: int, b: int) -> int:
    """两个整数相加。"""
    return a + b


agent.use_actions([add])

result = (
    agent
    .input("使用 action 计算 3333 + 6666。")
    .output({"answer": (int, "计算结果", True)})
    .get_result()
)

data = result.get_data()

@agent.action_func 从函数签名和 docstring 推导 action schema。agent.use_actions(...) 把它挂到 agent 上。模型在一次 request 内决定是否调用。

常用入口

入口适合
@agent.action_func把本地 Python 函数暴露给模型
agent.use_actions([...])注册一个或多个 action
agent.use_actions(["name"])按名称注册已经预注册的 action
agent.enable_python(...)给模型托管 Python 执行能力
agent.enable_shell(...)给模型受控 shell,建议配 command allowlist
agent.enable_workspace_file_actions(...)把当前 Workspace 文件作业区暴露成文件 actions
agent.enable_nodejs(...)给模型托管 Node.js 执行能力
agent.enable_sqlite(...)给模型 SQLite 查询能力
agent.use_actions(Search(...))注册内置搜索能力
agent.use_actions(Browse(...))注册内置页面浏览能力
@agent.auto_func用函数签名和 docstring 让模型生成实现,并使用已注册 action

内置 Search / Browse:

python
from agently.builtins.actions import Browse, Search

agent.use_actions(Search(timeout=15, backend="auto"))
agent.use_actions(Browse())

Search 是 Action-native package,不进入 Execution Environment。Browse 默认主线是 Playwright + BS4;如果 Browse 需要托管 browser/page/session,再启用 Browser Execution Environment。

托管能力 helpers

应用开发者要开放常见执行能力时,优先用 enable_* helpers:

python
agent.enable_python()
agent.enable_shell(commands=["pwd", "pytest"])
agent.enable_workspace_file_actions(write=True)
agent.enable_nodejs()
agent.enable_sqlite("./data/app.db")

这些 helper 会保留默认描述和安全边界。desc= 可以补充说明;确实要替换默认描述时用 desc_mode="override",只保留内置描述时用 desc_mode="default"

只有开发自定义 Action 后端时,才需要直接使用 register_action(..., executor=..., execution_environments=[...])

查看实际调用记录

指令型 action 会记录 digest 和 artifact refs,避免把完整代码、shell 输出、SQL 结果、页面 HTML、截图等原始内容每一轮都塞回 prompt。

python
turn = agent.input("使用 action,并总结执行结果。")
records = agent.get_action_result(prompt=turn.prompt)

for record in records:
    print(record)

如果需要读取 artifact 详情:

python
artifact_ref = records[0]["artifact_refs"][0]

raw = agent.action.read_action_artifact(
    artifact_id=artifact_ref["artifact_id"],
    action_call_id=artifact_ref["action_call_id"],
)

后续 action planning round 默认看到 digest。它知道发生了什么,但不会默认拿到完整 payload。

Action planning 用哪个模型

Action planning 是模型拥有的步骤。如果项目使用 model_pool,可以指定 action planning 的业务模型 key:

python
agent.set_settings("model_pool", {"task-main": "deepseek-chat-prod"})
agent.set_settings("action.planning_model_key", "task-main")

这会作用于默认 structured-plan 和 native tool-call planning 路径。SkillsExecutor 或 AgentTaskLoop 把 bounded action round 委托给 ActionRuntime 时,这个设置尤其重要。

Runtime 层级

应用开发者通常不需要先读这一段;写插件或排查架构时再看。

text
TriggerFlow

ActionRuntime      # 规划 + 调用归一化 + 派发

ActionFlow         # runtime 和 flow 表示之间的桥

ActionExecutor     # local function、MCP、sandbox、Search、Browse 等原子执行

默认连线:

text
Agent → ActionExtension → Action facade → ActionRuntime → ActionFlow → ActionExecutor

可替换插件类型:

  • ActionRuntime:改规划协议或调用归一化。
  • ActionFlow:改 runtime 与 flow 之间的编排形态。
  • ActionExecutor:加新后端,比如 HTTP、gRPC、远程 worker、自定义沙箱。

agently.types.plugins 导入协议:

python
from agently.types.plugins import (
    ActionExecutor,
    ActionRuntime,
    ActionFlow,
    ActionPlanningHandler,
    ActionExecutionHandler,
)

旧的 ToolManager 插件类型只作为遗留兼容保留。新插件不要写在 ToolManager 上。

什么时候升级到 TriggerFlow

Action 只负责一次 request 内的能力调用。多个 action 调用之上的高层流控、分支、人工审批、暂停恢复、持久化,不要塞进 executor。用 TriggerFlow 管这些流程。

你想改放哪里
新后端执行方式ActionExecutor
规划协议ActionRuntime
MCP/sandbox/process 生命周期ExecutionEnvironment
多阶段业务流程TriggerFlow

兼容入口

@agent.tool_funcagent.use_tool(...)agent.use_tools(...)extra.tool_logs 等旧入口仍可用,内部映射到 Action Runtime。新代码推荐使用 action 入口。

继续读:工具兼容

常见误用

  • 把业务工作流写进 ActionExecutor。
  • 用一个巨大的 action 代表所有业务能力。
  • 手工把工具目录写进 prompt,和真实 action surface 不一致。
  • 新插件继续基于 ToolManager
  • 不读取 action logs,无法解释模型到底调用了什么。

下一步