feat:【ai 大模型】增加 anthropic 接入

This commit is contained in:
YunaiV 2025-08-21 23:26:20 +08:00
parent 2fbb9f8893
commit 96a743157d
7 changed files with 98 additions and 3 deletions

View File

@ -84,6 +84,11 @@
<artifactId>spring-ai-starter-model-azure-openai</artifactId>
<version>${spring-ai.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-anthropic</artifactId>
<version>${spring-ai.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-deepseek</artifactId>

View File

@ -33,6 +33,7 @@ public enum AiPlatformEnum implements ArrayValuable<String> {
OPENAI("OpenAI", "OpenAI"), // OpenAI 官方
AZURE_OPENAI("AzureOpenAI", "AzureOpenAI"), // OpenAI 微软
ANTHROPIC("Anthropic", "Anthropic"), // Anthropic Claude
OLLAMA("Ollama", "Ollama"),
STABLE_DIFFUSION("StableDiffusion", "StableDiffusion"), // Stability AI

View File

@ -67,6 +67,7 @@ import org.springframework.ai.minimax.MiniMaxChatOptions;
import org.springframework.ai.minimax.MiniMaxEmbeddingModel;
import org.springframework.ai.minimax.MiniMaxEmbeddingOptions;
import org.springframework.ai.minimax.api.MiniMaxApi;
import org.springframework.ai.model.anthropic.autoconfigure.AnthropicChatAutoConfiguration;
import org.springframework.ai.model.azure.openai.autoconfigure.AzureOpenAiChatAutoConfiguration;
import org.springframework.ai.model.azure.openai.autoconfigure.AzureOpenAiEmbeddingAutoConfiguration;
import org.springframework.ai.model.azure.openai.autoconfigure.AzureOpenAiEmbeddingProperties;
@ -93,6 +94,8 @@ import org.springframework.ai.openai.OpenAiImageModel;
import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.ai.openai.api.OpenAiImageApi;
import org.springframework.ai.openai.api.common.OpenAiApiConstants;
import org.springframework.ai.anthropic.AnthropicChatModel;
import org.springframework.ai.anthropic.api.AnthropicApi;
import org.springframework.ai.stabilityai.StabilityAiImageModel;
import org.springframework.ai.stabilityai.api.StabilityAiApi;
import org.springframework.ai.vectorstore.SimpleVectorStore;
@ -168,6 +171,8 @@ public class AiModelFactoryImpl implements AiModelFactory {
return buildOpenAiChatModel(apiKey, url);
case AZURE_OPENAI:
return buildAzureOpenAiChatModel(apiKey, url);
case ANTHROPIC:
return buildAnthropicChatModel(apiKey, url);
case OLLAMA:
return buildOllamaChatModel(url);
default:
@ -206,6 +211,8 @@ public class AiModelFactoryImpl implements AiModelFactory {
return SpringUtil.getBean(OpenAiChatModel.class);
case AZURE_OPENAI:
return SpringUtil.getBean(AzureOpenAiChatModel.class);
case ANTHROPIC:
return SpringUtil.getBean(AnthropicChatModel.class);
case OLLAMA:
return SpringUtil.getBean(OllamaChatModel.class);
default:
@ -512,6 +519,21 @@ public class AiModelFactoryImpl implements AiModelFactory {
.build();
}
/**
* 可参考 {@link AnthropicChatAutoConfiguration} anthropicApi 方法
*/
private static AnthropicChatModel buildAnthropicChatModel(String apiKey, String url) {
AnthropicApi.Builder builder = AnthropicApi.builder().apiKey(apiKey);
if (StrUtil.isNotEmpty(url)) {
builder.baseUrl(url);
}
AnthropicApi anthropicApi = builder.build();
return AnthropicChatModel.builder()
.anthropicApi(anthropicApi)
.toolCallingManager(getToolCallingManager())
.build();
}
/**
* 可参考 {@link OpenAiImageAutoConfiguration} openAiImageModel 方法
*/

View File

@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.ai.enums.model.AiPlatformEnum;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
import org.springaicommunity.moonshot.MoonshotChatOptions;
import org.springaicommunity.qianfan.QianFanChatOptions;
import org.springframework.ai.anthropic.AnthropicChatOptions;
import org.springframework.ai.azure.openai.AzureOpenAiChatOptions;
import org.springframework.ai.chat.messages.*;
import org.springframework.ai.chat.prompt.ChatOptions;
@ -67,6 +68,9 @@ public class AiUtils {
case AZURE_OPENAI:
return AzureOpenAiChatOptions.builder().deploymentName(model).temperature(temperature).maxTokens(maxTokens)
.toolNames(toolNames).toolContext(toolContext).build();
case ANTHROPIC:
return AnthropicChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens)
.toolNames(toolNames).toolContext(toolContext).build();
case OLLAMA:
return OllamaOptions.builder().model(model).temperature(temperature).numPredict(maxTokens)
.toolNames(toolNames).toolContext(toolContext).build();

View File

@ -0,0 +1,59 @@
package cn.iocoder.yudao.module.ai.framework.ai.core.model.chat;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.ai.anthropic.AnthropicChatModel;
import org.springframework.ai.anthropic.api.AnthropicApi;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import reactor.core.publisher.Flux;
import java.util.ArrayList;
import java.util.List;
/**
* {@link AnthropicChatModel} 集成测试类
*
* @author 芋道源码
*/
public class AnthropicChatModelTest {
private final AnthropicChatModel chatModel = AnthropicChatModel.builder()
.anthropicApi(AnthropicApi.builder()
.apiKey("sk-muubv7cXeLw0Etgs743f365cD5Ea44429946Fa7e672d8942")
.baseUrl("https://aihubmix.com")
.build())
.build();
@Test
@Disabled
public void testCall() {
// 准备参数
List<Message> messages = new ArrayList<>();
messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));
messages.add(new UserMessage("1 + 1 = "));
// 调用
ChatResponse response = chatModel.call(new Prompt(messages));
// 打印结果
System.out.println(response);
}
@Test
@Disabled
public void testStream() {
// 准备参数
List<Message> messages = new ArrayList<>();
messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));
messages.add(new UserMessage("1 + 1 = "));
// 调用
Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages));
// 打印结果
flux.doOnNext(System.out::println).then().block();
}
}

View File

@ -16,8 +16,11 @@ import org.springframework.ai.image.ImageResponse;
*/
public class TongYiImagesModelTest {
private final DashScopeImageModel imageModel = new DashScopeImageModel(
new DashScopeImageApi("sk-7d903764249848cfa912733146da12d1"));
private final DashScopeImageModel imageModel = DashScopeImageModel.builder()
.dashScopeApi(DashScopeImageApi.builder()
.apiKey("sk-47aa124781be4bfb95244cc62f63f7d0")
.build())
.build();
@Test
@Disabled

View File

@ -175,7 +175,8 @@ spring:
azure: # OpenAI 微软
openai:
endpoint: https://eastusprejade.openai.azure.com
api-key: xxx
anthropic: # Anthropic Claude
api-key: sk-muubv7cXeLw0Etgs743f365cD5Ea44429946Fa7e672d8942
ollama:
base-url: http://127.0.0.1:11434
chat: