1. 主动停止的响应的消息仍然存储对话数据;2. 对话消息框当手动向上滚动的时候,停止滚动到底部,方便阅读已生成的消息;3. 消息内容,对 JSON 格式的数据,进行格式化显示;4. 支持“深度思考”按钮,可展开和折叠深度思考的消息;对 AI 的用户消息进行转义,避免不会支持的消息报错;5. 当 AI 接口调用异常的时候,给于用户提示实际的接口返回内容;6. 新增自动更新对话标题;6. 加载消息过程中,避免再次发送新消息和切换对话。
This commit is contained in:
@@ -5,9 +5,11 @@
|
|||||||
package com.jeesite.modules.cms.ai.config;
|
package com.jeesite.modules.cms.ai.config;
|
||||||
|
|
||||||
import com.jeesite.common.datasource.DataSourceHolder;
|
import com.jeesite.common.datasource.DataSourceHolder;
|
||||||
|
import com.jeesite.modules.cms.ai.properties.CmsAiProperties;
|
||||||
import com.jeesite.modules.cms.ai.tools.CmsAiTools;
|
import com.jeesite.modules.cms.ai.tools.CmsAiTools;
|
||||||
import org.springframework.ai.chat.client.ChatClient;
|
import org.springframework.ai.chat.client.ChatClient;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
@@ -18,6 +20,7 @@ import org.springframework.jdbc.core.JdbcTemplate;
|
|||||||
* @author ThinkGem
|
* @author ThinkGem
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@EnableConfigurationProperties(CmsAiProperties.class)
|
||||||
public class CmsAiChatConfig {
|
public class CmsAiChatConfig {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -25,9 +28,8 @@ public class CmsAiChatConfig {
|
|||||||
* @author ThinkGem
|
* @author ThinkGem
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public ChatClient chatClient(ChatClient.Builder builder) {
|
public ChatClient chatClient(ChatClient.Builder builder, CmsAiProperties properties) {
|
||||||
return builder
|
builder.defaultSystem("""
|
||||||
.defaultSystem("""
|
|
||||||
## 人物设定
|
## 人物设定
|
||||||
你是我的知识库AI助手,你把我当作朋友,耐心真诚地回复我提出的相关问题。
|
你是我的知识库AI助手,你把我当作朋友,耐心真诚地回复我提出的相关问题。
|
||||||
你需要遵循以下原则,与关注者进行友善而有价值的沟通。
|
你需要遵循以下原则,与关注者进行友善而有价值的沟通。
|
||||||
@@ -35,9 +37,12 @@ public class CmsAiChatConfig {
|
|||||||
1. 使用简体中文回答我的问题。
|
1. 使用简体中文回答我的问题。
|
||||||
2. 使用幽默有趣的方式与我沟通。
|
2. 使用幽默有趣的方式与我沟通。
|
||||||
3. 增加互动,如 “您的看法如何?”
|
3. 增加互动,如 “您的看法如何?”
|
||||||
""")
|
4. 可以用表情,避免过多表情。
|
||||||
.defaultTools(new CmsAiTools())
|
""");
|
||||||
.build();
|
if (properties.getToolCalls()) {
|
||||||
|
builder.defaultTools(new CmsAiTools());
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Bean
|
// @Bean
|
||||||
|
|||||||
@@ -0,0 +1,129 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||||
|
* No deletion without permission, or be held responsible to law.
|
||||||
|
*/
|
||||||
|
package com.jeesite.modules.cms.ai.config;
|
||||||
|
|
||||||
|
import com.jeesite.common.mapper.JsonMapper;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.web.reactive.function.client.WebClientCustomizer;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.io.buffer.DataBuffer;
|
||||||
|
import org.springframework.core.io.buffer.DataBufferUtils;
|
||||||
|
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.web.reactive.function.client.ClientResponse;
|
||||||
|
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
|
||||||
|
import reactor.core.publisher.Flux;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 推理模型OpenAI兼容处理
|
||||||
|
* @author ThinkGem
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class WebClientThinkConfig {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(WebClientThinkConfig.class);
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public WebClientCustomizer webClientCustomizerThink() {
|
||||||
|
return webClientBuilder -> {
|
||||||
|
ExchangeFilterFunction requestFilter = ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
|
||||||
|
logger.trace("Request url: {}: {}", clientRequest.method(), clientRequest.url());
|
||||||
|
return Mono.just(clientRequest);
|
||||||
|
});
|
||||||
|
ExchangeFilterFunction responseFilter = ExchangeFilterFunction.ofResponseProcessor(clientResponse -> {
|
||||||
|
logger.trace("Response status: {}", clientResponse.statusCode());
|
||||||
|
AtomicBoolean thinkingFlag = new AtomicBoolean(false);
|
||||||
|
Flux<DataBuffer> modifiedBody = clientResponse.bodyToFlux(DataBuffer.class)
|
||||||
|
.map(buf -> {
|
||||||
|
byte[] bytes = new byte[buf.readableByteCount()];
|
||||||
|
buf.read(bytes);
|
||||||
|
DataBufferUtils.release(buf);
|
||||||
|
return new String(bytes, StandardCharsets.UTF_8);
|
||||||
|
})
|
||||||
|
.flatMap(eventString -> {
|
||||||
|
logger.trace("Original response: ==> {}", eventString);
|
||||||
|
List<String> lines = new ArrayList<>();
|
||||||
|
String[] list = eventString.split("\\n", -1);
|
||||||
|
for (String line : list) {
|
||||||
|
if (!line.startsWith("data: ")) {
|
||||||
|
lines.add(line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String jsonPart = line.substring("data: ".length()).trim();
|
||||||
|
if (!(StringUtils.startsWith(jsonPart, "{")
|
||||||
|
&& StringUtils.endsWith(jsonPart, "}")
|
||||||
|
&& !"data: [DONE]".equals(line))) {
|
||||||
|
lines.add(line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Map<String, Object> map = JsonMapper.fromJson(jsonPart, Map.class);
|
||||||
|
if (map == null) {
|
||||||
|
lines.add(line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 修改内容字段
|
||||||
|
List<Object> choices = (List<Object>)map.get("choices");
|
||||||
|
if (choices == null) {
|
||||||
|
lines.add(line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (Object o : choices) {
|
||||||
|
Map<String, Object> choice = (Map<String, Object>) o;
|
||||||
|
if (choice == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Map<String, Object> delta = (Map<String, Object>) choice.get("delta");
|
||||||
|
if (delta == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String reasoningContent = (String) delta.get("reasoning_content");
|
||||||
|
String content = (String) delta.get("content");
|
||||||
|
if (reasoningContent != null) {
|
||||||
|
if (!thinkingFlag.get()) {
|
||||||
|
thinkingFlag.set(true);
|
||||||
|
delta.put("content", "<think>\n" + reasoningContent);
|
||||||
|
} else {
|
||||||
|
delta.put("content", reasoningContent);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (thinkingFlag.get()) {
|
||||||
|
thinkingFlag.set(false);
|
||||||
|
delta.put("content", "</think>" + (content == null ? "" : content));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 重新生成事件字符串
|
||||||
|
lines.add("data: " + JsonMapper.toJson(map));
|
||||||
|
}
|
||||||
|
String finalLine = StringUtils.join(lines, "\n");
|
||||||
|
logger.trace("Modified response: ==> {}", finalLine);
|
||||||
|
return Mono.just(finalLine);
|
||||||
|
})
|
||||||
|
.map(str -> {
|
||||||
|
byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
|
||||||
|
return new DefaultDataBufferFactory().wrap(bytes);
|
||||||
|
});
|
||||||
|
ClientResponse modifiedResponse = ClientResponse.from(clientResponse)
|
||||||
|
.headers(headers -> headers.remove(HttpHeaders.CONTENT_LENGTH))
|
||||||
|
.body(modifiedBody)
|
||||||
|
.build();
|
||||||
|
return Mono.just(modifiedResponse);
|
||||||
|
});
|
||||||
|
webClientBuilder.filter(requestFilter).filter(responseFilter);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.jeesite.modules.cms.ai.properties;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
@ConfigurationProperties("spring.ai")
|
||||||
|
public class CmsAiProperties {
|
||||||
|
|
||||||
|
private Boolean toolCalls = false;
|
||||||
|
|
||||||
|
public Boolean getToolCalls() {
|
||||||
|
return toolCalls;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToolCalls(Boolean toolCalls) {
|
||||||
|
this.toolCalls = toolCalls;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,18 +11,23 @@ import com.jeesite.common.lang.DateUtils;
|
|||||||
import com.jeesite.common.lang.StringUtils;
|
import com.jeesite.common.lang.StringUtils;
|
||||||
import com.jeesite.common.service.BaseService;
|
import com.jeesite.common.service.BaseService;
|
||||||
import com.jeesite.modules.sys.utils.UserUtils;
|
import com.jeesite.modules.sys.utils.UserUtils;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import org.springframework.ai.chat.client.ChatClient;
|
import org.springframework.ai.chat.client.ChatClient;
|
||||||
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
|
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
|
||||||
import org.springframework.ai.chat.client.advisor.QuestionAnswerAdvisor;
|
import org.springframework.ai.chat.client.advisor.vectorstore.QuestionAnswerAdvisor;
|
||||||
import org.springframework.ai.chat.memory.ChatMemory;
|
import org.springframework.ai.chat.memory.ChatMemory;
|
||||||
|
import org.springframework.ai.chat.messages.AssistantMessage;
|
||||||
import org.springframework.ai.chat.messages.Message;
|
import org.springframework.ai.chat.messages.Message;
|
||||||
import org.springframework.ai.chat.messages.UserMessage;
|
import org.springframework.ai.chat.messages.UserMessage;
|
||||||
import org.springframework.ai.chat.model.ChatResponse;
|
import org.springframework.ai.chat.model.ChatResponse;
|
||||||
|
import org.springframework.ai.chat.model.Generation;
|
||||||
import org.springframework.ai.vectorstore.SearchRequest;
|
import org.springframework.ai.vectorstore.SearchRequest;
|
||||||
import org.springframework.ai.vectorstore.VectorStore;
|
import org.springframework.ai.vectorstore.VectorStore;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.reactive.function.client.WebClientResponseException;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
|
import reactor.core.publisher.SignalType;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -35,6 +40,8 @@ import java.util.Map;
|
|||||||
public class CmsAiChatService extends BaseService {
|
public class CmsAiChatService extends BaseService {
|
||||||
|
|
||||||
private static final String CMS_CHAT_CACHE = "cmsChatCache";
|
private static final String CMS_CHAT_CACHE = "cmsChatCache";
|
||||||
|
private static final String[] USER_MESSAGE_SEARCH = new String[]{"{", "}", "$", "%"};
|
||||||
|
private static final String[] USER_MESSAGE_REPLACE = new String[]{"\\{", "\\}", "\\$", "\\%"};
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ChatClient chatClient;
|
private ChatClient chatClient;
|
||||||
@@ -102,14 +109,52 @@ public class CmsAiChatService extends BaseService {
|
|||||||
* 聊天对话,流输出
|
* 聊天对话,流输出
|
||||||
* @author ThinkGem
|
* @author ThinkGem
|
||||||
*/
|
*/
|
||||||
public Flux<ChatResponse> chatStream(String conversationId, String message) {
|
public Flux<ChatResponse> chatStream(String conversationId, String message, HttpServletRequest request) {
|
||||||
return chatClient.prompt()
|
return chatClient.prompt()
|
||||||
.messages(new UserMessage(message))
|
.messages(
|
||||||
|
new UserMessage(StringUtils.replaceEach(message, USER_MESSAGE_SEARCH, USER_MESSAGE_REPLACE))
|
||||||
|
)
|
||||||
.advisors(
|
.advisors(
|
||||||
new MessageChatMemoryAdvisor(chatMemory, conversationId, 1024),
|
new MessageChatMemoryAdvisor(chatMemory, conversationId, 1024),
|
||||||
new QuestionAnswerAdvisor(vectorStore, SearchRequest.builder().similarityThreshold(0.6F).topK(6).build()))
|
new QuestionAnswerAdvisor(vectorStore, SearchRequest.builder().similarityThreshold(0.6F).topK(6).build())
|
||||||
|
)
|
||||||
.stream()
|
.stream()
|
||||||
.chatResponse();
|
.chatResponse()
|
||||||
|
.doOnNext(response -> {
|
||||||
|
if (response.getResult() != null && StringUtils.isNotBlank(response.getResult().getOutput().getText())) {
|
||||||
|
AssistantMessage assistantMessage = (AssistantMessage)request.getAttribute("assistantMessage");
|
||||||
|
AssistantMessage currAssistantMessage = response.getResult().getOutput();
|
||||||
|
if (assistantMessage == null) {
|
||||||
|
request.setAttribute("assistantMessage", currAssistantMessage);
|
||||||
|
} else {
|
||||||
|
request.setAttribute("assistantMessage", new AssistantMessage(
|
||||||
|
assistantMessage.getText() + currAssistantMessage.getText(),
|
||||||
|
currAssistantMessage.getMetadata()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.doFinally((signalType) -> {
|
||||||
|
if (signalType != SignalType.ON_COMPLETE) {
|
||||||
|
AssistantMessage assistantMessage = (AssistantMessage)request.getAttribute("assistantMessage");
|
||||||
|
if (assistantMessage != null) {
|
||||||
|
chatMemory.add(conversationId, assistantMessage);
|
||||||
|
} else if (signalType == SignalType.CANCEL) {
|
||||||
|
chatMemory.add(conversationId, new AssistantMessage(text("暂无消息,你已主动停止响应。")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.onErrorResume(error -> {
|
||||||
|
String errorMessage = error.getMessage();
|
||||||
|
if (error instanceof WebClientResponseException webClientError) {
|
||||||
|
errorMessage = webClientError.getResponseBodyAsString();
|
||||||
|
}
|
||||||
|
AssistantMessage assistantMessage = new AssistantMessage(errorMessage);
|
||||||
|
chatMemory.add(conversationId, assistantMessage);
|
||||||
|
logger.error("Error message: {}", errorMessage);
|
||||||
|
return Flux.just(ChatResponse.builder()
|
||||||
|
.generations(List.of(new Generation(assistantMessage)))
|
||||||
|
.build());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ package com.jeesite.modules.cms.ai.web;
|
|||||||
import com.jeesite.common.config.Global;
|
import com.jeesite.common.config.Global;
|
||||||
import com.jeesite.common.web.BaseController;
|
import com.jeesite.common.web.BaseController;
|
||||||
import com.jeesite.modules.cms.ai.service.CmsAiChatService;
|
import com.jeesite.modules.cms.ai.service.CmsAiChatService;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import org.springframework.ai.chat.messages.Message;
|
import org.springframework.ai.chat.messages.Message;
|
||||||
import org.springframework.ai.chat.model.ChatResponse;
|
import org.springframework.ai.chat.model.ChatResponse;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -77,8 +78,8 @@ public class CmsAiChatController extends BaseController {
|
|||||||
* @author ThinkGem
|
* @author ThinkGem
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
@RequestMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
||||||
public Flux<ChatResponse> stream(String id, String message) {
|
public Flux<ChatResponse> stream(String id, String message, HttpServletRequest request) {
|
||||||
return cmsAiChatService.chatStream(id, message);
|
return cmsAiChatService.chatStream(id, message, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,19 +13,17 @@ spring:
|
|||||||
#api-key: ${BAILIAN_APP_KEY}
|
#api-key: ${BAILIAN_APP_KEY}
|
||||||
# 聊天对话模型
|
# 聊天对话模型
|
||||||
chat:
|
chat:
|
||||||
enabled: false
|
|
||||||
options:
|
options:
|
||||||
model: deepseek-ai/DeepSeek-R1-Distill-Qwen-7B
|
model: deepseek-ai/DeepSeek-R1-Distill-Qwen-7B
|
||||||
#model: DeepSeek-R1-Distill-Qwen-14B
|
#model: DeepSeek-R1-Distill-Qwen-14B
|
||||||
#model: deepseek-r1-distill-llama-8b
|
#model: deepseek-r1-distill-llama-8b
|
||||||
max-tokens: 1024
|
max-tokens: 1024
|
||||||
temperature: 0.6
|
temperature: 0.6
|
||||||
top-p: 0.7
|
top-p: 0.9
|
||||||
frequency-penalty: 0
|
frequency-penalty: 0
|
||||||
logprobs: true
|
#logprobs: true
|
||||||
# 向量库知识库模型(注意:不同的模型维度不同)
|
# 向量库知识库模型(注意:不同的模型维度不同)
|
||||||
embedding:
|
embedding:
|
||||||
enabled: false
|
|
||||||
options:
|
options:
|
||||||
model: BAAI/bge-m3
|
model: BAAI/bge-m3
|
||||||
#model: bge-large-zh-v1.5
|
#model: bge-large-zh-v1.5
|
||||||
@@ -33,12 +31,14 @@ spring:
|
|||||||
#model: text-embedding-v3
|
#model: text-embedding-v3
|
||||||
#dimensions: 1024
|
#dimensions: 1024
|
||||||
|
|
||||||
|
# 是否启用工具调用
|
||||||
|
tool-calls: false
|
||||||
|
|
||||||
# 本地大模型配置(使用该模型,请开启 enabled 参数)
|
# 本地大模型配置(使用该模型,请开启 enabled 参数)
|
||||||
ollama:
|
ollama:
|
||||||
base-url: http://localhost:11434
|
base-url: http://localhost:11434
|
||||||
# 聊天对话模型
|
# 聊天对话模型
|
||||||
chat:
|
chat:
|
||||||
enabled: true
|
|
||||||
options:
|
options:
|
||||||
model: qwen2.5
|
model: qwen2.5
|
||||||
#model: deepseek-r1:7b
|
#model: deepseek-r1:7b
|
||||||
@@ -48,7 +48,6 @@ spring:
|
|||||||
frequency-penalty: 0
|
frequency-penalty: 0
|
||||||
# 向量库知识库模型(注意:不同的模型维度不同)
|
# 向量库知识库模型(注意:不同的模型维度不同)
|
||||||
embedding:
|
embedding:
|
||||||
enabled: true
|
|
||||||
# 维度 dimensions 设置为 384
|
# 维度 dimensions 设置为 384
|
||||||
#model: all-minilm:33m
|
#model: all-minilm:33m
|
||||||
# 维度 dimensions 设置为 768
|
# 维度 dimensions 设置为 768
|
||||||
@@ -68,67 +67,64 @@ spring:
|
|||||||
#collection-name: vector_store
|
#collection-name: vector_store
|
||||||
collection-name: vector_store_1024
|
collection-name: vector_store_1024
|
||||||
|
|
||||||
# # Postgresql 向量数据库(PG 连接配置,见下文,需要手动建表)
|
# Postgresql 向量数据库(PG 连接配置,见下文,需要手动建表)
|
||||||
# pgvector:
|
pgvector:
|
||||||
# id-type: TEXT
|
id-type: TEXT
|
||||||
# index-type: HNSW
|
index-type: HNSW
|
||||||
# distance-type: COSINE_DISTANCE
|
distance-type: COSINE_DISTANCE
|
||||||
# initialize-schema: false
|
initialize-schema: false
|
||||||
# #table-name: vector_store_384
|
#table-name: vector_store_384
|
||||||
# #dimensions: 384
|
#dimensions: 384
|
||||||
# #table-name: vector_store_786
|
#table-name: vector_store_786
|
||||||
# #dimensions: 768
|
#dimensions: 768
|
||||||
# table-name: vector_store_1024
|
table-name: vector_store_1024
|
||||||
# dimensions: 1024
|
dimensions: 1024
|
||||||
# batching-strategy: TOKEN_COUNT
|
max-document-batch-size: 10000
|
||||||
# max-document-batch-size: 10000
|
|
||||||
|
|
||||||
# # ES 向量数据库(ES 连接配置,见下文)
|
# ES 向量数据库(ES 连接配置,见下文)
|
||||||
# elasticsearch:
|
elasticsearch:
|
||||||
# index-name: vector-index
|
index-name: vector-index
|
||||||
# initialize-schema: true
|
initialize-schema: true
|
||||||
# dimensions: 1024
|
dimensions: 1024
|
||||||
# similarity: cosine
|
similarity: cosine
|
||||||
# batching-strategy: TOKEN_COUNT
|
|
||||||
|
|
||||||
# # Milvus 向量数据库(字符串长度不超过65535)
|
# Milvus 向量数据库
|
||||||
# milvus:
|
milvus:
|
||||||
# client:
|
client:
|
||||||
# host: "localhost"
|
host: "localhost"
|
||||||
# port: 19530
|
port: 19530
|
||||||
# username: "root"
|
username: "root"
|
||||||
# password: "milvus"
|
password: "milvus"
|
||||||
# initialize-schema: true
|
initialize-schema: true
|
||||||
# database-name: "default2"
|
database-name: "default"
|
||||||
# collection-name: "vector_store2"
|
collection-name: "vector_store"
|
||||||
# embedding-dimension: 384
|
embedding-dimension: 384
|
||||||
# index-type: HNSW
|
index-type: HNSW
|
||||||
# metric-type: COSINE
|
metric-type: COSINE
|
||||||
|
|
||||||
# ========= Postgresql 向量数据库数据源 =========
|
# ========= Postgresql 向量数据库数据源 =========
|
||||||
|
|
||||||
#jdbc:
|
jdbc:
|
||||||
# ds_pgvector:
|
ds_pgvector:
|
||||||
# type: postgresql
|
type: postgresql
|
||||||
# driver: org.postgresql.Driver
|
driver: org.postgresql.Driver
|
||||||
# url: jdbc:postgresql://127.0.0.1:5433/jeesite-ai
|
url: jdbc:postgresql://127.0.0.1:5433/jeesite-ai
|
||||||
# username: postgres
|
username: postgres
|
||||||
# password: postgres
|
password: postgres
|
||||||
# testSql: SELECT 1
|
testSql: SELECT 1
|
||||||
# pool:
|
pool:
|
||||||
# init: 0
|
init: 0
|
||||||
# minIdle: 0
|
minIdle: 0
|
||||||
# breakAfterAcquireFailure: true
|
breakAfterAcquireFailure: true
|
||||||
|
|
||||||
# ========= ES 向量数据库连接配置 =========
|
# ========= ES 向量数据库连接配置 =========
|
||||||
|
|
||||||
#spring.elasticsearch:
|
spring.elasticsearch:
|
||||||
# enabled: true
|
socket-timeout: 120s
|
||||||
# socket-timeout: 120s
|
connection-timeout: 120s
|
||||||
# connection-timeout: 120s
|
uris: http://127.0.0.1:9200
|
||||||
# uris: http://127.0.0.1:9200
|
username: elastic
|
||||||
# username: elastic
|
password: elastic
|
||||||
# password: elastic
|
|
||||||
|
|
||||||
# 对话消息存缓存,可自定义存数据库
|
# 对话消息存缓存,可自定义存数据库
|
||||||
j2cache:
|
j2cache:
|
||||||
|
|||||||
Reference in New Issue
Block a user