Guides
AnyToolDefinition
定义、注册和执行 we0agent 工具:Pydantic 参数、执行策略、ToolContext、ToolExecuteResult 和工具事件。
工具是模型可以调用的业务能力。We0Agent(tools=...) 接收的是 Sequence[AnyToolDefinition],其中 AnyToolDefinition 是 ToolDefinition[Any] 的类型别名。
一个工具定义由四部分组成:工具 id、描述、Pydantic 参数 schema、异步执行函数。
最小定义顺序
第一步定义参数 schema。字段描述会进入模型工具 schema,应写清格式、单位和约束。
from pathlib import Path
from pydantic import Field, BaseModel
class ReadFileParameters(BaseModel):
path: str = Field(description="Path of the UTF-8 text file to read.")第二步定义异步执行函数。函数入参固定是 parameters 和 context,返回值固定是 ToolExecuteResult。
from we0agent.domain.models.tools import ToolContext, ToolExecuteResult
async def read_file(
parameters: ReadFileParameters,
context: ToolContext,
) -> ToolExecuteResult:
del context
path = Path(parameters.path).expanduser()
return ToolExecuteResult(
title=f"Read {path}",
metadata={"path": str(path)},
output=path.read_text(encoding="utf-8"),
)第三步用 define(...).init() 得到 AnyToolDefinition,再传给 We0Agent。
from we0agent.domain.types.tools import AnyToolDefinition
from we0agent.tools.core.definition import ToolDefinitionInit, define
read_file_tool: AnyToolDefinition = await define(
"read_file",
ToolDefinitionInit(
description="Read a UTF-8 text file from the local filesystem.",
parameters=ReadFileParameters,
execute_handler=read_file,
),
).init()
tools: list[AnyToolDefinition] = [read_file_tool]
agent = We0Agent(
name="assistant",
model=model,
system_prompt=system_prompt,
tools=tools,
)工具调用链路
参数 schema
参数 schema 使用 Pydantic BaseModel。字段描述会进入模型工具 schema,所以要写给模型看,而不只是写给人看。
class WriteFileParameters(BaseModel):
path: str = Field(description="Path of the file to write.")
content: str = Field(description="Full UTF-8 text content to write.")建议:
- 字段名稳定、短、可预测。
description说明单位、格式和约束。- 不要把多个含义塞进一个
str字段。 - 能用枚举就不要让模型自由生成字符串。
ToolExecuteResult
工具返回 ToolExecuteResult:
| 字段 | 类型 | 说明 |
|---|---|---|
title | str | None | 人类可读的工具结果标题,适合 UI 展示。 |
metadata | dict[str, Any] | 结构化元数据,如路径、exit code、行数。 |
output | Any | 工具结果正文,会进入工具结果事件和会话历史。 |
示例:
return ToolExecuteResult(
title=f"Wrote {path}",
metadata={"path": str(path), "bytes": len(content.encode("utf-8"))},
output=f"Wrote {path}",
)执行策略
ToolExecutionPolicy 告诉 engine 这个工具是否可以并发、是否有副作用。
from we0agent.tools.core.policy import ToolExecutionPolicy
ToolExecutionPolicy(
is_concurrency_safe=False,
has_side_effects=True,
)| 字段 | 含义 | 例子 |
|---|---|---|
is_concurrency_safe | 多个工具调用能否并发执行 | 读文件通常可以,写同一个目录通常不可以 |
has_side_effects | 是否改变外部世界 | 写文件、发请求、执行命令都是副作用 |
有副作用或不并发安全的工具会影响工具批次划分。不要把写文件、shell 命令、数据库写入标成 concurrency safe。
ToolContext
ToolContext 承载执行时上下文。工具 handler 必须接收它,即使当前不使用也要保留参数。
async def my_tool(parameters: MyParameters, context: ToolContext) -> ToolExecuteResult:
...后续接入业务上下文、session 信息、权限或观测字段时,ToolContext 是主要扩展点之一。
注册表
ToolRegistry 用于按 id 管理工具。
from we0agent.tools.core.registry import ToolRegistry
registry = ToolRegistry()
registry.register(read_file_tool)
tool = registry.get("read_file")重复 id 默认报错,需要覆盖时显式传 overwrite=True。
执行事件
工具相关事件按这个顺序出现:
| 事件 | 说明 |
|---|---|
tool-input-* | 模型正在生成工具参数,可能是 JSON 字符串分片。 |
tool-call | 参数完整,engine 准备执行工具。 |
tool-result | 工具成功返回。 |
tool-error | 工具执行失败或参数校验失败。 |
完整字段见 Events。
安全建议
- 生产环境不要直接暴露不受限的
bash。 - 对写文件、发请求、删除数据、改权限等工具做业务鉴权。
- 工具错误要可读,避免把内部 traceback 原样暴露给用户。
- 给高风险工具设置明确 schema,不要让模型自由拼接命令。
- 有副作用工具配合 snapshot 时,确保工具写入的是被 snapshot 追踪的 worktree。
示例
下面是一组本地示例常见工具划分:
| 工具 | 作用 | 策略 |
|---|---|---|
read_file | 读取 UTF-8 文件 | 并发安全、无副作用 |
write_file | 写入完整文件 | 不并发安全、有副作用 |
edit_file | 替换首个匹配文本 | 不并发安全、有副作用 |
bash | 执行 shell 命令 | 不并发安全、有副作用 |
这些工具适合学习 SDK 形态;业务项目应按自己的权限模型重写。