docs: 重构文档结构,分离学习笔记和 MVP 架构设计
**变更概述:** - 将 MVP 架构设计文档独立到项目根目录 `mvp/` - 整理 `docs/` 为纯学习和分析文档目录 - 按类型分类:learning(学习)、analysis(分析)、reports(报告)、guides(指南) **目录结构:** ``` mvp/ # MVP 架构设计(独立) ├── README.md # 数据库设计总览 ├── architecture/ # 架构文档 │ ├── agent-architecture-mvp.md │ ├── implementation-plan.md │ └── ... └── tables/ # 数据表设计 docs/ # 学习和分析文档 ├── learning/ # 学习笔记(00-08 编号) ├── analysis/ # 分析笔记 + 重构计划 ├── reports/ # 临时报告 └── guides/ # 指南文档 ``` **详细变更:** - docs/README.md → mvp/README.md(数据库设计入口) - docs/architecture/ → mvp/architecture/(架构设计) - docs/tables/ → mvp/tables/(数据表设计) - docs/学习笔记-*.md → docs/learning/07-*.md, 08-*.md - docs/项目学习路径.md → docs/learning/00-*.md - docs/功能分析报告.md → docs/analysis/ - docs/修复报告-*.md → docs/reports/ - docs/日志配置*.md → docs/guides/ 或 docs/reports/ - docs/design/ → docs/analysis/(问题分析和重构计划)
This commit is contained in:
@@ -0,0 +1,576 @@
|
||||
# Tool 定义方式对比与优化建议
|
||||
|
||||
> **文档日期**: 2026-05-31
|
||||
> **参考文档**: https://java2ai.com/docs/frameworks/agent-framework/tutorials/tools
|
||||
> **项目**: SuperBizAgent-java
|
||||
|
||||
---
|
||||
|
||||
## 📋 Spring AI Agent Framework 的 6 种 Tool 定义方式
|
||||
|
||||
| 方式 | 类型 | 难度 | 类型安全 | 动态性 | 最佳场景 |
|
||||
|------|------|------|---------|--------|---------|
|
||||
| **1. @Tool 注解** | 声明式 | ⭐ | ✅ | ❌ | 静态工具、类组织 |
|
||||
| **2. MethodToolCallback** | 编程式 | ⭐⭐⭐ | ✅ | ✅ | 动态构建、反射 |
|
||||
| **3. FunctionToolCallback** | 函数式 | ⭐⭐ | ✅ | ✅ | 函数式逻辑 |
|
||||
| **4. @Bean 函数** | Spring式 | ⭐ | ❌ | ✅ | Spring 应用 |
|
||||
| **5. ToolCallback 接口** | 自定义 | ⭐⭐⭐⭐ | ✅ | ✅ | 高度定制 |
|
||||
| **6. MCP ToolCallback** | 外部进程 | ⭐⭐ | ✅ | ✅ | 外部服务 |
|
||||
|
||||
---
|
||||
|
||||
## 🔍 项目当前使用方式
|
||||
|
||||
### **方式1:@Tool 注解(主要方式)**
|
||||
|
||||
**使用位置**:
|
||||
- `DateTimeTools.java`
|
||||
- `InternalDocsTools.java`
|
||||
- `QueryMetricsTools.java`
|
||||
- `QueryLogsTools.java`
|
||||
|
||||
**代码示例**:
|
||||
```java
|
||||
@Component
|
||||
public class InternalDocsTools {
|
||||
|
||||
@Autowired
|
||||
private VectorSearchService vectorSearchService; // ← 依赖注入
|
||||
|
||||
@Value("${rag.top-k:3}")
|
||||
private int topK; // ← 配置注入
|
||||
|
||||
@Tool(description = "Use this tool to search internal documentation...")
|
||||
public String queryInternalDocs(
|
||||
@ToolParam(description = "Search query") String query) { // ← 参数注解
|
||||
|
||||
List<SearchResult> results = vectorSearchService.searchSimilarDocuments(query, topK);
|
||||
return objectMapper.writeValueAsString(results);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**注入方式**(`ChatService.java:93-101`):
|
||||
```java
|
||||
public Object[] buildMethodToolsArray() {
|
||||
if (queryLogsTools != null) {
|
||||
return new Object[]{dateTimeTools, internalDocsTools, queryMetricsTools, queryLogsTools};
|
||||
} else {
|
||||
return new Object[]{dateTimeTools, internalDocsTools, queryMetricsTools};
|
||||
}
|
||||
}
|
||||
|
||||
// 在 ReactAgent 中使用
|
||||
ReactAgent.builder()
|
||||
.methodTools(buildMethodToolsArray()) // ← 传入 @Tool 注解的对象
|
||||
.build();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **方式6:MCP ToolCallback(外部工具)**
|
||||
|
||||
**使用位置**:
|
||||
- 腾讯云 CLS 日志查询(真实模式)
|
||||
- 其他外部 MCP 服务
|
||||
|
||||
**代码示例**(`ChatService.java:106-111`):
|
||||
```java
|
||||
@Autowired(required = false)
|
||||
private ToolCallbackProvider tools; // ← MCP 工具提供者
|
||||
|
||||
public ToolCallback[] getToolCallbacks() {
|
||||
if (tools == null) {
|
||||
return new ToolCallback[0];
|
||||
}
|
||||
return tools.getToolCallbacks();
|
||||
}
|
||||
|
||||
// 在 ReactAgent 中使用
|
||||
ReactAgent.builder()
|
||||
.methodTools(buildMethodToolsArray()) // Java 工具
|
||||
.tools(getToolCallbacks()) // MCP 工具
|
||||
.build();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ 当前方式的优缺点分析
|
||||
|
||||
### **优点** ✅
|
||||
|
||||
| 优点 | 说明 |
|
||||
|------|------|
|
||||
| **代码清晰** | `@Tool` 注解一目了然,易于理解 |
|
||||
| **类型安全** | 编译时检查,减少运行时错误 |
|
||||
| **依赖注入** | 完美集成 Spring 生态(`@Autowired`, `@Value`) |
|
||||
| **易于测试** | 工具类可以独立单元测试 |
|
||||
| **配置灵活** | 通过 `@Value` 读取配置(如 `topK`, `mockEnabled`) |
|
||||
| **状态管理** | 工具类可以有成员变量(如 `httpClient`, `objectMapper`) |
|
||||
| **生命周期** | 支持 `@PostConstruct` 初始化(如 `QueryMetricsTools.init()`) |
|
||||
|
||||
---
|
||||
|
||||
### **缺点** ❌
|
||||
|
||||
| 缺点 | 影响 | 是否需要优化 |
|
||||
|------|------|------------|
|
||||
| **工具数组需要手动管理** | 每增加一个工具,需要修改 `buildMethodToolsArray()` | ⚠️ 可优化 |
|
||||
| **工具名称为常量字符串** | `TOOL_QUERY_PROMETHEUS_ALERTS` 容易拼写错误 | ⚠️ 可优化 |
|
||||
| **无法动态启用/禁用工具** | 必须在编译时确定工具列表 | ⚠️ 可优化(已有 Mock 模式) |
|
||||
| **工具发现不够智能** | 需要手动添加到数组,无法自动扫描 | ⚠️ 可优化 |
|
||||
|
||||
---
|
||||
|
||||
## 🚀 优化方案
|
||||
|
||||
### **优化1:自动扫描 @Tool 注解** ⭐⭐⭐(推荐)
|
||||
|
||||
**问题**:每次新增工具类,都需要在 `ChatService` 中手动添加。
|
||||
|
||||
**解决方案**:自动扫描所有带 `@Component` 且包含 `@Tool` 方法的 Bean。
|
||||
|
||||
```java
|
||||
@Service
|
||||
public class ChatService {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext; // ← Spring 上下文
|
||||
|
||||
/**
|
||||
* 自动扫描所有工具类
|
||||
* 无需手动维护工具列表
|
||||
*/
|
||||
public Object[] buildMethodToolsArray() {
|
||||
List<Object> tools = new ArrayList<>();
|
||||
|
||||
// 1. 获取所有 Spring Bean
|
||||
Map<String, Object> beans = applicationContext.getBeansWithAnnotation(Component.class);
|
||||
|
||||
for (Object bean : beans.values()) {
|
||||
// 2. 检查是否包含 @Tool 方法
|
||||
boolean hasTool = Arrays.stream(bean.getClass().getMethods())
|
||||
.anyMatch(m -> m.isAnnotationPresent(Tool.class));
|
||||
|
||||
if (hasTool) {
|
||||
// 3. 根据配置决定是否添加
|
||||
if (shouldIncludeTool(bean)) {
|
||||
tools.add(bean);
|
||||
logger.info("🔧 自动注册工具: {}", bean.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tools.toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否应该包含某个工具(基于配置)
|
||||
*/
|
||||
private boolean shouldIncludeTool(Object bean) {
|
||||
// 特殊处理:QueryLogsTools 只在 Mock 模式下启用
|
||||
if (bean instanceof QueryLogsTools) {
|
||||
return queryLogsTools != null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**优点**:
|
||||
- ✅ 新增工具类无需修改 `ChatService`
|
||||
- ✅ 自动发现所有工具
|
||||
- ✅ 保留配置化的启用/禁用逻辑
|
||||
|
||||
**缺点**:
|
||||
- ⚠️ 性能开销(启动时扫描一次,可接受)
|
||||
- ⚠️ 可能注册不需要的工具(需要过滤逻辑)
|
||||
|
||||
---
|
||||
|
||||
### **优化2:使用 @Bean 函数定义工具** ⭐⭐
|
||||
|
||||
**适用场景**:工具逻辑简单、无状态、偏函数式
|
||||
|
||||
**改造示例**:
|
||||
|
||||
**改造前**(当前方式):
|
||||
```java
|
||||
@Component
|
||||
public class DateTimeTools {
|
||||
@Tool(description = "Get the current date and time")
|
||||
public String getCurrentDateTime() {
|
||||
return LocalDateTime.now()...toString();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**改造后**(@Bean 函数):
|
||||
```java
|
||||
@Configuration
|
||||
public class ToolsConfiguration {
|
||||
|
||||
@Bean("getCurrentDateTime")
|
||||
@Description("Get the current date and time in the user's timezone. " +
|
||||
"IMPORTANT: Time changes constantly. Always call this tool...")
|
||||
public Supplier<String> getCurrentDateTime() {
|
||||
return () -> LocalDateTime.now()
|
||||
.atZone(LocaleContextHolder.getTimeZone().toZoneId())
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
// 使用
|
||||
ReactAgent.builder()
|
||||
.toolNames("getCurrentDateTime") // ← 直接使用工具名
|
||||
.build();
|
||||
```
|
||||
|
||||
**优点**:
|
||||
- ✅ 更简洁(适合简单工具)
|
||||
- ✅ 函数式风格
|
||||
- ✅ Spring 自动发现和注册
|
||||
|
||||
**缺点**:
|
||||
- ❌ 无法使用成员变量(`Supplier` 无状态)
|
||||
- ❌ 工具名称为字符串,非类型安全
|
||||
- ❌ 不适合需要依赖注入的复杂工具(如 `InternalDocsTools`)
|
||||
|
||||
**结论**:**不推荐全面改造**,因为项目的工具大多需要依赖注入(`VectorSearchService`、`httpClient` 等)。
|
||||
|
||||
---
|
||||
|
||||
### **优化3:工具元数据统一管理** ⭐⭐⭐
|
||||
|
||||
**问题**:工具名称定义为常量,但未被使用,容易不一致。
|
||||
|
||||
**当前代码**:
|
||||
```java
|
||||
public class QueryMetricsTools {
|
||||
/** 工具名常量,用于动态构建提示词 */
|
||||
public static final String TOOL_QUERY_PROMETHEUS_ALERTS = "queryPrometheusAlerts";
|
||||
|
||||
@Tool(description = "...")
|
||||
public String queryPrometheusAlerts() { // ← 方法名就是工具名
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**问题**:`TOOL_QUERY_PROMETHEUS_ALERTS` 从未被使用,可能会过时。
|
||||
|
||||
**优化方案**:使用 `@Tool(name = ...)` 明确指定工具名
|
||||
|
||||
```java
|
||||
public class QueryMetricsTools {
|
||||
public static final String TOOL_NAME = "queryPrometheusAlerts";
|
||||
|
||||
@Tool(
|
||||
name = TOOL_NAME, // ← 明确指定工具名(可选,默认为方法名)
|
||||
description = "Query active alerts from Prometheus..."
|
||||
)
|
||||
public String queryPrometheusAlerts() {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**或者**:移除无用的常量
|
||||
|
||||
```java
|
||||
public class QueryMetricsTools {
|
||||
// 删除未使用的常量
|
||||
// public static final String TOOL_QUERY_PROMETHEUS_ALERTS = "queryPrometheusAlerts";
|
||||
|
||||
@Tool(description = "...")
|
||||
public String queryPrometheusAlerts() { // 方法名即工具名
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **优化4:工具分组与条件注册** ⭐⭐
|
||||
|
||||
**问题**:工具启用逻辑分散在多处(`@Autowired(required = false)`, `buildMethodToolsArray()`)
|
||||
|
||||
**优化方案**:使用 `@ConditionalOnProperty` 统一管理
|
||||
|
||||
```java
|
||||
// Mock 模式的日志查询工具
|
||||
@Component
|
||||
@ConditionalOnProperty(name = "cls.mock-enabled", havingValue = "true")
|
||||
public class QueryLogsTools {
|
||||
@Tool(description = "...")
|
||||
public String queryLogs(...) {
|
||||
// Mock 实现
|
||||
}
|
||||
}
|
||||
|
||||
// 真实模式的工具由 MCP 提供,无需 Java 实现
|
||||
```
|
||||
|
||||
**优点**:
|
||||
- ✅ 配置化启用/禁用
|
||||
- ✅ 无需 `@Autowired(required = false)`
|
||||
- ✅ Spring 自动管理生命周期
|
||||
|
||||
**修改后的 `ChatService`**:
|
||||
```java
|
||||
@Service
|
||||
public class ChatService {
|
||||
|
||||
@Autowired
|
||||
private List<Object> toolBeans; // ← Spring 自动注入所有工具类
|
||||
|
||||
@Autowired(required = false)
|
||||
private ToolCallbackProvider tools;
|
||||
|
||||
public Object[] buildMethodToolsArray() {
|
||||
return toolBeans.stream()
|
||||
.filter(bean -> hasToolMethod(bean)) // 过滤出包含 @Tool 方法的 Bean
|
||||
.toArray();
|
||||
}
|
||||
|
||||
private boolean hasToolMethod(Object bean) {
|
||||
return Arrays.stream(bean.getClass().getMethods())
|
||||
.anyMatch(m -> m.isAnnotationPresent(Tool.class));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **优化5:工具返回类型结构化** ⭐⭐
|
||||
|
||||
**问题**:工具返回值都是 `String`(JSON),LLM 需要解析
|
||||
|
||||
**当前代码**:
|
||||
```java
|
||||
@Tool(description = "...")
|
||||
public String queryInternalDocs(String query) {
|
||||
List<SearchResult> results = vectorSearchService.searchSimilarDocuments(query, topK);
|
||||
return objectMapper.writeValueAsString(results); // ← 手动序列化
|
||||
}
|
||||
```
|
||||
|
||||
**优化方案**:返回结构化对象(Spring AI 自动序列化)
|
||||
|
||||
```java
|
||||
@Tool(description = "...")
|
||||
public InternalDocsResponse queryInternalDocs(String query) {
|
||||
List<SearchResult> results = vectorSearchService.searchSimilarDocuments(query, topK);
|
||||
return new InternalDocsResponse(results); // ← 返回 POJO
|
||||
}
|
||||
|
||||
@Data
|
||||
public class InternalDocsResponse {
|
||||
private List<SearchResult> results;
|
||||
private int totalCount;
|
||||
private String status;
|
||||
|
||||
public InternalDocsResponse(List<SearchResult> results) {
|
||||
this.results = results;
|
||||
this.totalCount = results.size();
|
||||
this.status = "success";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**优点**:
|
||||
- ✅ 类型安全
|
||||
- ✅ LLM 自动解析
|
||||
- ✅ 更清晰的数据结构
|
||||
|
||||
**缺点**:
|
||||
- ⚠️ 需要定义额外的 DTO 类
|
||||
- ⚠️ Spring AI 需要支持(当前版本可能只支持 `String`)
|
||||
|
||||
**验证**:查看 Spring AI 文档确认是否支持非 String 返回值。
|
||||
|
||||
---
|
||||
|
||||
## 🎯 推荐的优化优先级
|
||||
|
||||
### **短期优化(1-2周)**
|
||||
|
||||
| 优化项 | 优先级 | 难度 | 收益 |
|
||||
|--------|--------|------|------|
|
||||
| **优化3:移除未使用的工具名常量** | 🔴 高 | ⭐ 低 | 代码整洁 |
|
||||
| **优化4:使用 `@ConditionalOnProperty`** | 🔴 高 | ⭐⭐ 中 | 配置简化 |
|
||||
| **优化1:自动扫描工具类** | 🟡 中 | ⭐⭐⭐ 中 | 易扩展 |
|
||||
|
||||
---
|
||||
|
||||
### **中期优化(1个月)**
|
||||
|
||||
| 优化项 | 优先级 | 难度 | 收益 |
|
||||
|--------|--------|------|------|
|
||||
| **优化5:工具返回类型结构化** | 🟡 中 | ⭐⭐ 中 | 类型安全 |
|
||||
| **添加工具单元测试** | 🟡 中 | ⭐⭐ 中 | 质量保障 |
|
||||
| **工具性能监控** | 🟢 低 | ⭐⭐ 中 | 可观测性 |
|
||||
|
||||
---
|
||||
|
||||
### **长期优化(3个月+)**
|
||||
|
||||
| 优化项 | 优先级 | 难度 | 收益 |
|
||||
|--------|--------|------|------|
|
||||
| **优化2:部分工具改为 @Bean 函数** | 🟢 低 | ⭐⭐ 中 | 函数式风格 |
|
||||
| **实现自定义 ToolCallback(高度定制)** | 🟢 低 | ⭐⭐⭐⭐ 高 | 特殊需求 |
|
||||
|
||||
---
|
||||
|
||||
## 📊 对比表:当前方式 vs 推荐方式
|
||||
|
||||
| 维度 | 当前方式 | 推荐方式(优化后) |
|
||||
|------|---------|------------------|
|
||||
| **工具发现** | 手动添加到数组 | 自动扫描 `@Tool` 注解 |
|
||||
| **启用/禁用** | `@Autowired(required = false)` + 条件判断 | `@ConditionalOnProperty` |
|
||||
| **工具名管理** | 未使用的常量 | 方法名即工具名 |
|
||||
| **代码行数** | ~100 行 | ~50 行 |
|
||||
| **易扩展性** | ⭐⭐ | ⭐⭐⭐⭐ |
|
||||
| **维护成本** | ⭐⭐⭐ | ⭐ |
|
||||
|
||||
---
|
||||
|
||||
## 💡 最佳实践建议
|
||||
|
||||
### 1️⃣ **工具设计原则**
|
||||
|
||||
```java
|
||||
// ✅ 好的工具设计
|
||||
@Component
|
||||
public class WeatherTools {
|
||||
|
||||
@Tool(description = "Get current weather for a location. Returns temperature, humidity, and conditions.")
|
||||
public String getCurrentWeather(
|
||||
@ToolParam(description = "City name, e.g., 'Beijing', 'London'") String city) {
|
||||
|
||||
// 清晰的输入验证
|
||||
if (city == null || city.trim().isEmpty()) {
|
||||
return "{\"error\": \"City name is required\"}";
|
||||
}
|
||||
|
||||
// 结构化的返回值
|
||||
WeatherData data = weatherService.getWeather(city);
|
||||
return objectMapper.writeValueAsString(data);
|
||||
}
|
||||
}
|
||||
|
||||
// ❌ 不好的工具设计
|
||||
@Tool(description = "Get weather") // ← 描述不够详细
|
||||
public String getWeather(String c) { // ← 参数名不明确
|
||||
return weatherService.get(c); // ← 返回值不规范
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2️⃣ **工具命名规范**
|
||||
|
||||
| 规范 | 示例 | 说明 |
|
||||
|------|------|------|
|
||||
| **动词开头** | `getCurrentDateTime`, `queryInternalDocs` | 明确动作 |
|
||||
| **驼峰命名** | `queryPrometheusAlerts` | Java 规范 |
|
||||
| **避免缩写** | `queryMetrics` ✅, `queryMtr` ❌ | 可读性 |
|
||||
| **包含主语** | `queryInternalDocs` ✅, `query` ❌ | 明确查询对象 |
|
||||
|
||||
---
|
||||
|
||||
### 3️⃣ **工具描述规范**
|
||||
|
||||
```java
|
||||
// ✅ 好的描述
|
||||
@Tool(description =
|
||||
"Query active alerts from Prometheus alerting system. " +
|
||||
"Returns all currently firing alerts with labels, annotations, state, and values. " +
|
||||
"Use this when you need to check alert status, investigate conditions, or monitor system health.")
|
||||
public String queryPrometheusAlerts() { }
|
||||
|
||||
// ❌ 不好的描述
|
||||
@Tool(description = "Get alerts") // ← 太简短
|
||||
public String queryPrometheusAlerts() { }
|
||||
```
|
||||
|
||||
**描述应包含**:
|
||||
1. **What**:工具的功能
|
||||
2. **Returns**:返回值类型
|
||||
3. **When to use**:使用场景
|
||||
|
||||
---
|
||||
|
||||
### 4️⃣ **工具错误处理**
|
||||
|
||||
```java
|
||||
@Tool(description = "...")
|
||||
public String queryInternalDocs(String query) {
|
||||
try {
|
||||
// 参数验证
|
||||
if (query == null || query.trim().isEmpty()) {
|
||||
return buildErrorResponse("Query cannot be empty", "INVALID_INPUT");
|
||||
}
|
||||
|
||||
// 业务逻辑
|
||||
List<SearchResult> results = vectorSearchService.searchSimilarDocuments(query, topK);
|
||||
|
||||
// 成功响应
|
||||
return buildSuccessResponse(results);
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Tool execution failed", e);
|
||||
// 返回结构化错误(而不是抛异常)
|
||||
return buildErrorResponse("Query failed", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String buildErrorResponse(String message, String details) {
|
||||
return String.format(
|
||||
"{\"status\": \"error\", \"message\": \"%s\", \"details\": \"%s\"}",
|
||||
message, details
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 参考资料
|
||||
|
||||
1. **Spring AI Alibaba Agent Framework 官方文档**
|
||||
- Tool 定义:https://java2ai.com/docs/frameworks/agent-framework/tutorials/tools
|
||||
- ReactAgent:https://java2ai.com/docs/frameworks/agent-framework/tutorials/react-agent
|
||||
|
||||
2. **Spring AI 官方文档**
|
||||
- Function Calling:https://docs.spring.io/spring-ai/reference/api/functions.html
|
||||
|
||||
3. **项目现有工具类**
|
||||
- `DateTimeTools.java` - 最简单的工具示例
|
||||
- `InternalDocsTools.java` - 依赖注入示例
|
||||
- `QueryMetricsTools.java` - 配置注入 + 状态管理示例
|
||||
|
||||
---
|
||||
|
||||
## ✅ 总结
|
||||
|
||||
### 当前方式:**@Tool 注解 + 手动注册** ✅
|
||||
|
||||
**评价**:**已经是很好的选择**,适合当前项目规模和复杂度。
|
||||
|
||||
**理由**:
|
||||
1. ✅ 工具需要依赖注入(`VectorSearchService`, `httpClient` 等)
|
||||
2. ✅ 工具需要配置注入(`@Value`)
|
||||
3. ✅ 工具需要生命周期管理(`@PostConstruct`)
|
||||
4. ✅ 工具逻辑组织在类中,易于维护
|
||||
|
||||
---
|
||||
|
||||
### 推荐的改进方向:
|
||||
|
||||
1. **短期**:移除未使用的常量,使用 `@ConditionalOnProperty`
|
||||
2. **中期**:自动扫描工具类,减少手动维护
|
||||
3. **长期**:根据实际需求考虑函数式改造或自定义 ToolCallback
|
||||
|
||||
---
|
||||
|
||||
**结论**:**保持当前的 @Tool 注解方式**,逐步应用上述优化,而不是全面重构。
|
||||
Reference in New Issue
Block a user