From 8e586a8c35312e66a061e214120be08f99300da1 Mon Sep 17 00:00:00 2001 From: wanghanlin <1533525126@qq.com> Date: Sat, 27 Jun 2026 15:34:59 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B1=82=E7=A7=BB=E9=99=A4=E6=9C=AA=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E7=9A=84=20PRODUCT=5FEXTRACT=EF=BC=88=E5=95=86?= =?UTF-8?q?=E5=93=81=E4=BF=A1=E6=81=AF=E6=8A=BD=E5=8F=96=EF=BC=89=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CLAUDE.md | 5 +- DEPLOY.md | 1 - README.md | 4 +- .../wok/supportbot/app/ProductInfoApp.java | 57 ------------------- .../supportbot/config/ChatModelFactory.java | 2 +- .../supportbot/config/ModelConfigLoader.java | 1 - .../supportbot/controller/AiController.java | 17 ------ .../wok/supportbot/entity/AiModelConfig.java | 2 +- .../wok/supportbot/entity/ProductInfo.java | 14 ----- .../service/AiModelConfigService.java | 4 +- .../static/components/ModelConfigManager.js | 5 +- .../SupportBotApplicationTests.java | 32 ----------- 12 files changed, 9 insertions(+), 135 deletions(-) delete mode 100644 src/main/java/com/wok/supportbot/app/ProductInfoApp.java delete mode 100644 src/main/java/com/wok/supportbot/entity/ProductInfo.java diff --git a/CLAUDE.md b/CLAUDE.md index e7b69d1..6526432 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -39,11 +39,10 @@ AI 智能客服系统,基于 Spring AI Alibaba + 通义千问 + PGVector,支 ### Spring AI 集成模式 - **ChatClient Builder**: 所有对话通过 `ChatClient.builder(chatModelFactory.getChatModel("CHAT"))` 构建,ChatModel 由 `ChatModelFactory` 按 DB 活跃配置动态创建 - **Advisor 链**: `MessageChatMemoryAdvisor`(记忆) → `MyLoggerAdvisor`(日志) → `QuestionAnswerAdvisor`(RAG) -- **结构化输出**: `ProductInfoApp` 使用 `.entity(ProductInfo.class)` 提取结构化数据 - **SSE 流式**: 三种实现 — Flux\、Flux\、SseEmitter ### ChatMemory 持久化 -当前使用 `DatabaseChatMemory`(PostgreSQL 持久化),`FileBasedChatMemory`(Kryo 序列化)已注释掉。`ProductInfoApp` 单独使用 `InMemoryChatMemory`。 +当前使用 `DatabaseChatMemory`(PostgreSQL 持久化),`FileBasedChatMemory`(Kryo 序列化)已注释掉。 ### RAG 双模式 1. **QuestionAnswerAdvisor 模式**(生产使用): 预检索优化 + `QuestionAnswerAdvisor` @@ -69,7 +68,7 @@ AI 智能客服系统,基于 Spring AI Alibaba + 通义千问 + PGVector,支 - **数据库自动初始化**: `DatabaseInitConfig` 在启动时检查并创建 `knowledge_category`/`knowledge_document`/`ai_model_config` 等表,对已存在的 `knowledge_document` 表会自动补加 `content_hash` 列。注意 `knowledge-base.sql` 脚本为早期版本,缺少此列,实际以 `DatabaseInitConfig` 为准 ### 模型配置管理 -- **ai_model_config 表**: 存储大模型配置,支持多套配置按 App 类型(CHAT / PRODUCT_EXTRACT / EMBEDDING / RAG_REWRITE)独立管理。**所有模型参数(名称、温度、最大Token、API Key、Base URL 等)全部由此表管理,不再依赖 application.yml** +- **ai_model_config 表**: 存储大模型配置,支持多套配置按 App 类型(CHAT / EMBEDDING / RAG_REWRITE)独立管理。**所有模型参数(名称、温度、最大Token、API Key、Base URL 等)全部由此表管理,不再依赖 application.yml** - **激活互斥**: 同一 App 类型只能有一个 `is_active=true` 的配置,激活操作由 Service 层 `@Transactional` 保证 - **启动 seed**: 首次启动时使用硬编码默认值写入 DB(`qwen-turbo` / `text-embedding-v2`),用户可在前端修改。**DashScope 自动配置已禁用**(`spring.ai.dashscope.enabled=false`),api-key 可选——yml 与 DB 均未配置 api-key 不影响启动,实际调用 AI 功能前在前端「AI 大模型配置管理」页面配置即可 - **启动校验**: `ModelConfigLoader` 在应用就绪后检查 DB 中每种 App 类型是否有活跃配置,并对 DashScope 提供商比较 DB 与 yml 的 API Key 一致性 diff --git a/DEPLOY.md b/DEPLOY.md index 2a2c60a..6294164 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -459,7 +459,6 @@ tail -f /opt/support-bot/logs/startup.out | App 类型 | 用途 | 默认模型 | |----------|------|----------| | CHAT | 主对话 | qwen-turbo | -| PRODUCT_EXTRACT | 结构化数据提取 | qwen-turbo | | EMBEDDING | 知识库向量化 | text-embedding-v2 | | RAG_REWRITE | RAG 查询重写 | qwen-turbo | diff --git a/README.md b/README.md index 49b7a07..f3dc0f9 100644 --- a/README.md +++ b/README.md @@ -164,8 +164,7 @@ src/main/java/com/wok/supportbot/ │ ├── MyLoggerAdvisor.java # 日志记录顾问 │ └── ReReadingAdvisor.java # 重读机制顾问 ├── app/ # 核心应用服务 -│ ├── AssistantApp.java # 智能客服应用 -│ └── ProductInfoApp.java # 商品信息提取应用 +│ └── AssistantApp.java # 智能客服应用 ├── chatmemory/ # 聊天记忆管理 │ ├── DatabaseChatMemory.java # 数据库记忆存储 │ └── FileBasedChatMemory.java # 文件记忆存储 @@ -193,7 +192,6 @@ src/main/java/com/wok/supportbot/ │ └── MyKeywordEnricher.java # AI 关键词提取 ├── entity/ # 数据实体类 │ ├── ChatMessage.java # 聊天消息实体 -│ ├── ProductInfo.java # 商品信息实体 │ ├── KnowledgeDocument.java # 知识文档实体 │ ├── KnowledgeCategory.java # 知识分类实体 │ ├── CategoryNode.java # 分类树节点 DTO diff --git a/src/main/java/com/wok/supportbot/app/ProductInfoApp.java b/src/main/java/com/wok/supportbot/app/ProductInfoApp.java deleted file mode 100644 index 4289a95..0000000 --- a/src/main/java/com/wok/supportbot/app/ProductInfoApp.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.wok.supportbot.app; - -import com.wok.supportbot.advisor.MyLoggerAdvisor; -import com.wok.supportbot.config.ChatModelFactory; -import com.wok.supportbot.entity.ProductInfo; -import lombok.extern.slf4j.Slf4j; -import org.springframework.ai.chat.client.ChatClient; -import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor; -import org.springframework.ai.chat.memory.ChatMemory; -import org.springframework.ai.chat.memory.InMemoryChatMemoryRepository; -import org.springframework.ai.chat.memory.MessageWindowChatMemory; -import org.springframework.stereotype.Component; - -/** - * 电商商品信息抽取助手App - 支持多提供商动态切换 - */ -@Component -@Slf4j -public class ProductInfoApp { - - private final ChatModelFactory chatModelFactory; - - private static final String SYSTEM_PROMPT = "你是一名电商商品信息抽取助手," + - "请从用户提供的商品网页内容中提取标题(title)、描述(description)、价格(price)、评分(rating)、评论数(reviewCount)、品牌(brand)、分类(category)等字段。" + - "请严格按照JSON格式返回,不要带任何解释和多余内容。"; - - public ProductInfoApp(ChatModelFactory chatModelFactory) { - this.chatModelFactory = chatModelFactory; - } - - /** - * 商品信息结构化抽取 - * @param rawContent 爬取的商品网页内容 - * @return 结构化的商品信息对象 - */ - public ProductInfo extractProductInfo(String rawContent) { - ChatMemory chatMemory = MessageWindowChatMemory.builder() - .chatMemoryRepository(new InMemoryChatMemoryRepository()) - .build(); - ChatClient chatClient = ChatClient.builder(chatModelFactory.getChatModel("PRODUCT_EXTRACT")) - .defaultSystem(SYSTEM_PROMPT) - .defaultAdvisors( - MessageChatMemoryAdvisor.builder(chatMemory).build(), - new MyLoggerAdvisor() - ) - .build(); - - ProductInfo productInfo = chatClient - .prompt() - .system(SYSTEM_PROMPT) - .user(rawContent) - .call() - .entity(ProductInfo.class); - log.info("Extracted product info: {}", productInfo); - return productInfo; - } -} diff --git a/src/main/java/com/wok/supportbot/config/ChatModelFactory.java b/src/main/java/com/wok/supportbot/config/ChatModelFactory.java index a5e6323..65e5609 100644 --- a/src/main/java/com/wok/supportbot/config/ChatModelFactory.java +++ b/src/main/java/com/wok/supportbot/config/ChatModelFactory.java @@ -67,7 +67,7 @@ public class ChatModelFactory { * 按应用类型获取活跃的 ChatModel * 如果该类型无活跃配置,抛出异常(不应在缺少配置时静默回退) * - * @param appType 应用类型:CHAT / PRODUCT_EXTRACT / EMBEDDING / RAG_REWRITE + * @param appType 应用类型:CHAT / EMBEDDING / RAG_REWRITE * @return ChatModel 实例 */ public ChatModel getChatModel(String appType) { diff --git a/src/main/java/com/wok/supportbot/config/ModelConfigLoader.java b/src/main/java/com/wok/supportbot/config/ModelConfigLoader.java index 92b52ad..b857c8e 100644 --- a/src/main/java/com/wok/supportbot/config/ModelConfigLoader.java +++ b/src/main/java/com/wok/supportbot/config/ModelConfigLoader.java @@ -28,7 +28,6 @@ public class ModelConfigLoader implements ApplicationListener