| | |
| | | package com.ard.agent.service; |
| | | |
| | | import com.ard.agent.tool.KnowledgeTools; |
| | | import com.ard.agent.tool.MonitorTools; |
| | | import com.alibaba.cloud.ai.graph.RunnableConfig; |
| | | import com.alibaba.cloud.ai.graph.agent.ReactAgent; |
| | | import com.alibaba.cloud.ai.graph.exception.GraphRunnerException; |
| | | import com.ard.common.security.utils.SecurityUtils; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.ai.chat.client.ChatClient; |
| | | import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor; |
| | | import org.springframework.ai.chat.model.ChatResponse; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.ai.chat.messages.AssistantMessage; |
| | | import org.springframework.ai.content.Content; |
| | | import org.springframework.stereotype.Service; |
| | | import reactor.core.publisher.Flux; |
| | | |
| | | @Slf4j |
| | | @Service |
| | | public class AIChatService { |
| | | |
| | | @Resource |
| | | private ChatClient chatClient; |
| | | @Resource |
| | | private MonitorTools monitorTools; // 注入工具类 |
| | | @Resource |
| | | private KnowledgeTools knowledgeTools; |
| | | private static final String SYSTEM_PROMPT = """ |
| | | 你是摄像头管理助手。请严格遵守以下规则: |
| | | |
| | | 1. **工具优先原则**:当用户问题涉及摄像机的实时状态、修改操作、查询具体设备信息时, |
| | | 必须调用对应的工具(getCameraDetail/searchCameras/updateCameraInfo), |
| | | 绝对不要使用自己的记忆或上下文中的静态文本来回答。 |
| | | |
| | | 2. **知识库使用场景**:只有当用户询问操作指南、故障排查手册、产品说明等静态知识时, |
| | | 才使用知识库中的内容。 |
| | | |
| | | 3. **冲突处理**:如果知识库中提到了某类操作,但用户要求执行具体操作, |
| | | 必须以工具调用的结果为准。 |
| | | |
| | | ========== 输出格式 ========== |
| | | 使用 Markdown 格式输出: |
| | | - ## 标题 |
| | | - - 列表项 |
| | | - **加粗** 强调 |
| | | - 表格用于数据展示 |
| | | """; |
| | | @Resource(name = "unifiedAgent") |
| | | private ReactAgent unifiedAgent; |
| | | |
| | | /** |
| | | * 流式对话 |
| | | * 唯一流式聊天入口 |
| | | */ |
| | | public Flux<String> streamChat(String userMessage) { |
| | | Long userId = SecurityUtils.getUserId(); |
| | | return chatClient.prompt() |
| | | .system(SYSTEM_PROMPT) |
| | | .user(userMessage) |
| | | .advisors(advisor -> advisor.param("chat_memory_conversation_id", userId)) |
| | | .tools(monitorTools, knowledgeTools) |
| | | .stream() |
| | | .content(); |
| | | try { |
| | | return unifiedAgent.streamMessages(userMessage, runnableConfig()) |
| | | .filter(msg -> msg instanceof AssistantMessage) |
| | | .map(Content::getText) |
| | | .doOnError(error -> log.error("Agent执行出错: {}", error.getMessage())); |
| | | } catch (GraphRunnerException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 唯一同步聊天入口 |
| | | */ |
| | | public String chat(String userMessage) throws GraphRunnerException { |
| | | AssistantMessage response = unifiedAgent.call(userMessage, runnableConfig()); |
| | | return response.getText(); |
| | | } |
| | | |
| | | private RunnableConfig runnableConfig() { |
| | | return RunnableConfig.builder() |
| | | .threadId(currentThreadId()) |
| | | .build(); |
| | | } |
| | | |
| | | private String currentThreadId() { |
| | | Long userId; |
| | | try { |
| | | userId = SecurityUtils.getUserId(); |
| | | } catch (Exception e) { |
| | | userId = null; |
| | | } |
| | | return userId == null ? "anonymous" : userId.toString(); |
| | | } |
| | | } |