LangChain4j 模型参数配置与调优
概述
本教程将详细介绍如何配置和调优 LangChain4j 中的模型参数,包括温度(temperature)、超时设置、日志记录、流式响应等高级功能。
核心模型参数
1. Temperature(温度)
Temperature 控制模型输出的随机性和创造性:
- 低温度 (0.0 - 0.3): 输出更确定、更一致,适合事实性任务
- 中温度 (0.5 - 0.7): 平衡创造性和一致性
- 高温度 (0.8 - 2.0): 输出更随机、更有创造性,适合创意写作
代码示例 (参考:tutorials/src/main/java/_01_ModelParameters.java)
java
package dev.langchain4j.example;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import java.time.Duration;
import static dev.langchain4j.model.openai.OpenAiChatModelName.GPT_4_O_MINI;
public class TemperatureExample {
public static void main(String[] args) {
String prompt = "用一句话描述春天";
// 低温度 - 输出更稳定、可预测
ChatLanguageModel conservativeModel = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName(GPT_4_O_MINI)
.temperature(0.1) // 低温度
.build();
System.out.println("【低温度输出】");
System.out.println(conservativeModel.generate(prompt));
System.out.println(conservativeModel.generate(prompt)); // 两次输出会非常相似
// 高温度 - 输出更有创意、随机性高
ChatLanguageModel creativeModel = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName(GPT_4_O_MINI)
.temperature(1.5) // 高温度
.build();
System.out.println("\n【高温度输出】");
System.out.println(creativeModel.generate(prompt));
System.out.println(creativeModel.generate(prompt)); // 两次输出差异较大
}
}
输出示例:
【低温度输出】
春天是万物复苏、生机勃勃的季节。
春天是万物复苏、生机盎然的季节。
【高温度输出】
春天是花朵绽放、蝴蝶翩翩起舞的诗意时光。
春暖花开,万物苏醒,大地披上绿色的新装,鸟儿欢唱着季节的赞歌。
2. Timeout(超时设置)
设置请求超时时间,避免长时间等待:
java
ChatLanguageModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName(GPT_4_O_MINI)
.timeout(Duration.ofSeconds(60)) // 设置 60 秒超时
.build();
推荐配置:
- 快速查询: 30 秒
- 常规对话: 60 秒
- 复杂任务: 120 秒
3. Max Tokens(最大令牌数)
控制生成内容的最大长度:
java
ChatLanguageModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName(GPT_4_O_MINI)
.maxTokens(500) // 最多生成 500 个 token
.build();
Token 估算:
- 1 个中文字符 ≈ 2-3 tokens
- 1 个英文单词 ≈ 1-2 tokens
- 500 tokens ≈ 200-250 个中文字
4. Top P(核采样)
控制模型考虑的词汇范围:
java
ChatLanguageModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName(GPT_4_O_MINI)
.topP(0.9) // 只考虑累积概率达到 90% 的词汇
.build();
- topP = 1.0: 考虑所有可能的词汇
- topP = 0.9: 只考虑最可能的 90% 词汇(推荐)
- topP = 0.5: 输出更保守
日志与调试
启用请求/响应日志
LangChain4j 提供内置的日志功能,帮助调试和监控:
java
import dev.langchain4j.model.openai.OpenAiChatModel;
ChatLanguageModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName(GPT_4_O_MINI)
.logRequests(true) // 记录请求内容
.logResponses(true) // 记录响应内容
.build();
String response = model.generate("你好");
日志输出示例:
Request:
- model: gpt-4o-mini
- messages: [UserMessage { contents = [TextContent { text = "你好" }] }]
- temperature: 0.7
- max tokens: null
Response:
- id: chatcmpl-abc123
- model: gpt-4o-mini
- usage: {prompt_tokens=8, completion_tokens=15, total_tokens=23}
- content: 你好!有什么我可以帮助你的吗?
自定义日志记录器
对于生产环境,使用自定义监听器:
java
import dev.langchain4j.model.chat.listener.ChatModelListener;
import dev.langchain4j.model.chat.listener.ChatModelRequest;
import dev.langchain4j.model.chat.listener.ChatModelResponse;
ChatModelListener customListener = new ChatModelListener() {
@Override
public void onRequest(ChatModelRequest request) {
System.out.println("发送请求: " + request.messages().size() + " 条消息");
}
@Override
public void onResponse(ChatModelResponse response) {
System.out.println("收到响应,耗时: " + response.metadata().finishReason());
System.out.println("Token 使用: " + response.tokenUsage());
}
@Override
public void onError(Throwable error) {
System.err.println("请求失败: " + error.getMessage());
}
};
ChatLanguageModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName(GPT_4_O_MINI)
.listeners(List.of(customListener)) // 添加监听器
.build();
流式响应(Streaming)
流式响应可以逐步返回内容,提供更好的用户体验。
代码示例 (参考:tutorials/src/main/java/_04_Streaming.java)
java
package dev.langchain4j.example;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.model.StreamingResponseHandler;
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
import dev.langchain4j.model.output.Response;
import static dev.langchain4j.model.openai.OpenAiChatModelName.GPT_4_O_MINI;
public class StreamingExample {
public static void main(String[] args) throws InterruptedException {
// 1. 创建流式模型
OpenAiStreamingChatModel model = OpenAiStreamingChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName(GPT_4_O_MINI)
.build();
// 2. 定义响应处理器
StreamingResponseHandler<AiMessage> handler = new StreamingResponseHandler<>() {
@Override
public void onNext(String token) {
// 每收到一个 token 就立即打印
System.out.print(token);
}
@Override
public void onComplete(Response<AiMessage> response) {
System.out.println("\n\n[响应完成]");
System.out.println("完整消息: " + response.content().text());
}
@Override
public void onError(Throwable error) {
System.err.println("发生错误: " + error.getMessage());
}
};
// 3. 发送流式请求
System.out.println("请写一首关于春天的诗:\n");
model.generate("请写一首关于春天的短诗", handler);
// 等待流式响应完成
Thread.sleep(10000);
}
}
AI Service 中使用流式响应
java
import dev.langchain4j.service.TokenStream;
interface StreamingAssistant {
TokenStream chat(String message);
}
StreamingAssistant assistant = AiServices.builder(StreamingAssistant.class)
.streamingChatModel(streamingModel) // 使用流式模型
.build();
assistant.chat("讲个笑话")
.onNext(System.out::print)
.onComplete(response -> System.out.println("\n完成"))
.onError(Throwable::printStackTrace)
.start();
重试与错误处理
配置重试策略
java
import dev.langchain4j.model.openai.OpenAiChatModel;
ChatLanguageModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName(GPT_4_O_MINI)
.maxRetries(3) // 最多重试 3 次
.build();
手动错误处理
java
try {
String response = model.generate("你好");
System.out.println(response);
} catch (Exception e) {
if (e.getMessage().contains("timeout")) {
System.err.println("请求超时,请稍后重试");
} else if (e.getMessage().contains("rate limit")) {
System.err.println("触发速率限制,请降低请求频率");
} else {
System.err.println("发生错误: " + e.getMessage());
}
}
响应格式控制
JSON 模式
强制模型返回有效的 JSON:
java
ChatLanguageModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName(GPT_4_O_MINI)
.responseFormat("json_object") // 强制 JSON 输出
.build();
String response = model.generate("用 JSON 格式返回:姓名张三,年龄25,城市北京");
System.out.println(response);
// 输出: {"姓名": "张三", "年龄": 25, "城市": "北京"}
严格 JSON Schema(推荐)
java
ChatLanguageModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName(GPT_4_O_MINI)
.responseFormat("json_schema") // 使用 JSON Schema
.strictJsonSchema(true) // 严格模式
.build();
// 结合 AI Service 使用
interface PersonExtractor {
Person extractFrom(String text);
}
static class Person {
private String name;
private int age;
private String city;
// getters and setters...
}
PersonExtractor extractor = AiServices.create(PersonExtractor.class, model);
Person person = extractor.extractFrom("我叫张三,今年25岁,住在北京");
模型选择建议
OpenAI 模型对比
| 模型 | 成本 | 速度 | 能力 | 适用场景 |
|---|---|---|---|---|
| gpt-4o-mini | 低 | 快 | 中 | 开发测试、简单任务 |
| gpt-4o | 中 | 中 | 高 | 生产环境、复杂推理 |
| gpt-4-turbo | 高 | 中 | 最高 | 高精度任务 |
| gpt-3.5-turbo | 最低 | 最快 | 低 | 大规模简单任务 |
使用示例
java
// 开发环境
ChatLanguageModel devModel = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-4o-mini")
.temperature(0.7)
.build();
// 生产环境
ChatLanguageModel prodModel = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-4o")
.temperature(0.3)
.timeout(Duration.ofSeconds(60))
.maxRetries(3)
.logRequests(false) // 生产环境关闭详细日志
.logResponses(false)
.build();
完整配置示例
java
package dev.langchain4j.example;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import java.time.Duration;
import static dev.langchain4j.model.openai.OpenAiChatModelName.GPT_4_O_MINI;
public class CompleteConfigExample {
public static void main(String[] args) {
ChatLanguageModel model = OpenAiChatModel.builder()
// 基础配置
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName(GPT_4_O_MINI)
// 生成参数
.temperature(0.7) // 创造性
.topP(0.9) // 核采样
.maxTokens(2000) // 最大长度
// 网络配置
.timeout(Duration.ofSeconds(60)) // 超时
.maxRetries(3) // 重试次数
// 日志配置
.logRequests(true) // 记录请求
.logResponses(true) // 记录响应
// 响应格式
.responseFormat("json_object") // JSON 模式
.build();
// 使用模型
String response = model.generate("介绍一下 LangChain4j");
System.out.println(response);
}
}
性能优化建议
1. 批量处理
java
List<String> questions = List.of("问题1", "问题2", "问题3");
// 不推荐:逐个调用
for (String question : questions) {
String answer = model.generate(question); // 每次都是独立请求
}
// 推荐:批量处理(如果支持)
List<ChatMessage> messages = questions.stream()
.map(q -> UserMessage.from(q))
.collect(Collectors.toList());
2. 缓存响应
java
Map<String, String> cache = new ConcurrentHashMap<>();
String getCachedResponse(String prompt) {
return cache.computeIfAbsent(prompt, p -> model.generate(p));
}
3. 并行请求
java
ExecutorService executor = Executors.newFixedThreadPool(5);
List<CompletableFuture<String>> futures = questions.stream()
.map(q -> CompletableFuture.supplyAsync(() -> model.generate(q), executor))
.collect(Collectors.toList());
List<String> answers = futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());
常见问题
Q1: Temperature 和 Top P 应该如何搭配?
A: 通常只需要调整其中一个:
- Temperature: 更直观,推荐使用
- Top P: 更精细的控制
- 不要同时设置极端值(如 temperature=2.0 + topP=0.1)
Q2: 如何处理速率限制?
A:
java
// 使用指数退避重试
int maxRetries = 5;
for (int i = 0; i < maxRetries; i++) {
try {
return model.generate(prompt);
} catch (Exception e) {
if (e.getMessage().contains("rate limit") && i < maxRetries - 1) {
Thread.sleep((long) Math.pow(2, i) * 1000); // 1s, 2s, 4s, 8s, 16s
} else {
throw e;
}
}
}
Q3: 如何估算 Token 消耗?
A: 使用 Tokenizer:
java
import dev.langchain4j.model.openai.OpenAiTokenizer;
Tokenizer tokenizer = new OpenAiTokenizer(GPT_4_O_MINI);
int tokenCount = tokenizer.estimateTokenCountInText("你好,世界!");
System.out.println("Token 数量: " + tokenCount);
下一步学习
- 03-提示词与模板 - 掌握提示词工程
- 04-AI服务核心模式 - 深入 AI Services
- 05-对话记忆管理 - 实现上下文记忆
参考资料
- 示例代码:
tutorials/src/main/java/_01_ModelParameters.java - 流式响应:
tutorials/src/main/java/_04_Streaming.java - OpenAI 文档: https://platform.openai.com/docs/api-reference