# tool2.0 **Repository Path**: zhao-qiuling/tool2.0 ## Basic Information - **Project Name**: tool2.0 - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-19 - **Last Updated**: 2026-04-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # tool-observability-lab 一个最小学习型项目,用 `Java + Spring Boot + Spring AI` 理解三个核心概念: 1. Tool Calling 2.0 2. Dynamic Tool Discovery 3. Observability 这个项目故意不做前端、不接数据库、不做复杂 RAG、不引入 MCP。 重点不是“堆功能”,而是把一条最小但完整的工具治理链路跑通,让你学明白。 ## 1. 你要先建立的心智模型 ### 1.1 什么是 Tool Calling 2.0 如果你把它理解成“模型会调用一个函数”,那还停留在早期视角。 这个项目想教你的 Tool Calling 2.0 是: - 工具不是散落的方法,而是平台要治理的能力单元 - 每个工具都应该有名字、描述、输入 schema、领域标签、关键词 - 平台不应该默认把全部工具都暴露给模型 - 平台需要先筛候选,再做真实 tool call - 每一次 tool call 都必须可观测 也就是说,重点不只是“调没调工具”,而是: - 暴露了哪些工具 - 为什么暴露这些工具 - 模型或平台最终选了哪个 - 工具执行耗时多少 - 工具结果到底是什么 - 错误发生在哪一层 ### 1.2 Tool 和 Function Calling 的区别 可以这样理解: - `Function Calling` 更像“模型输出函数名和参数” - `Tool Calling` 更像“平台管理可调用能力” `Tool Calling` 比 `Function Calling` 多出来的不是一个新词,而是平台化能力: - schema - 描述 - discovery - 候选暴露 - 调用治理 - trace / log / metrics 在这个 demo 里,Spring AI 的 `@Tool` 让 Java 方法能被封装为工具; 但真正让它像“平台”的,是工具注册中心、discovery、统一编排和观测。 ### 1.3 什么是 Dynamic Tool Discovery 不是把所有工具一次性塞给模型,而是: 1. 先根据问题筛出少量候选工具 2. 再把候选工具交给下一阶段 3. 最终才发生真实 tool call 为什么不能一开始把所有工具全暴露: - 工具一多,提示词会膨胀 - 工具一多,模型更容易误选 - 工具一多,治理成本会急剧上升 - 工具一多,你很难知道“为什么它选了这个” 在这个项目里,discovery 虽然是关键词打分,但结构是对的: - 先筛候选 - 再缩小暴露面 - 再执行调用 这就是最小的 Dynamic Tool Discovery 雏形。 ### 1.4 什么是 Observability AI 应用里的 Observability 不是“我看到了最后答案”。 真正需要看的,是完整调用链: - 收到什么问题 - 筛出哪些候选工具 - 最终选择哪个工具 - 工具入参是什么 - 工具耗时多少 - 工具结果是什么 - 哪一层报错 如果没有可观测性,你只能看到“回答像是对的”; 但你根本不知道: - 它有没有真的调工具 - 它调的是哪个工具 - 工具结果是不是空的 - 模型是不是绕开工具直接编答案 所以,tool calling 必须可观测,而不是只看最终答案。 ## 2. 这三个概念在项目里的关系 这三个概念不是并列的,而是一条链: 1. `Dynamic Tool Discovery` 先筛出候选工具 2. `Tool Calling 2.0` 再在候选范围里执行真实调用 3. `Observability` 记录整个 discovery + calling 过程 你可以把这条链记成一句话: `先缩小暴露面,再执行工具,再完整观测` ## 3. 项目里有哪些工具 本项目内置 4 个最小工具: - `search_policy` - `search_life` - `query_employee` - `query_department` 它们故意分成不同领域: - 政策类 - 生活类 - 员工目录类 - 部门信息类 这样你能明显看到: - 不是所有问题都应该交给同一个工具 - discovery 的价值就是先把“领域范围”缩小 ## 4. 项目结构 ```text src ├─ main │ ├─ java/com/example/toolobservabilitylab │ │ ├─ config │ │ ├─ controller │ │ ├─ model │ │ ├─ service │ │ ├─ support │ │ └─ tool │ └─ resources │ ├─ application.yml │ └─ application-ollama.yml └─ test ``` 额外还有: - `scripts/compare-tool-modes.ps1` ## 5. 先看哪些类 如果你是按学习顺序看代码,建议这样看: ### 第一步:看工具本身 - [PolicyToolService.java](D:\学习企业项目\untitled4\src\main\java\com\example\toolobservabilitylab\tool\PolicyToolService.java) - [LifeToolService.java](D:\学习企业项目\untitled4\src\main\java\com\example\toolobservabilitylab\tool\LifeToolService.java) - [EmployeeToolService.java](D:\学习企业项目\untitled4\src\main\java\com\example\toolobservabilitylab\tool\EmployeeToolService.java) - [DepartmentToolService.java](D:\学习企业项目\untitled4\src\main\java\com\example\toolobservabilitylab\tool\DepartmentToolService.java) 你会看到: - Spring AI 的 `@Tool` - 每个工具各自的输入参数 - 工具真正执行的业务逻辑 ### 第二步:看工具注册中心 - [LabToolRegistry.java](D:\学习企业项目\untitled4\src\main\java\com\example\toolobservabilitylab\service\LabToolRegistry.java) 这里最重要,因为它体现了“工具治理”: - 所有工具被统一注册 - 每个工具有描述、schema、关键词、领域 - 工具不是散落在项目里,而是进入平台管理 ### 第三步:看 discovery - [ToolDiscoveryService.java](D:\学习企业项目\untitled4\src\main\java\com\example\toolobservabilitylab\service\ToolDiscoveryService.java) 这里体现了: - 为什么不是一次性把所有工具塞给模型 - 平台如何先做候选筛选 - `topK` 如何限制暴露面 ### 第四步:看统一编排 - [LabOrchestratorService.java](D:\学习企业项目\untitled4\src\main\java\com\example\toolobservabilitylab\service\LabOrchestratorService.java) 这是整个项目最关键的类。 它把链路串成: 1. 收到问题 2. discovery 3. 候选工具记录 4. 最终选择工具 5. 调用工具 6. 返回最终答案 7. 返回 trace 事件 ### 第五步:看可观测性 - [LabObservationService.java](D:\学习企业项目\untitled4\src\main\java\com\example\toolobservabilitylab\service\LabObservationService.java) - [RequestTraceContext.java](D:\学习企业项目\untitled4\src\main\java\com\example\toolobservabilitylab\support\RequestTraceContext.java) 这里体现了三层观测: - 日志 - trace 事件 - metrics ## 6. 工具注册中心是怎么做的 `LabToolRegistry` 统一维护每个工具的: - `name` - `domain` - `description` - `inputSchema` - `keywords` - `ToolCallback` 这就是“最小治理单元”。 所以这个项目不是简单地写了 4 个工具类,而是把 4 个工具纳入了统一平台治理。 ## 7. discovery 是怎么做的 `ToolDiscoveryService` 使用最简单、最容易教学的规则: - 命中工具名 - 命中关键词 - 命中描述词 然后按分数排序,取 `topK`。 为什么这里故意不用复杂向量检索: - 这个项目的学习重点不是检索算法 - 而是“先 discovery 再暴露工具”的结构 结构学会了,以后你可以把它替换成: - embedding 检索 - 向量数据库 - rerank - LLM-based tool search ## 8. 为什么这不是简单的“写几个工具类” 因为这里已经有平台侧职责了: - 有工具注册中心 - 有 discovery 阶段 - 有候选工具缩小暴露面 - 有真实 tool call - 有 trace / log / metrics - 有 schema / description / keyword / domain 这已经具备了“最小工具平台”的雏形。 差别在于: - “几个工具类”只是在写功能 - “工具平台 demo”是在学习治理链路 ## 9. 运行方式 ### 9.1 默认最小学习模式 默认配置不依赖任何大模型: - [application.yml](D:\学习企业项目\untitled4\src\main\resources\application.yml) 启动: ```powershell .\mvnw.cmd spring-boot:run ``` 如果 `8080` 被占用: ```powershell java -jar target/tool-observability-lab-0.0.1-SNAPSHOT.jar --server.port=8081 ``` ### 9.2 开启真实 LLM_TOOL_CALL 项目已经给你准备好了 Ollama profile: - [application-ollama.yml](D:\学习企业项目\untitled4\src\main\resources\application-ollama.yml) 前提: 1. 本机安装并启动 `Ollama` 2. 本机可访问 `http://localhost:11434` 3. 本机已有模型,例如 `qwen2.5:7b` 用 profile 启动: ```powershell .\mvnw.cmd spring-boot:run "-Dspring-boot.run.profiles=ollama" ``` 或者直接运行 jar: ```powershell java -jar target/tool-observability-lab-0.0.1-SNAPSHOT.jar --spring.profiles.active=ollama ``` ## 10. 如何做对比实验 ### 10.1 先看工具目录 ```powershell curl http://localhost:8080/api/lab/tools ``` 你要重点观察: - 每个工具是否有描述 - 每个工具是否有 schema - 每个工具是否有关键词 ### 10.2 先跑 RULE_ONLY ```powershell curl -X POST http://localhost:8080/api/lab/ask ^ -H "Content-Type: application/json" ^ -d "{\"question\":\"张三的电话是多少?\",\"mode\":\"RULE_ONLY\",\"topK\":2}" ``` 重点观察返回中的字段: - `candidates` - `selectedTool` - `toolArguments` - `toolResult` - `traceEvents` ### 10.3 再跑 LLM_TOOL_CALL ```powershell curl -X POST http://localhost:8080/api/lab/ask ^ -H "Content-Type: application/json" ^ -d "{\"question\":\"平台研发部负责人是谁?\",\"mode\":\"LLM_TOOL_CALL\",\"topK\":2}" ``` 重点观察: - 候选工具是不是仍然先被筛过 - 模型是不是只在候选工具里做选择 - trace 里是否能看到工具调用 ### 10.4 用脚本做对比 项目提供了实验脚本: - [compare-tool-modes.ps1](D:\学习企业项目\untitled4\scripts\compare-tool-modes.ps1) 示例: ```powershell .\scripts\compare-tool-modes.ps1 -BaseUrl http://localhost:8080 -Question "平台研发部负责人是谁?" -TopK 2 ``` 这个脚本会: 1. 先调用 `RULE_ONLY` 2. 再尝试调用 `LLM_TOOL_CALL` 3. 打印两个模式的: - selectedTool - toolArguments - toolResult - finalAnswer - traceEvents 如果 LLM 模式失败,脚本会直接提示你常见原因。 ## 11. 日志和 Observability 看哪里 ### 11.1 控制台日志 日志里你会看到这些关键阶段: - `question-received` - `candidate-tools` - `tool-selected` - `tool-call-start` - `tool-call-success` - `tool-call-error` - `final-answer` 这正对应了你要学习的完整链路。 ### 11.2 响应里的 traceEvents 这个项目故意把 trace 事件也放进响应里。 原因很简单: - 这是学习项目 - 我希望你不用接 tracing 平台,也能直接看到链路 ### 11.3 Actuator metrics 可观测性接口: - `GET /actuator/metrics` - `GET /actuator/prometheus` 你可以重点看工具调用相关指标: - `lab.tool.calls` - `lab.tool.execution.duration` - `lab.stage.duration` ## 12. RULE_ONLY 和 LLM_TOOL_CALL 分别在教你什么 ### RULE_ONLY 它教你平台链路: - discovery 是怎么做的 - 为什么先筛工具 - 参数是怎么构造的 - trace 是怎么记录的 它的价值是: - 不依赖模型 - 稳定 - 便于先学结构 ### LLM_TOOL_CALL 它教你真实模型参与后的变化: - 模型如何在候选工具中做选择 - 模型调用工具后如何整合结果 - 真实 tool call 为什么更需要 observability ## 13. 项目里你真正能学到什么 学完这个项目,你应该能建立这几个判断: 1. Tool Calling 2.0 不是“让模型多调一个函数” 2. Dynamic Tool Discovery 是工具治理的前置阶段 3. 工具一多,必须控制暴露面 4. AI 应用必须看调用链,不是只看最终答案 5. schema、description、keywords、domain 都是治理资产 6. 一个真正可用的 AI 工具系统,平台层职责比工具方法本身更重要 ## 14. 测试与验证 本项目已经补了最小集成测试: - [LabControllerIntegrationTests.java](D:\学习企业项目\untitled4\src\test\java\com\example\toolobservabilitylab\LabControllerIntegrationTests.java) 运行: ```powershell .\mvnw.cmd test ``` 打包: ```powershell .\mvnw.cmd -DskipTests package ```