From 80a6d9236ade191a5de0975abe4de5a6e7e63915 Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期四, 19 三月 2026 14:03:10 +0800
Subject: [PATCH] #AI.注释

---
 rsf-server/src/main/java/com/vincent/rsf/server/ai/tool/BuiltinToolGovernanceSupport.java        |   16 +++
 rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/McpMountRuntimeFactoryImpl.java  |   16 +++
 rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiConfigResolverServiceImpl.java |    5 +
 rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiChatMemoryServiceImpl.java     |   34 ++++++
 rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/BuiltinMcpToolRegistryImpl.java  |   24 ++++
 rsf-server/src/main/java/com/vincent/rsf/server/ai/tool/RsfWmsStockTools.java                    |    8 +
 rsf-server/src/main/java/com/vincent/rsf/server/ai/tool/RsfWmsBaseTools.java                     |   12 ++
 rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiParamValidationSupport.java    |   15 +++
 rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiMcpMountServiceImpl.java       |   21 ++++
 rsf-server/src/main/java/com/vincent/rsf/server/ai/tool/RsfWmsTaskTools.java                     |    9 +
 rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiChatServiceImpl.java           |   41 ++++++++
 rsf-server/src/main/java/com/vincent/rsf/server/ai/controller/AiChatController.java              |   31 ++++++
 rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiPromptRenderSupport.java       |   16 +++
 13 files changed, 248 insertions(+), 0 deletions(-)

diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/ai/controller/AiChatController.java b/rsf-server/src/main/java/com/vincent/rsf/server/ai/controller/AiChatController.java
index 613d629..b096123 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/ai/controller/AiChatController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/ai/controller/AiChatController.java
@@ -23,6 +23,11 @@
 
     private final AiChatService aiChatService;
 
+    /**
+     * 杩斿洖褰撳墠鐢ㄦ埛鍦ㄦ寚瀹� Prompt 鍦烘櫙涓嬬殑 AI 杩愯鏃跺揩鐓с��
+     * 杩欓噷涓嶄細鐪熸瑙﹀彂妯″瀷璋冪敤锛屽彧璐熻矗鎶婂綋鍓嶇敓鏁堢殑妯″瀷銆丳rompt銆�
+     * 宸叉寕杞� MCP 浠ュ強浼氳瘽璁板繂姒傚喌涓�娆℃�ц繑鍥炵粰鍓嶇鎶藉眽鍒濆鍖栦娇鐢ㄣ��
+     */
     @PreAuthorize("isAuthenticated()")
     @GetMapping("/ai/chat/runtime")
     public R runtime(@RequestParam(required = false) String promptCode,
@@ -30,6 +35,10 @@
         return R.ok().add(aiChatService.getRuntime(promptCode, sessionId, getLoginUserId(), getTenantId()));
     }
 
+    /**
+     * 鏌ヨ褰撳墠鐧诲綍鐢ㄦ埛鍦ㄦ寚瀹� Prompt 涓嬬殑鍘嗗彶浼氳瘽鍒楄〃銆�
+     * 鍓嶇宸︿晶浼氳瘽鏍忎緷璧栬鎺ュ彛鍋氫細璇濆垏鎹€�佹悳绱㈠拰鍒锋柊銆�
+     */
     @PreAuthorize("isAuthenticated()")
     @GetMapping("/ai/chat/sessions")
     public R sessions(@RequestParam(required = false) String promptCode,
@@ -37,6 +46,9 @@
         return R.ok().add(aiChatService.listSessions(promptCode, keyword, getLoginUserId(), getTenantId()));
     }
 
+    /**
+     * 杞垹闄ゅ崟涓� AI 浼氳瘽锛屽悓鏃剁骇鑱斿垹闄や細璇濅笅鐨勬秷鎭褰曘��
+     */
     @PreAuthorize("isAuthenticated()")
     @PostMapping("/ai/chat/session/remove/{sessionId}")
     public R removeSession(@PathVariable Long sessionId) {
@@ -44,18 +56,29 @@
         return R.ok("Delete Success").add(sessionId);
     }
 
+    /**
+     * 鏇存柊浼氳瘽鏍囬锛屼緵鍓嶇閲嶅懡鍚嶄細璇濇椂璋冪敤銆�
+     */
     @PreAuthorize("isAuthenticated()")
     @PostMapping("/ai/chat/session/rename/{sessionId}")
     public R renameSession(@PathVariable Long sessionId, @RequestBody AiChatSessionRenameRequest request) {
         return R.ok("Update Success").add(aiChatService.renameSession(sessionId, request, getLoginUserId(), getTenantId()));
     }
 
+    /**
+     * 鏇存柊浼氳瘽缃《鐘舵�併��
+     * 缃《鍙奖鍝嶅綋鍓嶇敤鎴风殑浼氳瘽鎺掑簭锛屼笉鏀瑰彉浼氳瘽鍐呭鍜岃蹇嗐��
+     */
     @PreAuthorize("isAuthenticated()")
     @PostMapping("/ai/chat/session/pin/{sessionId}")
     public R pinSession(@PathVariable Long sessionId, @RequestBody AiChatSessionPinRequest request) {
         return R.ok("Update Success").add(aiChatService.pinSession(sessionId, request, getLoginUserId(), getTenantId()));
     }
 
+    /**
+     * 娓呯┖鎸囧畾浼氳瘽鐨勬寔涔呭寲娑堟伅銆佹憳瑕佽蹇嗗拰浜嬪疄璁板繂銆�
+     * 浼氳瘽鏈韩淇濈暀锛屼究浜庡墠绔户缁湪鍚屼竴涓� sessionId 涓婂彂璧锋柊瀵硅瘽銆�
+     */
     @PreAuthorize("isAuthenticated()")
     @PostMapping("/ai/chat/session/memory/clear/{sessionId}")
     public R clearSessionMemory(@PathVariable Long sessionId) {
@@ -63,6 +86,9 @@
         return R.ok("Clear Success").add(sessionId);
     }
 
+    /**
+     * 鍙繚鐣欎細璇濇渶杩戜竴杞棶绛旓紝鐢ㄤ簬涓诲姩瑁佸壀涓婁笅鏂囩獥鍙c��
+     */
     @PreAuthorize("isAuthenticated()")
     @PostMapping("/ai/chat/session/memory/retain-latest/{sessionId}")
     public R retainLatestRound(@PathVariable Long sessionId) {
@@ -70,6 +96,11 @@
         return R.ok("Retain Success").add(sessionId);
     }
 
+    /**
+     * 浠� SSE 鏂瑰紡鍚姩 AI 瀵硅瘽銆�
+     * 鎺у埗鍣ㄥ彧璐熻矗鐢熸垚 requestId銆佽褰曞叆鍙f棩蹇楀拰鎶婇壌鏉冧笂涓嬫枃閫忎紶缁欐湇鍔″眰锛�
+     * 鐪熸鐨勬祦寮忔帹鐞嗐�佸伐鍏疯皟鐢ㄥ拰璁板繂钀藉簱閮藉湪鏈嶅姟灞傚畬鎴愩��
+     */
     @PreAuthorize("isAuthenticated()")
     @PostMapping(value = "/ai/chat/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
     public SseEmitter stream(@RequestBody AiChatRequest request) {
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiChatMemoryServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiChatMemoryServiceImpl.java
index 5f1c1f3..d531a27 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiChatMemoryServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiChatMemoryServiceImpl.java
@@ -30,6 +30,11 @@
     private final AiChatSessionMapper aiChatSessionMapper;
     private final AiChatMessageMapper aiChatMessageMapper;
 
+    /**
+     * 璇诲彇浼氳瘽璁板繂蹇収銆�
+     * 杩斿洖缁撴灉鍚屾椂鍖呭惈瀹屾暣钀藉簱鍘嗗彶銆佺煭鏈熻蹇嗙獥鍙d互鍙婃憳瑕�/浜嬪疄璁板繂锛�
+     * 渚夸簬璋冪敤鏂规寜涓嶅悓鐢ㄩ�旈�夋嫨鏁版嵁绮掑害銆�
+     */
     @Override
     public AiChatMemoryDto getMemory(Long userId, Long tenantId, String promptCode, Long sessionId) {
         ensureIdentity(userId, tenantId);
@@ -59,6 +64,10 @@
                 .build();
     }
 
+    /**
+     * 鏌ヨ褰撳墠鐢ㄦ埛鍦ㄦ煇涓� Prompt 涓嬬殑浼氳瘽鍒楄〃銆�
+     * 鍒楄〃鍙繑鍥炵敤浜庝晶杈规爮灞曠ず鐨勬憳瑕佷俊鎭紝涓嶈繑鍥炲畬鏁村璇濆唴瀹广��
+     */
     @Override
     public List<AiChatSessionDto> listSessions(Long userId, Long tenantId, String promptCode, String keyword) {
         ensureIdentity(userId, tenantId);
@@ -83,6 +92,10 @@
         return result;
     }
 
+    /**
+     * 瑙f瀽鏈疆璇锋眰搴旇钀藉埌鍝釜浼氳瘽銆�
+     * 濡傛灉鍓嶇甯︿簡 sessionId 鍒欏仛褰掑睘鏍¢獙骞跺鐢紱鍚﹀垯鑷姩鍒涘缓鏂颁細璇濄��
+     */
     @Override
     public AiChatSession resolveSession(Long userId, Long tenantId, String promptCode, Long sessionId, String titleSeed) {
         ensureIdentity(userId, tenantId);
@@ -108,6 +121,10 @@
         return session;
     }
 
+    /**
+     * 钀藉簱淇濆瓨涓�鏁磋疆瀵硅瘽銆�
+     * 杩欓噷浼氶『搴忓啓鍏ユ湰杞敤鎴锋秷鎭拰妯″瀷鍥炲锛屽苟鍦ㄦ渶鍚庡埛鏂颁細璇濇爣棰樸�佹渶鍚庢椿璺冩椂闂村拰璁板繂鐢诲儚銆�
+     */
     @Override
     public void saveRound(AiChatSession session, Long userId, Long tenantId, List<AiChatMessageDto> memoryMessages, String assistantContent) {
         if (session == null || session.getId() == null) {
@@ -136,6 +153,7 @@
         refreshMemoryProfile(session.getId(), userId);
     }
 
+    /** 鍒犻櫎鏁翠釜浼氳瘽鍙婂叾娑堟伅銆� */
     @Override
     public void removeSession(Long userId, Long tenantId, Long sessionId) {
         ensureIdentity(userId, tenantId);
@@ -169,6 +187,7 @@
         }
     }
 
+    /** 鏇存柊浼氳瘽鏍囬骞惰繑鍥炴渶鏂颁細璇濇憳瑕併�� */
     @Override
     public AiChatSessionDto renameSession(Long userId, Long tenantId, Long sessionId, AiChatSessionRenameRequest request) {
         ensureIdentity(userId, tenantId);
@@ -186,6 +205,7 @@
         return buildSessionDto(requireOwnedSession(sessionId, userId, tenantId));
     }
 
+    /** 鏇存柊浼氳瘽缃《鐘舵�併�� */
     @Override
     public AiChatSessionDto pinSession(Long userId, Long tenantId, Long sessionId, AiChatSessionPinRequest request) {
         ensureIdentity(userId, tenantId);
@@ -203,6 +223,7 @@
         return buildSessionDto(requireOwnedSession(sessionId, userId, tenantId));
     }
 
+    /** 娓呯┖鏌愪釜浼氳瘽鐨勫叏閮ㄦ秷鎭拰娲剧敓璁板繂瀛楁銆� */
     @Override
     public void clearSessionMemory(Long userId, Long tenantId, Long sessionId) {
         ensureIdentity(userId, tenantId);
@@ -224,6 +245,7 @@
                 .setLastMessageTime(session.getCreateTime()));
     }
 
+    /** 鍙繚鐣欐渶杩戜竴杞棶绛旓紝鐢ㄤ簬鎵嬪姩瑁佸壀闀夸細璇濄�� */
     @Override
     public void retainLatestRound(Long userId, Long tenantId, Long sessionId) {
         ensureIdentity(userId, tenantId);
@@ -307,6 +329,7 @@
     }
 
     private List<AiChatMessageDto> normalizeMessages(List<AiChatMessageDto> memoryMessages) {
+        /** 娓呮礂鍓嶇涓婁紶鐨勫唴瀛樻秷鎭紝鍙厑璁� user/assistant 涓ょ被瑙掕壊钀藉簱銆� */
         List<AiChatMessageDto> normalized = new ArrayList<>();
         if (Cools.isEmpty(memoryMessages)) {
             return normalized;
@@ -372,6 +395,10 @@
     }
 
     private String buildSessionTitle(String titleSeed) {
+        /**
+         * 鎶婇杞敤鎴烽棶棰樺帇缂╂垚閫傚悎浣滀负浼氳瘽鏍囬鐨勭煭鎽樿銆�
+         * 杩欓噷浼氬幓鎺夋崲琛屻�佽繛缁┖鐧斤紝骞朵紭鍏堝湪鑷劧璇箟鏂偣澶勬埅鏂��
+         */
         if (!StringUtils.hasText(titleSeed)) {
             throw new CoolException("AI 浼氳瘽鏍囬涓嶈兘涓虹┖");
         }
@@ -429,6 +456,10 @@
     }
 
     private void refreshMemoryProfile(Long sessionId, Long userId) {
+        /**
+         * 閲嶆柊璁$畻浼氳瘽鐨勬憳瑕佽蹇嗗拰鍏抽敭浜嬪疄銆�
+         * 杩欐槸鈥滄寔涔呭寲娑堟伅鈥濆拰鈥滄ā鍨嬩笂涓嬫枃娌荤悊鈥濅箣闂寸殑妗ユ鏂规硶銆�
+         */
         List<AiChatMessageDto> messages = listMessages(sessionId);
         List<AiChatMessageDto> shortMemoryMessages = tailMessagesByRounds(messages, AiDefaults.MEMORY_RECENT_ROUNDS);
         List<AiChatMessageDto> historyMessages = messages.size() > shortMemoryMessages.size()
@@ -454,6 +485,7 @@
     }
 
     private List<AiChatMessageDto> tailMessagesByRounds(List<AiChatMessageDto> source, int rounds) {
+        /** 鎸夆�滅敤鎴峰彂瑷�杞鈥濊鍓渶杩戞秷鎭紝鑰屼笉鏄畝鍗曟寜鏉℃暟鎴柇銆� */
         if (Cools.isEmpty(source) || rounds <= 0) {
             return List.of();
         }
@@ -492,6 +524,7 @@
     }
 
     private String buildMemorySummary(List<AiChatMessageDto> historyMessages) {
+        /** 涓鸿緝鏃╁巻鍙茬敓鎴愬彲鐩存帴鎻掑叆绯荤粺娑堟伅鐨勬枃鏈憳瑕併�� */
         StringBuilder builder = new StringBuilder("杈冩棭瀵硅瘽鎽樿:\n");
         for (AiChatMessageDto item : historyMessages) {
             if (item == null || !StringUtils.hasText(item.getContent())) {
@@ -511,6 +544,7 @@
     }
 
     private String buildMemoryFacts(List<AiChatMessageDto> messages) {
+        /** 浠庢渶杩戠敤鎴峰叧娉ㄧ偣涓彁鐐煎叧閿簨瀹烇紝浣滀负杞婚噺鎸佷箙璁板繂銆� */
         if (Cools.isEmpty(messages)) {
             return null;
         }
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiChatServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiChatServiceImpl.java
index 8a784ea..0430123 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiChatServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiChatServiceImpl.java
@@ -88,6 +88,10 @@
     @Qualifier("aiChatTaskExecutor")
     private final Executor aiChatTaskExecutor;
 
+    /**
+     * 鑾峰彇褰撳墠瀵硅瘽鎶藉眽鍒濆鍖栨墍闇�鐨勮繍琛屾椂鏁版嵁銆�
+     * 璇ユ柟娉曚笉浼氳Е鍙戞ā鍨嬭皟鐢紝鑰屾槸鎶婇厤缃В鏋愮粨鏋滃拰浼氳瘽璁板繂鑱氬悎鎴愬墠绔竴娆℃覆鏌撴墍闇�鐨勫揩鐓с��
+     */
     @Override
     public AiChatRuntimeDto getRuntime(String promptCode, Long sessionId, Long userId, Long tenantId) {
         AiResolvedConfig config = aiConfigResolverService.resolve(promptCode, tenantId);
@@ -109,6 +113,9 @@
                 .build();
     }
 
+    /**
+     * 鏌ヨ鎸囧畾 Prompt 鍦烘櫙涓嬬殑鍘嗗彶浼氳瘽鎽樿鍒楄〃銆�
+     */
     @Override
     public List<AiChatSessionDto> listSessions(String promptCode, String keyword, Long userId, Long tenantId) {
         AiResolvedConfig config = aiConfigResolverService.resolve(promptCode, tenantId);
@@ -140,6 +147,10 @@
         aiChatMemoryService.retainLatestRound(userId, tenantId, sessionId);
     }
 
+    /**
+     * 鍚姩涓�娆℃柊鐨� SSE 瀵硅瘽娴併��
+     * 鎺у埗绾跨▼绔嬪嵆杩斿洖 emitter锛岀湡姝g殑妯″瀷璋冪敤涓庡伐鍏锋墽琛屼氦缁� AI 涓撶敤绾跨▼姹犲紓姝ュ鐞嗐��
+     */
     @Override
     public SseEmitter stream(AiChatRequest request, Long userId, Long tenantId) {
         SseEmitter emitter = new SseEmitter(AiDefaults.SSE_TIMEOUT_MS);
@@ -148,6 +159,14 @@
     }
 
     private void doStream(AiChatRequest request, Long userId, Long tenantId, SseEmitter emitter) {
+        /**
+         * AI 瀵硅瘽鐨勬牳蹇冩墽琛岄摼璺細
+         * 1. 鏍¢獙韬唤鍜岃В鏋愮鎴烽厤缃�
+         * 2. 瑙f瀽鎴栧垱寤轰細璇濓紝鍔犺浇璁板繂
+         * 3. 鍔ㄦ�佹寕杞� MCP 宸ュ叿
+         * 4. 鍙戣捣妯″瀷娴佸紡/闈炴祦寮忚皟鐢�
+         * 5. 鎸佷箙鍖栨湰杞秷鎭紝杈撳嚭 SSE 浜嬩欢骞惰褰曞璁℃棩蹇�
+         */
         String requestId = request.getRequestId();
         long startedAt = System.currentTimeMillis();
         AtomicReference<Long> firstTokenAtRef = new AtomicReference<>();
@@ -302,6 +321,7 @@
     }
 
     private AiResolvedConfig resolveConfig(AiChatRequest request, Long tenantId) {
+        /** 鎶婅姹傞噷鐨� Prompt 鍦烘櫙瑙f瀽鎴愪竴浠藉彲鐩存帴鎵ц鐨� AI 閰嶇疆銆� */
         try {
             return aiConfigResolverService.resolve(request.getPromptCode(), tenantId);
         } catch (Exception e) {
@@ -311,6 +331,7 @@
     }
 
     private AiChatSession resolveSession(AiChatRequest request, Long userId, Long tenantId, String promptCode) {
+        /** 鏍规嵁 sessionId 澶嶇敤鍘嗗彶浼氳瘽锛屾垨鍦ㄩ娆℃彁闂椂鍒涘缓鏂颁細璇濄�� */
         try {
             return aiChatMemoryService.resolveSession(userId, tenantId, promptCode, request.getSessionId(), resolveTitleSeed(request.getMessages()));
         } catch (Exception e) {
@@ -320,6 +341,7 @@
     }
 
     private AiChatMemoryDto loadMemory(Long userId, Long tenantId, String promptCode, Long sessionId) {
+        /** 璇诲彇浼氳瘽鐨勭煭鏈熻蹇嗐�佹憳瑕佽蹇嗗拰浜嬪疄璁板繂锛屼緵妯″瀷缁勮涓婁笅鏂囥�� */
         try {
             return aiChatMemoryService.getMemory(userId, tenantId, promptCode, sessionId);
         } catch (Exception e) {
@@ -329,6 +351,7 @@
     }
 
     private McpMountRuntimeFactory.McpMountRuntime createRuntime(AiResolvedConfig config, Long userId) {
+        /** 鎸夐厤缃腑鐨� MCP 鎸傝浇璁板綍鏋勯�犳湰杞璇濅笓灞炵殑宸ュ叿杩愯鏃躲�� */
         try {
             return mcpMountRuntimeFactory.create(config.getMcpMounts(), userId);
         } catch (Exception e) {
@@ -471,6 +494,10 @@
 
     private OpenAiChatOptions buildChatOptions(AiParam aiParam, ToolCallback[] toolCallbacks, Long userId, Long tenantId,
                                                String requestId, Long sessionId, Map<String, Object> metadata) {
+        /**
+         * 缁勮涓�娆¤亰澶╄皟鐢ㄧ殑鍏ㄩ儴妯″瀷閫夐」鍜� Tool Context銆�
+         * Tool Context 浼氶�忎紶缁欏唴缃伐鍏峰拰澶栭儴 MCP锛屼繚璇佸伐鍏峰湪绉熸埛鍜屼細璇濊寖鍥村唴鎵ц銆�
+         */
         if (userId == null) {
             throw buildAiException("AI_AUTH_USER_MISSING", AiErrorCategory.AUTH, "OPTIONS_BUILD", "褰撳墠鐧诲綍鐢ㄦ埛涓嶅瓨鍦�", null);
         }
@@ -508,6 +535,7 @@
                                              Long sessionId, AtomicLong toolCallSequence,
                                              AtomicLong toolSuccessCount, AtomicLong toolFailureCount,
                                              Long callLogId, Long userId, Long tenantId) {
+        /** 缁欐墍鏈夊伐鍏峰洖璋冨涓婁竴灞傚彲瑙傛祴鍖呰锛岀敤浜庡疄鏃� SSE 杞ㄨ抗鍜屽璁℃棩蹇楄惤搴撱�� */
         if (Cools.isEmpty(toolCallbacks)) {
             return toolCallbacks;
         }
@@ -523,6 +551,10 @@
     }
 
     private List<Message> buildPromptMessages(AiChatMemoryDto memory, List<AiChatMessageDto> sourceMessages, AiPrompt aiPrompt, Map<String, Object> metadata) {
+        /**
+         * 缁勮鏈�缁堟彁浜ょ粰妯″瀷鐨勬秷鎭垪琛ㄣ��
+         * 椤哄簭涓婂缁堟槸锛氱郴缁� Prompt -> 鍘嗗彶鎽樿 -> 鍏抽敭浜嬪疄 -> 鏈�杩戝璇� -> 褰撳墠鐢ㄦ埛杈撳叆銆�
+         */
         if (Cools.isEmpty(sourceMessages)) {
             throw new CoolException("瀵硅瘽娑堟伅涓嶈兘涓虹┖");
         }
@@ -569,6 +601,7 @@
     }
 
     private List<AiChatMessageDto> mergeMessages(List<AiChatMessageDto> persistedMessages, List<AiChatMessageDto> memoryMessages) {
+        /** 鎶婅惤搴撳巻鍙蹭笌鏈疆鍓嶇鍐呭瓨澧為噺鍚堝苟鎴愭ā鍨嬪彲娑堣垂鐨勫畬鏁翠笂涓嬫枃銆� */
         List<AiChatMessageDto> merged = new ArrayList<>();
         if (!Cools.isEmpty(persistedMessages)) {
             merged.addAll(persistedMessages);
@@ -634,6 +667,7 @@
     }
 
     private void emitDone(SseEmitter emitter, String requestId, ChatResponseMetadata metadata, String fallbackModel, Long sessionId, long startedAt, Long firstTokenAt) {
+        /** 杈撳嚭瀵硅瘽瀹屾垚浜嬩欢锛岀粺涓�灏佽鑰楁椂銆侀鍖呭欢杩熷拰 token 鐢ㄩ噺銆� */
         Usage usage = metadata == null ? null : metadata.getUsage();
         emitStrict(emitter, "done", AiChatDoneDto.builder()
                 .requestId(requestId)
@@ -662,6 +696,7 @@
     }
 
     private void emitStrict(SseEmitter emitter, String eventName, Object payload) {
+        /** 涓ユ牸鍙戦�� SSE 浜嬩欢锛涗竴鏃﹀彂閫佸け璐ワ紝鐩存帴涓婃姏涓烘祦寮忚緭鍑哄紓甯搞�� */
         try {
             String data = objectMapper.writeValueAsString(payload);
             emitter.send(SseEmitter.event()
@@ -673,6 +708,7 @@
     }
 
     private void emitSafely(SseEmitter emitter, String eventName, Object payload) {
+        /** 灏濊瘯鍙戦�侀潪鍏抽敭浜嬩欢锛屽彂閫佸け璐ュ彧璁板綍鏃ュ織锛屼笉鎵撴柇涓诲璇濇祦绋嬨�� */
         try {
             emitStrict(emitter, eventName, payload);
         } catch (Exception e) {
@@ -748,6 +784,11 @@
 
         @Override
         public String call(String toolInput, ToolContext toolContext) {
+            /**
+             * 宸ュ叿鎵ц瑙傛祴鍖呰鍣ㄣ��
+             * 鍦ㄧ湡瀹炶皟鐢ㄥ墠鍚庡垎鍒彂閫� tool_start / tool_result / tool_error锛�
+             * 鍚屾椂鎶婅皟鐢ㄦ憳瑕佸啓鍏� MCP 璋冪敤鏃ュ織琛ㄣ��
+             */
             String toolName = delegate.getToolDefinition() == null ? "unknown" : delegate.getToolDefinition().name();
             String mountName = delegate instanceof MountedToolCallback ? ((MountedToolCallback) delegate).getMountName() : null;
             String toolCallId = requestId + "-tool-" + toolCallSequence.incrementAndGet();
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiConfigResolverServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiConfigResolverServiceImpl.java
index 991bfd2..b6087f5 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiConfigResolverServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiConfigResolverServiceImpl.java
@@ -19,6 +19,11 @@
     private final AiPromptService aiPromptService;
     private final AiMcpMountService aiMcpMountService;
 
+    /**
+     * 鎸夌鎴疯В鏋愪竴娆″畬鏁寸殑 AI 杩愯閰嶇疆銆�
+     * 璇ユ柟娉曟槸瀵硅瘽鍏ュ彛銆佽繍琛屾�佹憳瑕佸拰閰嶇疆涓績鍏辩敤鐨勭粺涓�瑙f瀽鐐癸紝
+     * 璐熻矗鎶婂綋鍓嶇敓鏁堢殑鍙傛暟銆丳rompt 鍜� MCP 鎸傝浇鑱氬悎鎴愪竴涓笉鍙啀鎷嗗垎鐨勯厤缃璞°��
+     */
     @Override
     public AiResolvedConfig resolve(String promptCode, Long tenantId) {
         if (tenantId == null) {
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiMcpMountServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiMcpMountServiceImpl.java
index e358929..f09b0fa 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiMcpMountServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiMcpMountServiceImpl.java
@@ -36,6 +36,7 @@
     private final McpMountRuntimeFactory mcpMountRuntimeFactory;
     private final ObjectMapper objectMapper;
 
+    /** 鏌ヨ鏌愪釜绉熸埛涓嬪綋鍓嶅惎鐢ㄧ殑 MCP 鎸傝浇鍒楄〃銆� */
     @Override
     public List<AiMcpMount> listActiveMounts(Long tenantId) {
         ensureTenantId(tenantId);
@@ -47,6 +48,7 @@
                 .orderByAsc(AiMcpMount::getId));
     }
 
+    /** 淇濆瓨鍓嶆牎楠� MCP 鎸傝浇鑽夌锛屽苟琛ュ叏杩愯鏃堕粯璁ゅ�笺�� */
     @Override
     public void validateBeforeSave(AiMcpMount aiMcpMount, Long tenantId) {
         ensureTenantId(tenantId);
@@ -55,6 +57,7 @@
         ensureRequiredFields(aiMcpMount, tenantId);
     }
 
+    /** 鏇存柊鍓嶆牎楠屽苟閿佸畾璁板綍鎵�灞炵鎴凤紝闃叉璺ㄧ鎴蜂慨鏀广�� */
     @Override
     public void validateBeforeUpdate(AiMcpMount aiMcpMount, Long tenantId) {
         ensureTenantId(tenantId);
@@ -67,6 +70,10 @@
         ensureRequiredFields(aiMcpMount, tenantId);
     }
 
+    /**
+     * 棰勮褰撳墠鎸傝浇鏈�缁堜細鏆撮湶缁欐ā鍨嬬殑宸ュ叿鐩綍銆�
+     * 瀵瑰唴缃� MCP 浼氶澶栧悎骞舵不鐞嗙洰褰曚俊鎭紝瀵瑰閮� MCP 鍒欎互瀹為檯瑙f瀽缁撴灉涓哄噯銆�
+     */
     @Override
     public List<AiMcpToolPreviewDto> previewTools(Long mountId, Long userId, Long tenantId) {
         AiMcpMount mount = requireMount(mountId, tenantId);
@@ -93,6 +100,7 @@
         }
     }
 
+    /** 瀵瑰凡淇濆瓨鐨勬寕杞藉仛鐪熷疄杩為�氭�ф祴璇曪紝骞舵妸缁撴灉鍥炲啓鍒拌繍琛屾�佸瓧娈点�� */
     @Override
     public AiMcpConnectivityTestDto testConnectivity(Long mountId, Long userId, Long tenantId) {
         AiMcpMount mount = requireMount(mountId, tenantId);
@@ -120,6 +128,7 @@
         }
     }
 
+    /** 瀵硅〃鍗曢噷鐨勮崏绋块厤缃仛涓存椂杩為�氭�ф祴璇曪紝涓嶈惤搴撱�� */
     @Override
     public AiMcpConnectivityTestDto testDraftConnectivity(AiMcpMount mount, Long userId, Long tenantId) {
         ensureTenantId(tenantId);
@@ -162,6 +171,10 @@
         }
     }
 
+    /**
+     * 鐩存帴鎵ц鏌愪竴涓伐鍏风殑娴嬭瘯璋冪敤銆�
+     * 璇ユ柟娉曚富瑕佹湇鍔′簬绠$悊绔殑鈥滃伐鍏锋祴璇曗�濋潰鏉匡紝涓嶅弬涓庢寮忓璇濋摼璺��
+     */
     @Override
     public AiMcpToolTestDto testTool(Long mountId, Long userId, Long tenantId, AiMcpToolTestRequest request) {
         if (userId == null) {
@@ -215,6 +228,7 @@
     }
 
     private void fillDefaults(AiMcpMount aiMcpMount) {
+        /** 涓烘寕杞借崏绋胯ˉ榻愮粺涓�榛樿鍊硷紝淇濊瘉鍚庣画杩愯鏃朵唬鐮佷笉闇�瑕侀噸澶嶅垽鏂┖鍊笺�� */
         if (!StringUtils.hasText(aiMcpMount.getTransportType())) {
             aiMcpMount.setTransportType(AiDefaults.MCP_TRANSPORT_SSE_HTTP);
         }
@@ -233,6 +247,10 @@
     }
 
     private void ensureRequiredFields(AiMcpMount aiMcpMount, Long tenantId) {
+        /**
+         * 鎸� transportType 鏍¢獙鎸傝浇蹇呭~椤广��
+         * 杩欓噷鎶娾�滃瓧娈靛悎娉曟�р�濆拰鈥滆法璁板綍鍐茬獊鈥濅竴璧锋敹鍙o紝閬垮厤鏍¢獙閫昏緫鍒嗘暎鍦� controller 灞傘��
+         */
         if (!StringUtils.hasText(aiMcpMount.getName())) {
             throw new CoolException("MCP 鎸傝浇鍚嶇О涓嶈兘涓虹┖");
         }
@@ -257,6 +275,7 @@
     }
 
     private AiMcpMount requireMount(Long mountId, Long tenantId) {
+        /** 鎸夌鎴峰姞杞芥寕杞借褰曪紝涓嶅瓨鍦ㄧ洿鎺ユ姏閿欍�� */
         ensureTenantId(tenantId);
         if (mountId == null) {
             throw new CoolException("MCP 鎸傝浇 ID 涓嶈兘涓虹┖");
@@ -273,6 +292,7 @@
     }
 
     private void ensureBuiltinConflictFree(AiMcpMount aiMcpMount, Long tenantId) {
+        /** 鏍¢獙鍚岀鎴蜂笅鏄惁瀛樺湪涓庡綋鍓嶅唴缃紪鐮佷簰鏂ョ殑鍚敤鎸傝浇銆� */
         if (aiMcpMount.getStatus() == null || aiMcpMount.getStatus() != StatusType.ENABLE.val) {
             return;
         }
@@ -311,6 +331,7 @@
     }
 
     private List<AiMcpToolPreviewDto> buildToolPreviewDtos(ToolCallback[] callbacks, List<AiMcpToolPreviewDto> governedCatalog) {
+        /** 鎶婂簳灞� ToolCallback 鍜屾不鐞嗙洰褰曚俊鎭嫾鎴愬墠绔渶瑕佺殑缁撴瀯鍖栧伐鍏峰崱鐗囨暟鎹�� */
         List<AiMcpToolPreviewDto> tools = new ArrayList<>();
         Map<String, AiMcpToolPreviewDto> catalogMap = new java.util.LinkedHashMap<>();
         for (AiMcpToolPreviewDto item : governedCatalog) {
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiParamValidationSupport.java b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiParamValidationSupport.java
index 9312751..1d05099 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiParamValidationSupport.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiParamValidationSupport.java
@@ -35,6 +35,11 @@
     private final GenericApplicationContext applicationContext;
     private final ObservationRegistry observationRegistry;
 
+    /**
+     * 瀵逛竴浠� AI 鍙傛暟鑽夌鍋氱湡瀹炶繛閫氭�ф牎楠屻��
+     * 鏍¢獙鏂瑰紡涓嶆槸绠�鍗曞垽鏂瓧娈甸潪绌猴紝鑰屾槸鐩存帴鏋勯�犺亰澶╂ā鍨嬪苟鍙戣捣涓�娆℃渶灏忔帰娴嬭皟鐢紝
+     * 鐢ㄨ繑鍥炵粨鏋滃拰鑰楁椂鐢熸垚鍓嶇鍙睍绀虹殑鏍¢獙鎶ュ憡銆�
+     */
     public AiParamValidateResultDto validate(AiParam aiParam) {
         long startedAt = System.currentTimeMillis();
         try {
@@ -66,6 +71,11 @@
     }
 
     private OpenAiChatModel createChatModel(AiParam aiParam) {
+        /**
+         * 鏋勯�犱粎鐢ㄤ簬鏍¢獙鐨勮交閲忚亰澶╂ā鍨嬨��
+         * 杩欓噷娌跨敤姝e紡閾捐矾鐨� Observation 鍜� ToolCalling 渚濊禆锛�
+         * 淇濊瘉鏍¢獙缁撹涓庣湡瀹炶繍琛岀幆澧冨敖閲忎竴鑷淬��
+         */
         OpenAiApi openAiApi = buildOpenAiApi(aiParam);
         ToolCallingManager toolCallingManager = DefaultToolCallingManager.builder()
                 .observationRegistry(observationRegistry)
@@ -88,6 +98,10 @@
     }
 
     private OpenAiApi buildOpenAiApi(AiParam aiParam) {
+        /**
+         * 鏍规嵁琛ㄥ崟閲岀殑 Base URL銆丄PI Key 鍜岃秴鏃跺弬鏁版瀯閫� OpenAI 鍏煎瀹㈡埛绔��
+         * 璇ユ柟娉曡鏄惧紡鎷嗗嚭鏉ワ紝鏄负浜嗚鈥滅綉缁滆繛鎺ュ弬鏁扳�濆拰鈥滄ā鍨嬮�夐」鈥濊亴璐e垎绂汇��
+         */
         int timeoutMs = aiParam.getTimeoutMs() == null ? AiDefaults.DEFAULT_TIMEOUT_MS : aiParam.getTimeoutMs();
         SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
         requestFactory.setConnectTimeout(timeoutMs);
@@ -101,6 +115,7 @@
     }
 
     private String formatDate(Date date) {
+        /** 缁熶竴杈撳嚭缁欏墠绔殑鏍¢獙鏃堕棿鏍煎紡銆� */
         return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
     }
 }
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiPromptRenderSupport.java b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiPromptRenderSupport.java
index 0251428..3a07196 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiPromptRenderSupport.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiPromptRenderSupport.java
@@ -17,6 +17,10 @@
 
     private static final Pattern VARIABLE_PATTERN = Pattern.compile("\\{\\{?([a-zA-Z0-9_.-]+)}}?");
 
+    /**
+     * 鍚屾椂娓叉煋 System Prompt 鍜� User Prompt锛屽苟鍥炰紶鏈瑙f瀽鍒扮殑鍙橀噺娓呭崟銆�
+     * 璇ユ柟娉曠敤浜� Prompt 绠$悊椤电殑棰勮鑳藉姏锛屽府鍔╃鐞嗗憳鍦ㄤ笉鐪熸璋冪敤妯″瀷鐨勫墠鎻愪笅楠岃瘉妯℃澘缁撴灉銆�
+     */
     public AiPromptPreviewDto render(String systemPrompt, String userPromptTemplate, String input, Map<String, Object> metadata) {
         String finalInput = input == null ? "" : input;
         return AiPromptPreviewDto.builder()
@@ -26,6 +30,11 @@
                 .build();
     }
 
+    /**
+     * 鍙覆鏌撶敤鎴锋秷鎭ā鏉裤��
+     * 濡傛灉妯℃澘娌℃湁娑堣垂浠讳綍鍙橀噺锛屽垯淇濈暀妯℃澘鍘熸枃骞舵妸鐢ㄦ埛杈撳叆闄勫姞鍒版湯灏撅紝
+     * 杩欐牱鍙互鏄惧紡鏆撮湶鈥滄ā鏉挎湭鐢熸晥鈥濈殑闂锛岃�屼笉鏄潤榛樺悶鎺夎緭鍏ャ��
+     */
     public String renderUserPrompt(String userPromptTemplate, String input, Map<String, Object> metadata) {
         if (!StringUtils.hasText(userPromptTemplate)) {
             return input;
@@ -38,6 +47,7 @@
     }
 
     private String renderTemplate(String template, String input, Map<String, Object> metadata) {
+        /** 娓叉煋浠绘剰妯℃澘鐗囨锛涚┖妯℃澘淇濇寔鍘熸牱杩斿洖銆� */
         if (!StringUtils.hasText(template)) {
             return template;
         }
@@ -45,6 +55,10 @@
     }
 
     private String replaceTemplateVariables(String template, String input, Map<String, Object> metadata) {
+        /**
+         * 缁熶竴澶勭悊 `{{input}}`銆乣{input}` 浠ュ強 metadata 閲岀殑鍗犱綅鍙橀噺鏇挎崲銆�
+         * 杩欓噷浣跨敤鏈寸礌鏇挎崲鑰屼笉鏄剼鏈墽琛岋紝鐩殑鏄妯℃澘琛屼负绋冲畾銆佸彲棰勬湡銆佹槗鎺掓煡銆�
+         */
         String rendered = template
                 .replace("{{input}}", input)
                 .replace("{input}", input);
@@ -60,6 +74,7 @@
     }
 
     private List<String> resolveVariables(String systemPrompt, String userPromptTemplate, Map<String, Object> metadata) {
+        /** 鏀堕泦褰撳墠 Prompt 涓樉寮忓嚭鐜拌繃鐨勫彉閲忓悕锛岀敤浜庡墠绔睍绀恒�� */
         LinkedHashSet<String> variables = new LinkedHashSet<>();
         collectVariables(variables, systemPrompt);
         collectVariables(variables, userPromptTemplate);
@@ -70,6 +85,7 @@
     }
 
     private void collectVariables(LinkedHashSet<String> variables, String template) {
+        /** 鎵弿妯℃澘鏂囨湰涓殑鍗犱綅鍙橀噺骞舵寜鍑虹幇椤哄簭鍘婚噸銆� */
         if (!StringUtils.hasText(template)) {
             return;
         }
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/BuiltinMcpToolRegistryImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/BuiltinMcpToolRegistryImpl.java
index 2c4b725..398efba 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/BuiltinMcpToolRegistryImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/BuiltinMcpToolRegistryImpl.java
@@ -28,6 +28,11 @@
     private final RsfWmsTaskTools rsfWmsTaskTools;
     private final RsfWmsBaseTools rsfWmsBaseTools;
 
+    /**
+     * 鏍¢獙鍐呯疆 MCP 缂栫爜鏄惁鍚堟硶銆�
+     * 褰撳墠鐗堟湰鍙厑璁镐娇鐢ㄦ樉寮忕櫥璁板湪娉ㄥ唽琛ㄤ腑鐨勭紪鐮侊紝鏈煡缂栫爜鐩存帴鎷掔粷锛�
+     * 杩欐牱鍙互纭繚鈥滈〉闈㈠彲閫夐」鈥濆拰鈥滆繍琛屾椂鍙寕杞介」鈥濆缁堜竴鑷淬��
+     */
     @Override
     public void validateBuiltinCode(String builtinCode) {
         if (!StringUtils.hasText(builtinCode)) {
@@ -38,6 +43,10 @@
         }
     }
 
+    /**
+     * 鏍规嵁鎸傝浇璁板綍鍒涘缓鍐呯疆宸ュ叿鍥炶皟銆�
+     * 杩欓噷涓嶄細鍋氫换浣曞姩鎬佸彂鐜帮紝鎵�鏈夊伐鍏烽兘蹇呴』缁忚繃鏄惧紡娉ㄥ唽鍜屾不鐞嗙洰褰曟牎楠屽悗鎵嶈兘鏆撮湶缁欐ā鍨嬨��
+     */
     @Override
     public List<ToolCallback> createToolCallbacks(AiMcpMount mount, Long userId) {
         String builtinCode = mount.getBuiltinCode();
@@ -52,6 +61,10 @@
         throw new CoolException("涓嶆敮鎸佺殑鍐呯疆 MCP 缂栫爜: " + builtinCode);
     }
 
+    /**
+     * 杩斿洖鏌愪釜鍐呯疆缂栫爜涓嬪彲棰勮鐨勫伐鍏风洰褰曚俊鎭��
+     * 璇ョ洰褰曟瘮杩愯鏃跺洖璋冨浜嗗伐鍏风敤閫斻�佹煡璇㈣竟鐣屽拰绀轰緥鎻愰棶锛屼緵绠$悊椤靛睍绀恒��
+     */
     @Override
     public List<AiMcpToolPreviewDto> listBuiltinToolCatalog(String builtinCode) {
         validateBuiltinCode(builtinCode);
@@ -62,6 +75,11 @@
     }
 
     private List<ToolCallback> createValidatedCallbacks(Object toolBean, String builtinCode) {
+        /**
+         * 鎶� `@Tool` Bean 杞垚 Spring AI ToolCallback锛屽苟寮哄埗鏍¢獙锛�
+         * 1. 宸ュ叿鍚嶅繀椤荤鍚堝懡鍚嶈鑼�
+         * 2. 姣忎釜宸ュ叿閮藉繀椤诲嚭鐜板湪娌荤悊鐩綍閲�
+         */
         List<ToolCallback> callbacks = Arrays.asList(ToolCallbacks.from(toolBean));
         Map<String, AiMcpToolPreviewDto> catalog = catalogByBuiltinCode(builtinCode);
         for (ToolCallback callback : callbacks) {
@@ -80,10 +98,15 @@
     }
 
     private List<String> supportedBuiltinCodes() {
+        /** 褰撳墠鐗堟湰鍏佽鎸傝浇鐨勫叏閮ㄥ唴缃� MCP 缂栫爜銆� */
         return List.of(AiDefaults.MCP_BUILTIN_RSF_WMS);
     }
 
     private Map<String, AiMcpToolPreviewDto> catalogByBuiltinCode(String builtinCode) {
+        /**
+         * 鏋勯�犲唴缃伐鍏锋不鐞嗙洰褰曘��
+         * 杩欓噷鐨勭洰褰曟槸杩愯鏃舵牎楠屽拰绠$悊绔瑙堢殑鍏卞悓浜嬪疄鏉ユ簮锛屼笉鑳戒笌宸ュ叿瀹炵幇鑴辫妭銆�
+         */
         if (AiDefaults.MCP_BUILTIN_RSF_WMS.equals(builtinCode)) {
             Map<String, AiMcpToolPreviewDto> catalog = new LinkedHashMap<>();
             catalog.put("rsf_query_available_inventory", buildCatalogItem(
@@ -142,6 +165,7 @@
 
     private AiMcpToolPreviewDto buildCatalogItem(String name, String toolGroup, String toolPurpose,
                                                  String queryBoundary, List<String> exampleQuestions) {
+        /** 缁熶竴鍒涘缓宸ュ叿鐩綍鏉$洰锛岄伩鍏嶄笉鍚屽伐鍏风粍鍑虹幇瀛楁椋庢牸涓嶄竴鑷淬�� */
         return AiMcpToolPreviewDto.builder()
                 .name(name)
                 .toolGroup(toolGroup)
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/McpMountRuntimeFactoryImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/McpMountRuntimeFactoryImpl.java
index a290fd7..befeb3f 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/McpMountRuntimeFactoryImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/McpMountRuntimeFactoryImpl.java
@@ -39,6 +39,11 @@
     private final ObjectMapper objectMapper;
     private final BuiltinMcpToolRegistry builtinMcpToolRegistry;
 
+    /**
+     * 鎶婁竴缁� MCP 鎸傝浇璁板綍瑙f瀽鎴愪竴娆″璇濆彲鐩存帴浣跨敤鐨勮繍琛屾椂瀵硅薄銆�
+     * 璇ユ柟娉曠粺涓�澶勭悊鍐呯疆 MCP銆佽繙绋� SSE MCP 鍜屾湰鍦� STDIO MCP锛�
+     * 鍚屾椂鏀堕泦鎸傝浇鎴愬姛椤广�佸け璐ラ」浠ュ強鏈�缁堟毚闇茬粰妯″瀷鐨勫伐鍏峰洖璋冨垪琛ㄣ��
+     */
     @Override
     public McpMountRuntime create(List<AiMcpMount> mounts, Long userId) {
         List<McpSyncClient> clients = new ArrayList<>();
@@ -75,6 +80,7 @@
     }
 
     private List<ToolCallback> wrapMountedCallbacks(List<ToolCallback> source, String mountName) {
+        /** 涓烘瘡涓伐鍏峰洖璋冭ˉ涓婃寕杞芥潵婧愶紝渚夸簬鍚庣画瀹¤銆佽娴嬪拰鍓嶇宸ュ叿杞ㄨ抗灞曠ず銆� */
         List<ToolCallback> mountedCallbacks = new ArrayList<>();
         for (ToolCallback callback : source) {
             if (callback == null) {
@@ -86,6 +92,7 @@
     }
 
     private void ensureUniqueToolNames(List<ToolCallback> callbacks) {
+        /** 纭繚澶氭寕杞借仛鍚堝悗涓嶄細鍑虹幇鍚屽悕宸ュ叿锛屽惁鍒欐ā鍨嬩晶鏃犳硶姝g‘鍒嗚鲸宸ュ叿瀹氫箟銆� */
         LinkedHashSet<String> duplicateNames = new LinkedHashSet<>();
         LinkedHashSet<String> seenNames = new LinkedHashSet<>();
         for (ToolCallback callback : callbacks) {
@@ -106,6 +113,10 @@
     }
 
     private McpSyncClient createClient(AiMcpMount mount) {
+        /**
+         * 鎸夋寕杞介厤缃姩鎬佸垱寤� MCP Client銆�
+         * 璇ユ柟娉曞彧璐熻矗 transport 灞傚垵濮嬪寲锛屼笉璐熻矗宸ュ叿鍘婚噸鍜岄敊璇仛鍚堛��
+         */
         Duration timeout = Duration.ofMillis(mount.getRequestTimeoutMs() == null
                 ? AiDefaults.DEFAULT_TIMEOUT_MS
                 : mount.getRequestTimeoutMs());
@@ -153,6 +164,7 @@
     }
 
     private List<String> readStringList(String json) {
+        /** 瑙f瀽鎸傝浇琛ㄩ噷鐨� JSON 鏁扮粍閰嶇疆锛屼緥濡� STDIO args銆� */
         if (!StringUtils.hasText(json)) {
             return Collections.emptyList();
         }
@@ -165,6 +177,7 @@
     }
 
     private Map<String, String> readStringMap(String json) {
+        /** 瑙f瀽鎸傝浇琛ㄩ噷鐨� JSON Map 閰嶇疆锛屼緥濡� headers 鎴栫幆澧冨彉閲忋�� */
         if (!StringUtils.hasText(json)) {
             return Collections.emptyMap();
         }
@@ -184,6 +197,7 @@
         private final List<String> mountedNames;
         private final List<String> errors;
 
+        /** 杩愯鏃跺璞℃湰韬彧鍋氭暟鎹皝瑁呭拰璧勬簮閲婃斁锛屼笉寮曞叆棰濆涓氬姟閫昏緫銆� */
         private DefaultMcpMountRuntime(List<McpSyncClient> clients, ToolCallback[] callbacks, List<String> mountedNames, List<String> errors) {
             this.clients = clients;
             this.callbacks = callbacks;
@@ -213,6 +227,7 @@
 
         @Override
         public void close() {
+            /** 缁熶竴鍏抽棴鏈杩愯鏃堕噷鍒涘缓鐨勫閮� MCP Client锛岄伩鍏嶈繛鎺ユ硠婕忋�� */
             for (McpSyncClient client : clients) {
                 try {
                     client.close();
@@ -228,6 +243,7 @@
         private final ToolCallback delegate;
         private final String mountName;
 
+        /** 瑁呴グ鍣ㄤ粎琛ュ厖鎸傝浇鏉ユ簮锛屼笉鏀瑰彉搴曞眰宸ュ叿瀹氫箟鍜岃皟鐢ㄨ涓恒�� */
         private MountedToolCallbackImpl(ToolCallback delegate, String mountName) {
             this.delegate = delegate;
             this.mountName = mountName;
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/ai/tool/BuiltinToolGovernanceSupport.java b/rsf-server/src/main/java/com/vincent/rsf/server/ai/tool/BuiltinToolGovernanceSupport.java
index 06030dc..ec96b73 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/ai/tool/BuiltinToolGovernanceSupport.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/ai/tool/BuiltinToolGovernanceSupport.java
@@ -11,6 +11,10 @@
     private BuiltinToolGovernanceSupport() {
     }
 
+    /**
+     * 鎶婂伐鍏峰叆鍙傞噷鐨� limit 缁熶竴鏀舵暃鍒板畨鍏ㄨ寖鍥村唴銆�
+     * 鎵�鏈夊唴缃彧璇诲伐鍏烽兘閫氳繃璇ユ柟娉曢檺鍒惰繑鍥炶妯★紝閬垮厤妯″瀷涓�娆℃煡璇㈣繃澶氭暟鎹��
+     */
     public static int normalizeLimit(Integer limit, int defaultValue, int maxValue) {
         if (limit == null) {
             return defaultValue;
@@ -21,6 +25,10 @@
         return limit;
     }
 
+    /**
+     * 瑕佹眰澶氫釜杩囨护鏉′欢閲岃嚦灏戞湁涓�涓湁鏁堝�笺��
+     * 杩欐槸闃叉 AI 宸ュ叿琚ā鍨嬪綋鎴愨�滃叏琛ㄦ壂鎻忔帴鍙b�濅娇鐢ㄧ殑绗竴閬撲繚鎶ゃ��
+     */
     public static void requireAnyFilter(String message, String... values) {
         if (values == null || values.length == 0) {
             throw new CoolException(message);
@@ -33,6 +41,10 @@
         throw new CoolException(message);
     }
 
+    /**
+     * 娓呮礂鍗曚釜鏂囨湰鍨嬫煡璇㈠弬鏁帮紝骞堕檺鍒舵渶澶ч暱搴︺��
+     * 杩欓噷鍙仛杞婚噺娌荤悊锛屼笉鍋氭ā绯婂厹搴曟垨鑷姩绾犻敊锛岄潪娉曡緭鍏ョ洿鎺ユ嫆缁濄��
+     */
     public static String sanitizeQueryText(String value, String fieldLabel, int maxLength) {
         if (!StringUtils.hasText(value)) {
             return null;
@@ -44,6 +56,10 @@
         return normalized;
     }
 
+    /**
+     * 娓呮礂瀛楃涓叉暟缁勫瀷鍙傛暟锛屽父鐢ㄤ簬绔欑偣绫诲瀷銆佺姸鎬佸垪琛ㄧ瓑鎵归噺杩囨护鏉′欢銆�
+     * 杩斿洖缁撴灉浼氳嚜鍔ㄥ墧闄ょ┖鍊硷紝浣嗗鏋滄渶缁堜负绌轰粛鐒惰涓洪潪娉曡姹傘��
+     */
     public static List<String> sanitizeStringList(List<String> values, String fieldLabel, int maxSize, int maxItemLength) {
         if (values == null || values.isEmpty()) {
             throw new CoolException(fieldLabel + "涓嶈兘涓虹┖");
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/ai/tool/RsfWmsBaseTools.java b/rsf-server/src/main/java/com/vincent/rsf/server/ai/tool/RsfWmsBaseTools.java
index b0d2e1c..1db90ba 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/ai/tool/RsfWmsBaseTools.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/ai/tool/RsfWmsBaseTools.java
@@ -27,6 +27,10 @@
     private final BasStationService basStationService;
     private final DictDataService dictDataService;
 
+    /**
+     * 鏌ヨ浠撳簱鍩虹淇℃伅銆�
+     * 璇ュ伐鍏烽潰鍚戔�滄寜缂栫爜/鍚嶇О瀹氫綅浠撳簱鈥濈殑闂瓟鍦烘櫙锛屼笉璐熻矗鎻愪緵鍏ㄩ噺浠撳簱涓绘暟鎹鍑鸿兘鍔涖��
+     */
     @Tool(name = "rsf_query_warehouses", description = "鍙鏌ヨ宸ュ叿銆傛寜浠撳簱缂栫爜鎴栧悕绉版煡璇粨搴撳熀纭�淇℃伅銆�")
     public List<Map<String, Object>> queryWarehouses(
             @ToolParam(description = "浠撳簱缂栫爜锛屽彲閫�") String code,
@@ -61,6 +65,10 @@
         return result;
     }
 
+    /**
+     * 鏌ヨ鍩虹绔欑偣淇℃伅銆�
+     * 鏌ヨ鏉′欢鍏佽鎸夌珯鐐瑰悕绉般�佺紪鍙锋垨浣跨敤鐘舵�佺粍鍚堣繃婊わ紝杩斿洖鍊煎彧淇濈暀 AI 瀵硅瘽闇�瑕佺殑瀛楁銆�
+     */
     @Tool(name = "rsf_query_bas_stations", description = "鍙鏌ヨ宸ュ叿銆傛寜绔欑偣缂栧彿銆佺珯鐐瑰悕绉版垨浣跨敤鐘舵�佹煡璇㈠熀纭�绔欑偣銆�")
     public List<Map<String, Object>> queryBasStations(
             @ToolParam(description = "绔欑偣鍚嶇О锛屽彲閫�") String stationName,
@@ -106,6 +114,10 @@
         return result;
     }
 
+    /**
+     * 鏌ヨ瀛楀吀鏁版嵁銆�
+     * 瀛楀吀绫诲瀷缂栫爜鏄己鍒舵潯浠讹紝鐢ㄦ潵纭繚妯″瀷涓嶄細瓒婅繃涓氬姟杈圭晫鐩存帴閬嶅巻鏁村紶瀛楀吀琛ㄣ��
+     */
     @Tool(name = "rsf_query_dict_data", description = "鍙鏌ヨ宸ュ叿銆傛牴鎹瓧鍏哥被鍨嬬紪鐮佹煡璇㈠瓧鍏告暟鎹紝鍙寜鍊兼垨鏍囩杩涗竴姝ヨ繃婊ゃ��")
     public List<Map<String, Object>> queryDictData(
             @ToolParam(required = true, description = "瀛楀吀绫诲瀷缂栫爜") String dictTypeCode,
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/ai/tool/RsfWmsStockTools.java b/rsf-server/src/main/java/com/vincent/rsf/server/ai/tool/RsfWmsStockTools.java
index 7fcce30..4c09581 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/ai/tool/RsfWmsStockTools.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/ai/tool/RsfWmsStockTools.java
@@ -27,6 +27,10 @@
     private final LocItemService locItemService;
     private final DeviceSiteService deviceSiteService;
 
+    /**
+     * 鏌ヨ褰撳墠鍙敤浜庡嚭搴撶殑搴撳瓨鏄庣粏銆�
+     * 璇ュ伐鍏峰彧鍏佽鎸夌墿鏂欑紪鐮佹垨鐗╂枡鍚嶇О鍋氬畾鍚戞煡璇紝涓嶅厑璁告棤鏉′欢鎵弿搴撳瓨琛ㄣ��
+     */
     @Tool(name = "rsf_query_available_inventory", description = "鍙鏌ヨ宸ュ叿銆傛牴鎹墿鏂欑紪鐮佹垨鐗╂枡鍚嶇О鏌ヨ褰撳墠鍦ㄥ簱涓斿彲鐢ㄤ簬鍑哄簱鐨勫簱瀛樻槑缁嗐��")
     public List<Map<String, Object>> queryAvailableInventory(
             @ToolParam(description = "鐗╂枡缂栫爜锛屼紭鍏堜娇鐢�") String matnr,
@@ -72,6 +76,10 @@
         return result;
     }
 
+    /**
+     * 鏌ヨ鎸囧畾浣滀笟绫诲瀷鍙敤鐨勮澶囩珯鐐广��
+     * 杩斿洖鐨勬槸妯″瀷鏇村鏄撴秷璐圭殑鎵佸钩缁撴瀯锛岃�屼笉鏄洿鎺ユ毚闇插畬鏁村疄浣撳璞°��
+     */
     @Tool(name = "rsf_query_station_list", description = "鍙鏌ヨ宸ュ叿銆傛牴鎹綔涓氱被鍨嬪垪琛ㄦ煡璇㈠彲鐢ㄧ珯鐐癸紝杩斿洖绔欑偣缂栧彿銆佸悕绉般�佺洰鏍囦綅缃拰鐘舵�佺瓑淇℃伅銆�")
     public List<Map<String, Object>> queryStationList(
             @ToolParam(required = true, description = "浣滀笟绫诲瀷鍒楄〃") List<String> types,
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/ai/tool/RsfWmsTaskTools.java b/rsf-server/src/main/java/com/vincent/rsf/server/ai/tool/RsfWmsTaskTools.java
index 0aecbf7..377a73b 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/ai/tool/RsfWmsTaskTools.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/ai/tool/RsfWmsTaskTools.java
@@ -21,6 +21,10 @@
 
     private final TaskService taskService;
 
+    /**
+     * 鏌ヨ浠诲姟鍒楄〃銆�
+     * 鏂规硶瑕佹眰鑷冲皯甯︿竴涓繃婊ゆ潯浠讹紝閬垮厤妯″瀷鎶婁换鍔¤〃褰撲綔鍙洿鎺ラ亶鍘嗙殑鏁版嵁婧愩��
+     */
     @Tool(name = "rsf_query_task_list", description = "鍙鏌ヨ宸ュ叿銆傛寜浠诲姟鍙枫�佺姸鎬併�佷换鍔$被鍨嬨�佹簮绔欑偣銆佺洰鏍囩珯鐐圭瓑鏉′欢鏌ヨ浠诲姟鍒楄〃銆�")
     public List<Map<String, Object>> queryTaskList(
             @ToolParam(description = "浠诲姟鍙凤紝鍙ā绯婃煡璇�") String taskCode,
@@ -62,6 +66,10 @@
         return result;
     }
 
+    /**
+     * 鏌ヨ鍗曚釜浠诲姟璇︽儏銆�
+     * 涓庡垪琛ㄦ煡璇笉鍚岋紝杩欓噷鍏佽杩斿洖鏇翠赴瀵岀殑瀛楁锛屼絾浠嶇劧瑕佹眰璋冪敤鏂归�氳繃浠诲姟 ID 鎴栦换鍔″彿鍋氱簿纭畾浣嶃��
+     */
     @Tool(name = "rsf_query_task_detail", description = "鍙鏌ヨ宸ュ叿銆傛牴鎹换鍔� ID 鎴栦换鍔″彿鏌ヨ浠诲姟璇︽儏銆�")
     public Map<String, Object> queryTaskDetail(
             @ToolParam(description = "浠诲姟 ID") Long taskId,
@@ -101,6 +109,7 @@
     }
 
     private Map<String, Object> buildTaskSummary(Task task) {
+        /** 鎶婁换鍔″疄浣撴敹鏁涗负閫傚悎妯″瀷闃呰鍜屽墠绔睍绀虹殑鎽樿缁撴瀯銆� */
         Map<String, Object> item = new LinkedHashMap<>();
         item.put("id", task.getId());
         item.put("taskCode", task.getTaskCode());

--
Gitblit v1.9.1