构建您的智能体
工具和丰富消息
工具是您的智能体可以在轮次中间调用的服务器端助手。 访客输入内容,LLM 决定“我需要为此调用一个工具”,工具在服务器上运行, 其结果要么反馈到 LLM 的最终答案中,要么直接在小部件中作为结构化块显示 (例如“与人工联系”按钮)。
工具受智能体的 垂直能力 限制。
每个工具声明它需要哪个能力;注册表只将工具暴露给能力列表包含该 slug 的智能体。
管理员可以使用 vertical_overrides.enabled_tools 进一步缩小列表。
发货的工具
| 工具 | 所需能力 | 垂直领域 | 作用 |
|---|---|---|---|
escalate_to_human |
ticket_escalation |
help_center | 显示“与人工联系”按钮(块类型 escalation_button)和 LLM 可以合并的结果。点击触发现有的潜在客户捕获流程,以便操作员可以认领对话。 |
更多工具随着后续阶段发货 — lookup_product、
order_status、find_in_docs、book_demo 等。
每个工具都是实现 App\Services\Tools\Contracts\Tool 的单个 PHP 类。
热路径如何解析工具调用
对于启用工具的代理上的每个访客轮次,MessageStreamController 在流式传输最终答案之前运行一个小型工具解析循环:
- 从注册表的
forAgent($agent)结果构建 OpenAI 风格的tools数组。 - 调用
llm->chatWithTools(messages, tools)非流式。模型要么返回tool_calls(它想要调用一个或多个工具),要么返回content(它准备回答)。 - 如果
tool_calls:为每次调用发出tool_callSSE 事件,运行工具的execute(),将工具结果作为{role: 'tool'}消息附加到消息历史中,然后循环。 - 一旦模型返回
content(或在 3 跳之后,以先到者为准),回退到现有的streamChat路径。访客仍然获得最终答案的逐 token 流式传输,因此 TTFT 得以保留。 - 工具产生的任何
block有效负载(例如escalation_button)作为blockSSE 事件发出,供小部件内联渲染。
提供商兼容性
| 提供商 | 工具调用 | 注释 |
|---|---|---|
| OpenAI (gpt-4o-mini, gpt-4o) | Native | 通过 SDK 完全支持 OpenAI tools 数组。 |
| OpenRouter | Model-dependent | 支持工具能力的模型(Claude 3.5、Llama 3.3 70B Hermes 等)通过相同的 OpenAI 兼容表面工作。 |
| Cloudflare Workers AI | Model-dependent | Llama 3.3 70B Hermes 和其他一些模型支持函数调用。不支持工具的模型优雅降级 — 它们会忽略 tools 数组并直接返回内容,因此循环只是退出。 |
小部件渲染块
小部件在轮次期间接收 block SSE 事件,并将每个块附加到飞行中的助手消息。
resources/widget/src/ui/blocks.tsx 中的渲染器注册表将块 type 映射到 Preact 组件。
未知块类型被静默丢弃(面向未来服务器的向前兼容)。
小部件的 canRender(capability, agent) 帮助器现在在以下情况下返回 true:
- 捆绑包为该能力提供渲染器,AND
- 智能体的服务器解析的
capabilities数组选择加入。
两者都是必需的 — 小部件永远不会启用服务器未授权的能力,也永远不会尝试渲染捆绑包中没有渲染器的块。
添加新工具
- 在
app/Services/Tools/Tools/YourTool.php中实现App\Services\Tools\Contracts\Tool。选择一个唯一的name(),编写清晰的description()(LLM 使用它来决定何时调用),声明它需要的capability()slug,并定义schema()JSON。 - 在
ToolRegistry::__construct中注册工具。 - 如果您的工具的
execute()返回block有效负载,请在ui/blocks.tsx中为其提供渲染器,并将相关能力 slug 添加到capabilities.ts中的RENDERABLE集。 - 为工具添加 Pest 单元测试,并使用
FakeOpenAi::pushToolCall为端到端流程添加功能测试。
延迟考虑
工具循环在流式传输最终答案开始之前每跳增加一次非流式往返。 对于典型的“需要一个工具”的轮次,这在访客看到第一个 token 之前大约增加 +200–500 ms 的延迟。 99% 的情况(不使用工具)保持不变,因为注册表为其能力与任何注册工具不匹配的智能体返回空工具列表。
为了保持延迟可控,紧密编写工具描述,以便 LLM 仅在真正需要时才调用工具。 跳数限制(3)是一个安全网 — 编写良好的工具描述应该在 1 跳内收敛。