掌握如何在LangChain4J中集成多个LLM供应商,实现灵活的模型切换
时间:30分钟 | 难度:⭐⭐ | Week 2
官方Example信息
- GitHub链接:OpenAiExample.java
- 相关Example:OpenAiExample、AnthropicExample
- 所在路径:src/main/java/dev/langchain4j/examples/
- 代码行数:约40-60行
- 难度:初级-中级 ⭐⭐
学习目标
- 理解OpenAI和Claude的区别
- 学会集成OpenAI ChatGPT
- 学会集成Anthropic Claude
- 掌握模型参数配置
- 实现LLM工厂模式
- 能在项目中灵活切换模型
🚀 快速入门:多LLM集成
为什么需要多LLM?
为什么?:
1. 成本优化 - 不同模型价格不同
2. 性能对比 - 同一任务不同模型效果可能不同
3. 可用性 - 某个模型宕机时可自动切换
4. 专业化 - 某些任务可能只有特定模型表现好
现实场景:
- 简单问题 → gpt-4o-mini(便宜)
- 复杂推理 → gpt-4o(贵但准)
- 代码生成 → Claude 3 Opus(最强)
- 快速响应 → Claude 3 Haiku(最快)
多LLM的基本架构
┌─────────────────┐
│ 应用层 │
└────────┬────────┘
│
┌────────▼──────────┐
│ LLMFactory │
│ (LLM工厂) │
└────────┬──────────┘
│
┌────┴─────────────┐
│ │
┌───▼────┐ ┌──────▼──┐
│ OpenAI │ │ Anthropic│
│ GPT │ │ Claude │
└────────┘ └──────────┘
│ │
API调用 API调用
实现一个简单的MultiLlmService
@Service
public class MultiLlmService {
private final ChatModel openAiModel;
private final ChatModel claudeModel;
public MultiLlmService(
@Value("${openai.api-key}") String openaiKey,
@Value("${anthropic.api-key}") String claudeKey
) {
// OpenAI初始化
this.openAiModel = OpenAiChatModel.builder()
.apiKey(openaiKey)
.modelName("gpt-4o-mini")
.build();
// Claude初始化
this.claudeModel = AnthropicChatModel.builder()
.apiKey(claudeKey)
.modelName("claude-3-haiku-20240307")
.build();
}
// 根据任务类型选择模型
public String chat(String question, String modelType) {
ChatModel model = "openai".equals(modelType) ? openAiModel : claudeModel;
return model.chat(question);
}
}
深度讲解
OpenAI集成完全指南
1️⃣ OpenAiChatModel配置
// 最小化配置
OpenAiChatModel model = OpenAiChatModel.builder()
.apiKey("sk-proj-xxx")
.modelName("gpt-4o-mini")
.build();
// 完整配置
OpenAiChatModel model = OpenAiChatModel.builder()
.apiKey("sk-proj-xxx")
.baseUrl("https://api.openai.com/v1/")
.modelName("gpt-4o-mini")
.temperature(0.7)
.maxTokens(1000)
.topP(1.0)
.frequencyPenalty(0.0)
.presencePenalty(0.0)
.build();
参数说明:
apiKey:OpenAI API密钥baseUrl:API端点(支持代理URL,如国内镜像)modelName:模型名称(gpt-4o、gpt-4o-mini等)temperature:创意度(0-2,0最确定,2最随机)maxTokens:最大输出长度topP:核心采样(0-1)frequencyPenalty:频率惩罚(减少重复词)presencePenalty:新颖性惩罚(鼓励新话题)
2️⃣ 支持的OpenAI模型
最新模型(推荐):
- gpt-4o(最强,多模态)
- gpt-4o-mini(推荐,性价比最高)
- gpt-4-turbo(高级推理)
过时模型(不推荐新项目):
- gpt-3.5-turbo(便宜但弱)
- gpt-4(比4o差)
3️⃣ OpenAI API代理配置
国内用户,可使用代理:
// 使用国内镜像(如果key支持)
OpenAiChatModel model = OpenAiChatModel.builder()
.apiKey("sk-proj-xxx")
.baseUrl("https://api.openai-proxy.com/v1/") // 代理URL
.modelName("gpt-4o-mini")
.build();
Anthropic Claude集成完全指南
1️⃣ AnthropicChatModel配置
// 最小化配置
AnthropicChatModel model = AnthropicChatModel.builder()
.apiKey("sk-ant-xxx")
.modelName("claude-3-haiku-20240307")
.build();
// 完整配置
AnthropicChatModel model = AnthropicChatModel.builder()
.apiKey("sk-ant-xxx")
.modelName("claude-3-opus-20240229")
.temperature(0.7)
.maxTokens(1024)
.topK(40)
.topP(1.0)
.build();
2️⃣ 支持的Claude模型对比
模型系列 性能 速度 成本 用途
─────────────────────────────────────────────
Claude 3 Opus ★★★★★ 慢 最贵 复杂推理、代码
Claude 3 Sonnet ★★★★ 中等 中等 均衡使用
Claude 3 Haiku ★★★ 快 便宜 简单任务、快速
Claude 2 ★★★★ 中等 便宜 通用任务(过时)
3️⃣ Claude vs OpenAI对比
维度 Claude 3 Opus GPT-4o
─────────────────────────────────────────
推理能力 ⭐⭐⭐⭐⭐(最强) ⭐⭐⭐⭐⭐
代码质量 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐
多模态 ⭐⭐ ⭐⭐⭐⭐⭐
成本 贵 中等
速度 慢 快
上下文窗口 200K 128K
中文理解 ⭐⭐⭐ ⭐⭐⭐⭐
💻 实战代码
LLMFactory工厂模式
@Component
public class LlmFactory {
@Value("${openai.api-key}")
private String openaiKey;
@Value("${anthropic.api-key}")
private String anthropicKey;
private final Map<String, ChatModel> models = new ConcurrentHashMap<>();
/**
* 获取指定模型的ChatModel实例
*/
public ChatModel getModel(LlmType type) {
return models.computeIfAbsent(type.getName(), k -> createModel(type));
}
/**
* 创建新的ChatModel实例
*/
private ChatModel createModel(LlmType type) {
return switch (type) {
case GPT_4O_MINI -> OpenAiChatModel.builder()
.apiKey(openaiKey)
.modelName("gpt-4o-mini")
.temperature(0.7)
.build();
case GPT_4O -> OpenAiChatModel.builder()
.apiKey(openaiKey)
.modelName("gpt-4o")
.temperature(0.7)
.build();
case CLAUDE_3_OPUS -> AnthropicChatModel.builder()
.apiKey(anthropicKey)
.modelName("claude-3-opus-20240229")
.temperature(0.7)
.build();
case CLAUDE_3_HAIKU -> AnthropicChatModel.builder()
.apiKey(anthropicKey)
.modelName("claude-3-haiku-20240307")
.temperature(0.7)
.build();
};
}
}
// 模型类型枚举
public enum LlmType {
GPT_4O_MINI("gpt-4o-mini", "openai"),
GPT_4O("gpt-4o", "openai"),
CLAUDE_3_OPUS("claude-3-opus", "anthropic"),
CLAUDE_3_HAIKU("claude-3-haiku", "anthropic");
private final String modelName;
private final String provider;
LlmType(String modelName, String provider) {
this.modelName = modelName;
this.provider = provider;
}
public String getName() { return modelName; }
public String getProvider() { return provider; }
}
使用工厂的Service
@Service
public class MultiLlmService {
@Autowired
private LlmFactory llmFactory;
/**
* 自动选择最优模型
*/
public String chatWithOptimalModel(String question) {
// 简单的启发式选择
if (isComplexQuestion(question)) {
return llmFactory.getModel(LlmType.GPT_4O).chat(question);
} else {
return llmFactory.getModel(LlmType.GPT_4O_MINI).chat(question);
}
}
/**
* 对比两个模型的输出
*/
public ModelComparison compareModels(String question) {
String openaiResult = llmFactory.getModel(LlmType.GPT_4O_MINI).chat(question);
String claudeResult = llmFactory.getModel(LlmType.CLAUDE_3_HAIKU).chat(question);
return ModelComparison.builder()
.question(question)
.openaiAnswer(openaiResult)
.claudeAnswer(claudeResult)
.timestamp(LocalDateTime.now())
.build();
}
private boolean isComplexQuestion(String question) {
// 简单的复杂度判断
return question.length() > 100 ||
question.contains("为什么") ||
question.contains("如何");
}
}
🔧 常见问题
Q1:如何处理API Key?
A: 最佳实践:
# application.yml
openai:
api-key: ${OPENAI_API_KEY} # 从环境变量读取
base-url: https://api.openai.com/v1/
anthropic:
api-key: ${ANTHROPIC_API_KEY}
# 设置环境变量
export OPENAI_API_KEY=sk-proj-xxx
export ANTHROPIC_API_KEY=sk-ant-xxx
Q2:成本和速度该如何选择?
A: 根据场景:
快速响应(<1秒) → GPT-4o-mini 或 Claude-3-Haiku
均衡方案(<5秒) → Claude-3-Sonnet 或 GPT-4o
最佳质量(无限制) → Claude-3-Opus 或 GPT-4o
Q3:如何实现自动故障转移?
A:
public String chatWithFallback(String question) {
try {
return llmFactory.getModel(LlmType.GPT_4O_MINI).chat(question);
} catch (Exception e) {
log.warn("GPT-4o-mini failed, switching to Claude");
return llmFactory.getModel(LlmType.CLAUDE_3_HAIKU).chat(question);
}
}
📊 成本对比
模型 输入价格 输出价格 推荐场景
─────────────────────────────────────────────────────
GPT-4o-mini $0.15/1M tokens $0.60/1M 日常任务
GPT-4o $5/1M tokens $15/1M 复杂推理
Claude 3 Haiku $0.25/1M tokens $1.25/1M 快速处理
Claude 3 Sonnet $3/1M tokens $15/1M 均衡使用
Claude 3 Opus $15/1M tokens $75/1M 最复杂任务
✅ 最佳实践
1️⃣ 模型选择策略
// ✅ 好的做法
public ChatModel selectModel(TaskType taskType) {
return switch (taskType) {
case SIMPLE_QA -> gptMini; // 便宜
case CODE_GENERATION -> claude; // 代码最强
case COMPLEX_REASONING -> gpt4o;// 推理最强
};
}
// ❌ 坏的做法
public ChatModel getModel() {
return gpt4o; // 总用最贵的,浪费钱
}
2️⃣ 并发调用多个模型
// 获取多个模型的输出用于投票
CompletableFuture<String> openai = CompletableFuture.supplyAsync(() ->
llmFactory.getModel(LlmType.GPT_4O_MINI).chat(question)
);
CompletableFuture<String> claude = CompletableFuture.supplyAsync(() ->
llmFactory.getModel(LlmType.CLAUDE_3_HAIKU).chat(question)
);
CompletableFuture.allOf(openai, claude).join();
// 对多个回答进行投票或组合
3️⃣ 模型性能监控
@Service
public class ModelMonitor {
private final Map<String, ModelMetrics> metrics = new ConcurrentHashMap<>();
public void recordModelPerformance(String modelName, long latency, String result) {
metrics.computeIfAbsent(modelName, k -> new ModelMetrics())
.record(latency, result);
}
public ModelMetrics getMetrics(String modelName) {
return metrics.get(modelName);
}
}
💭 思考问题
- 成本vs质量的平衡:如何在不同场景下选择合适的模型?
- 多模型投票:3个不同的LLM给出不同答案,如何判断哪个更好?
- 实时模型切换:如何根据响应时间动态切换模型?
- 模型微调:不同模型的temperature参数应该如何设置?
学习成果检查:
- 能区分OpenAI和Claude的优劣 ✅ 2026-03-07
- 能配置OpenAiChatModel和AnthropicChatModel ✅ 2026-03-07
- 能实现简单的LLM工厂模式 ✅ 2026-03-07
- 能根据任务选择合适的模型 ✅ 2026-03-07
- 能实现模型的自动故障转移 ✅ 2026-03-07
下一步:学习Chain设计模式,将多个步骤组织成完整的流程。