多工具并行与安全边界
约 490 字大约 2 分钟
布欧-Lewyon
2026-06-08
首页 › Agent Spring Boot › Function Calling
多 tool_calls 并行
当用户问「上海几点?天气如何?」,模型一次返回两个 tool_calls。AgentService 用 Mono.zip 并行执行:
List<Mono<ChatMessage>> toolResultMonos = assistantMsg.getToolCalls().stream()
.map(tc -> executeToolAndBuildMessage(tc))
.collect(Collectors.toList());
return Mono.zip(toolResultMonos, results -> {
for (Object r : results) {
messages.add((ChatMessage) r);
}
return messages;
}).flatMap(ignored -> callLLM(messages, remainingRounds - 1));比串行执行更快,尤其有外部 HTTP 时。
轮次上限
remainingRounds = 3:最多 3 次 LLM 往返。防止:
- 模型反复调同一 Tool
- 参数错误导致无限 loop
生产可配置化,并记录每轮 tool_calls 审计日志。
扩展 Tool 的三处修改(当前设计)
AgentService静态TOOLSToolService新方法executeToolAndBuildMessage的switchSYSTEM_PROMPT补充使用说明
agent-function-calling/docs/BACKEND.md 建议进阶为 Registry:
Map<String, Function<Map<String,Object>, String>> registry;减少 switch 膨胀。agent-memory / agent-rag 工具变多后更值得重构。
安全边界
| 风险 | 防护 |
|---|---|
| Prompt 注入执行危险操作 | Tool 内硬编码只读 SQL |
| 模型乱调 Tool | System Prompt + 轮次上限 |
| API Key 泄露 | 环境变量,勿写 yml 提交 Git |
| 敏感信息进日志 | 脱敏 tool 参数 |
写操作 Tool(退款、删数据)应人工确认,不要全自动。
聊天 vs Agent 双模式
前端 App.tsx 模式切换:
| 模式 | API | 体验 |
|---|---|---|
| chat | /api/chat/stream | 打字机 |
| agent | /api/agent/chat | 等待后整段显示 |
Agent 模式暂不透出 tool_calls 明细;调试可在 AgentService 打日志或扩展 JSON 返回 steps[](agent-rag 的 V2 设计见项目 docs/architecture/V2-AGENT-API-DESIGN.md)。
学习点
Mono.zip处理多 Tool 并行。remainingRounds是必备熔断。- Registry 模式是 Tool 数量增长后的重构方向。
小结
- 多 Tool 一次返回时用
Mono.zip;轮次上限防死循环。 - 安全靠 Tool 最小权限 + Prompt + 审计。
- 下一项目
agent-memory在 Tool 列表加入记忆能力,并引入userId/sessionId。
上一节:ToolService 实战
下一节:记忆模型与 Redis 结构
