This commit is contained in:
Luke.Ye 2025-07-12 00:35:49 +08:00
parent 3ae551a18e
commit fec5ce0ca2
4 changed files with 34 additions and 14 deletions

View File

@ -71,6 +71,7 @@ public class LLMAppServiceImpl implements LLMAppService {
if (StrUtil.isNotEmpty(slugId)) { if (StrUtil.isNotEmpty(slugId)) {
// pin逻辑 // pin逻辑
pinnedDocs = pinDocsByKeywords(llmToken, slugId, esFilepaths, question); pinnedDocs = pinDocsByKeywords(llmToken, slugId, esFilepaths, question);
log.info("question={} , 已占用 slugId={}, pinnedDocs={}", question, slugId, JSONUtil.toJsonStr(pinnedDocs));
} else { } else {
log.info("无可用的LLM工作区(slug)降级为无pin模式: question={}, 正在回答的问题: ", question, JSONUtil.toJsonStr(workspaceSelector.getAllInUseSlugQuestions())); log.info("无可用的LLM工作区(slug)降级为无pin模式: question={}, 正在回答的问题: ", question, JSONUtil.toJsonStr(workspaceSelector.getAllInUseSlugQuestions()));
} }

View File

@ -44,14 +44,14 @@ public class DynamicConfig {
@Value("${llm.enable.auto.pin:false}") @Value("${llm.enable.auto.pin:false}")
private String enableAutoPin; private String enableAutoPin;
@Value("{llm.default.workspace.name:部门知识库}") @Value("${llm.default.workspace.name:部门知识库}")
private String llmDefaultWsName; private String llmDefaultWsName;
@Value("{llm.default.slug.id:87e14982-a821-48d8-9c6b-3557d0bb2f96}") @Value("${llm.default.slug.id:87e14982-a821-48d8-9c6b-3557d0bb2f96}")
private String llmDefaultSlugId; private String llmDefaultSlugId;
@Value("${llm.active.slug.ids: 87e14982-a821-48d8-9c6b-3557d0bb2f96,bcd9ba38-36a6-4e1d-a0a4-933a96fce665}") @Value("${llm.active.slug.ids:0fbab149-0bdb-4499-93c7-936dec40812d,bcd9ba38-36a6-4e1d-a0a4-933a96fce665}")
private String llmActiveSlugIds; private String llmSharedActiveSlugIds;
@Value("${markdown.path}") @Value("${markdown.path}")
private String mdDirectoryPath; private String mdDirectoryPath;
@ -61,7 +61,7 @@ public class DynamicConfig {
public Set<String> getLlmActiveSlugs() { public Set<String> getLlmActiveSlugs() {
// 支持逗号分号和换行分隔 // 支持逗号分号和换行分隔
return Arrays.stream(llmActiveSlugIds.split("[,;\\n]")) return Arrays.stream(llmSharedActiveSlugIds.split("[,;\\n]"))
.map(String::trim) .map(String::trim)
.filter(StrUtil::isNotBlank) .filter(StrUtil::isNotBlank)
.collect(Collectors.toSet()); .collect(Collectors.toSet());

View File

@ -60,6 +60,7 @@ public class AnythingLLMServiceImpl implements AnythingLLMService {
slug = fetchSlugByWsName(llmToken, (String) params.getOrDefault(ConstantConfig.LLM_WS_NAME_KEY, dynamicConfig.getLlmDefaultWsName())); slug = fetchSlugByWsName(llmToken, (String) params.getOrDefault(ConstantConfig.LLM_WS_NAME_KEY, dynamicConfig.getLlmDefaultWsName()));
} }
log.info("[准备开始回答问题]: question={}, slug={}", question, slug);
String url = baseUrl + "/api/workspace/" + slug + "/stream-chat"; String url = baseUrl + "/api/workspace/" + slug + "/stream-chat";
Map<String, Object> body = Map.of( Map<String, Object> body = Map.of(

View File

@ -2,31 +2,47 @@ package com.knowledge.base.infrastructure.south.llm;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.knowledge.base.infrastructure.config.DynamicConfig; import com.knowledge.base.infrastructure.config.DynamicConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Map; import java.util.*;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@Component @Component
@Slf4j
public class WorkspaceSelector { public class WorkspaceSelector {
private final Set<String> availableSlugs;
private final DynamicConfig dynamicConfig;
// slugInUse 状态只保留当前 Nacos 配置的 slug
private final Map<String, Boolean> slugInUse = new ConcurrentHashMap<>(); private final Map<String, Boolean> slugInUse = new ConcurrentHashMap<>();
// 仅为日志打印保存 slug->question释放时清理即可
private final Map<String, String> slugQuestion = new ConcurrentHashMap<>(); private final Map<String, String> slugQuestion = new ConcurrentHashMap<>();
@Autowired @Autowired
public WorkspaceSelector(DynamicConfig dynamicConfig) { public WorkspaceSelector(DynamicConfig dynamicConfig) {
this.availableSlugs = dynamicConfig.getLlmActiveSlugs(); this.dynamicConfig = dynamicConfig;
availableSlugs.forEach(slug -> slugInUse.put(slug, false)); }
/**
* 获取当前最新的slug集合
*/
private Set<String> getCurrentSlugs() {
Set<String> slugs = dynamicConfig.getLlmActiveSlugs();
// 同步slugInUse和slugQuestion仅保留现有slug
slugInUse.keySet().removeIf(slug -> !slugs.contains(slug));
slugQuestion.keySet().removeIf(slug -> !slugs.contains(slug));
// 为新slug初始化状态
for (String slug : slugs) {
slugInUse.putIfAbsent(slug, false);
}
return slugs;
} }
/** /**
* 获取一个空闲的slug返回StrUtil.EMPTY则无可用 * 获取一个空闲的slug返回StrUtil.EMPTY则无可用
* 并记录question方便日志打印
*/ */
public synchronized String acquire(String question) { public synchronized String acquire(String question) {
Set<String> availableSlugs = getCurrentSlugs();
for (String slug : availableSlugs) { for (String slug : availableSlugs) {
if (!slugInUse.getOrDefault(slug, false)) { if (!slugInUse.getOrDefault(slug, false)) {
slugInUse.put(slug, true); slugInUse.put(slug, true);
@ -39,7 +55,9 @@ public class WorkspaceSelector {
/** 释放slug同时清理question */ /** 释放slug同时清理question */
public synchronized void release(String slug) { public synchronized void release(String slug) {
Set<String> availableSlugs = getCurrentSlugs();
if (availableSlugs.contains(slug)) { if (availableSlugs.contains(slug)) {
log.info("slug is released: {}, question: {}", slug, slugQuestion.get(slug));
slugInUse.put(slug, false); slugInUse.put(slug, false);
slugQuestion.remove(slug); slugQuestion.remove(slug);
} }
@ -54,8 +72,8 @@ public class WorkspaceSelector {
* 获取当前所有已占用的slug及对应的question * 获取当前所有已占用的slug及对应的question
*/ */
public Map<String, String> getAllInUseSlugQuestions() { public Map<String, String> getAllInUseSlugQuestions() {
// 返回不可变拷贝避免外部修改内部map // 返回当前有效slug的快照
getCurrentSlugs(); // 同步最新
return new ConcurrentHashMap<>(slugQuestion); return new ConcurrentHashMap<>(slugQuestion);
} }
} }