工具 Handlers(默认与替换)
适用版本:
v4.0.8.2
Tool Loop 的扩展点很少,核心就两个:
plan_analysis_handlertool_execution_handler
1. 默认 handler 链与可替换点
如何阅读这张图
- 规划器和执行器是两个明确断点,分别对应“决策”和“副作用”。
- 结果注入不是第三个可替换 handler,而是框架稳定协议的一部分,所以建议保留默认行为。
架构思路
最重要的边界不是“能不能自定义”,而是“不要把推理逻辑和副作用混在一个 handler 里”。否则后续很难追踪到底是规划错了,还是执行层失控了。
2. plan_analysis_handler
职责:
- 决定本轮是
execute还是response - 产出
execution_commands[]
签名:
python
async def custom_plan_handler(
prompt,
settings,
tool_list,
done_plans,
last_round_records,
round_index,
max_rounds,
agent_name,
): ...推荐返回:
python
{
"next_action": "execute" | "response",
"execution_commands": [
{
"purpose": str,
"tool_name": str,
"tool_kwargs": dict,
"todo_suggestion": str,
}
],
}3. tool_execution_handler
职责:
- 执行
execution_commands - 返回可审计的执行记录
签名:
python
async def custom_execution_handler(
tool_commands,
settings,
async_call_tool,
done_plans,
round_index,
concurrency,
agent_name,
): ...推荐返回:
python
[
{
"purpose": str,
"tool_name": str,
"kwargs": dict,
"todo_suggestion": str,
"success": bool,
"result": Any,
"error": str,
}
]4. 默认行为有哪些
默认规划器:
- 使用独立
ModelRequest - 监听
instant.next_action - 当
next_action=response时提前短路
默认执行器:
- 使用
tool.loop.concurrency做并发控制 - 逐条调用
async_call_tool(...) - 对错误字符串自动标注
success=False
5. 在 Agent 层替换
python
from agently import Agently
agent = Agently.create_agent()
agent.register_tool_plan_analysis_handler(custom_plan_handler)
agent.register_tool_execution_handler(custom_execution_handler)恢复默认:
python
agent.register_tool_plan_analysis_handler(None)
agent.register_tool_execution_handler(None)6. 在 Core 层全局替换
python
from agently import Agently
Agently.tool.register_plan_analysis_handler(custom_plan_handler)
Agently.tool.register_tool_execution_handler(custom_execution_handler)7. 设计建议
- 规划器只做决策,不直接执行副作用
- 执行器只做执行,不重复业务推理
- 统一用
execution_commands作为主输出协议 - 返回值尽量保留
purpose/tool_name/result/error - 让
todo_suggestion保持可读,它会影响下一轮规划