LanguageModel 是 langchain4j 中定义大语言模型(LLM)核心能力的顶级接口,位于 dev.langchain4j.model.language 包下,是所有语言模型实现类的 “契约”—— 它抽象了 “生成文本” 这一核心行为,屏蔽了不同模型(OpenAI、本地模型、Azure OpenAI 等)的底层差异,让开发者可以用统一的方式调用任意 LLM。
注意:LangChain4j 将不再扩展对 LanguageModel 的支持,因此在所有新功能中,我们将使用 ChatModel 接口。
LanguageModel 接口定义了两个方法:
default Response<String> generate(Prompt prompt) 生成对给定提示词的响应。该方法是一个默认方法,底层通过调用 generate(String prompt) 实现。
Response<String> generate(String prompt) 生成对给定提示词的响应。
接口文档:https://docs.langchain4j.dev/apidocs/dev/langchain4j/model/language/LanguageModel.html
下面发起“你是谁?”问题,验证 LanguageModel 的功能:
package com.hxstrive.langchain4j.languageModel;
import dev.langchain4j.model.input.Prompt;
import dev.langchain4j.model.language.LanguageModel;
import dev.langchain4j.model.openai.OpenAiLanguageModel;
import dev.langchain4j.model.output.Response;
public class LanguageModelDemo {
// 推荐:将OPEN_API_KEY设置成环境变量, 避免硬编码或随着代码泄露
// 注意,设置完环境变量记得重启IDEA,不然可能环境变量不会生效
private static final String API_KEY = System.getenv("OPEN_API_KEY");
public static void main(String[] args) {
// 创建 LanguageModel 实现类(OpenAI 为例)
LanguageModel model = OpenAiLanguageModel.builder()
.baseUrl("https://api.xty.app/v1")
.apiKey(API_KEY)
.modelName("gpt-3.5-turbo-0125") // 模型名称
.temperature(0.7) // 随机性(0-1,越小越精准)
.logRequests(true)
.logResponses(true)
.build();
// 生成文本
Response<String> response = model.generate(new Prompt("你是谁?"));
System.out.println("回复内容:\n" + response.content());
System.out.println("元数据:\n" + response.metadata());
System.out.println("Token使用量:\n" + response.tokenUsage());
System.out.println("结束原因:\n" + response.finishReason());
}
}运行上述示例,请求参数如下:
[main] INFO dev.langchain4j.http.client.log.LoggingHttpClient -- HTTP request:
- method: POST
- url: https://api.xty.app/v1/completions
- headers: [Authorization: Beare...00], [User-Agent: langchain4j-openai], [Content-Type: application/json]
- body: {
"model" : "text-davinci-003",
"prompt" : "你是谁?",
"temperature" : 0.7,
"stream" : false
}响应内容如下:
[main] INFO dev.langchain4j.http.client.log.LoggingHttpClient -- HTTP response:
- status code: 200
- headers: [:status: 200], [access-control-allow-headers: *], [access-control-allow-methods: POST, GET, OPTIONS, DELETE,PUT], [access-control-allow-origin: *], [access-control-max-age: 3600], [alt-svc: h3=":443"; ma=86400], [cf-cache-status: DYNAMIC], [cf-ray: 9c0b8f417807f7af-LAX], [content-length: 731], [content-type: application/json;charset=UTF-8], [date: Tue, 20 Jan 2026 03:42:06 GMT], [nel: {"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}], [report-to: {"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=gyGffd6mqoaTXg7S91JKA0Dm1jhNAdGuLX4xRI07tNxN4JQjJNBmgRVtYNhMsl7sTMf0o1RuAQm4d2WKfGuvk1SkheO8qbJM9U%2BO"}]}], [server: cloudflare], [server-timing: [cfCacheStatus;desc="DYNAMIC", cfEdge;dur=8,cfOrigin;dur=4438]], [x-oneapi-request-id: 20260120114202498115825KYH8xXtG]
- body: {
"id": "cmpl-owIrj0KhatyNjK4CmnE6Sx1UGE10PUyP",
"object": "text_completion",
"created": 1768880526,
"model": "text-davinci-003",
"choices": [
{
"index": 0,
"text": "我是 **ChatGPT**,一个由 **OpenAI** 训练的人工智能助手。\n\n我可以用中文或其他语言,帮助你:\n- 回答问题、解释概念 \n- 写作或润色文本 \n- 学习、编程、翻译 \n- 头脑风暴、解决问题 \n\n你可以把我当作一个随时可用的智能助手 🙂 \n你想让我帮你做什么?",
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 12,
"completion_tokens": 137,
"total_tokens": 149
}
}注意,此时的请求接口为 /v1/completions,即文本补全接口。对应的是 OpenAI 的初代生成模型,这类模型不支持对话格式,仅接收纯文本 prompt 进行续写、补全或生成任务。
下面是 OpenAI 提供的文本补全模型:
模型名称 | 特点 | 适用场景 | 注意事项 |
text-davinci-003 | 性能最强的文本补全模型,支持长文本生成、复杂推理、摘要、翻译 | 内容创作、代码生成、文案续写、复杂指令执行 | 价格较高,token 消耗快;已被标记为「legacy」(旧版),未来可能逐步下线 |
text-curie-001 | 平衡性能与成本,推理能力优于 babbage 和 ada | 简单摘要、分类任务、批量文本处理 | 适合对成本敏感,且不需要顶级推理能力的场景 |
text-babbage-001 | 速度快、成本低 | 基础文本补全、关键词提取、简单改写 | 不适合复杂逻辑任务 |
text-ada-001 | 最快、最便宜的文本补全模型 | 超大规模批量处理、简单文本生成、语义搜索辅助 | 推理能力最弱,仅适合轻量任务 |
注意:上述模型不支持 messages 参数,必须用 prompt 传递指令,如下:
{
"model": "text-davinci-003",
"prompt": "请续写下面的句子:今天的天气很好,",
"temperature": 0.7,
"max_tokens": 100
}如果你误用了对话(Chat)模型,如 gpt-3.5-turbo,则会抛出如下错误信息:
Exception in thread "main" java.lang.IllegalArgumentException: content cannot be null at dev.langchain4j.internal.Exceptions.illegalArgument(Exceptions.java:23) at dev.langchain4j.internal.ValidationUtils.ensureNotNull(ValidationUtils.java:55) at dev.langchain4j.internal.ValidationUtils.ensureNotNull(ValidationUtils.java:42) at dev.langchain4j.model.output.Response.<init>(Response.java:65) at dev.langchain4j.model.output.Response.<init>(Response.java:49) at dev.langchain4j.model.output.Response.from(Response.java:168) at dev.langchain4j.model.openai.OpenAiLanguageModel.generate(OpenAiLanguageModel.java:74) at dev.langchain4j.model.language.LanguageModel.generate(LanguageModel.java:29) at com.hxstrive.langchain4j.languageModel.LanguageModelDemo.main(LanguageModelDemo.java:26)
出现该错误的根本原因是响应格式不匹配导致的,对话模型响应的格式如下:
[main] INFO dev.langchain4j.http.client.log.LoggingHttpClient -- HTTP response:
- status code: 200
- headers: [:status: 200], [access-control-allow-credentials: false], [access-control-allow-headers: *], [access-control-allow-methods: GET, POST, PUT, DELETE, PATCH, OPTIONS], [access-control-allow-origin: *], [access-control-expose-headers: Content-Disposition], [access-control-max-age: 86400], [alt-svc: h3=":443"; ma=86400], [cf-cache-status: DYNAMIC], [cf-ray: 9c0b9eb01a8594cd-LHR], [content-length: 347], [content-type: application/json], [date: Tue, 20 Jan 2026 03:52:36 GMT], [nel: {"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}], [report-to: {"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=ZKkViSCoI3Y9WuHn3wor79TbDhMwssLaAw6kAc215RLuijtIIhbEPmRsJ4DRqicU6J9jJ3zxWKMYcyUq%2FpOQ0iTiZoDEO91tcjMB"}]}], [server: cloudflare], [server-timing: [cfCacheStatus;desc="DYNAMIC", cfEdge;dur=10,cfOrigin;dur=1579]], [x-oneapi-request-id: 20260120115234815205922tmwHFQYn]
- body: {
"choices": [
{
"finish_reason": "stop",
"index": 0,
"logprobs": null,
"message": {
"content": "This is a test!",
"role": "assistant"
}
}
],
"created": 1768881155,
"id": "chatcmpl-OQIxVuGntJ9RS9Yk8MXxnX0IOrR2s",
"model": "gpt-3.5-turbo",
"object": "chat.completion",
"system_fingerprint": "fp_b28b39ffa8",
"usage": {
"completion_tokens": 5,
"prompt_tokens": 13,
"total_tokens": 18
}
}在 LanguageModel 类的 generate(String prompt) 方法中将会提取响应内容代码如下:
public Response<String> generate(String prompt) {
CompletionRequest request = CompletionRequest.builder().model(this.modelName).prompt(prompt).temperature(this.temperature).build();
// 发起请求,将响应封装到 CompletionResponse 对象中
CompletionResponse response = (CompletionResponse 对象中)RetryUtils.withRetryMappingExceptions(() -> {
return (CompletionResponse)this.client.completion(request).execute();
}, this.maxRetries);
// 获取 choices,并转换为 completionChoice
CompletionChoice completionChoice = (CompletionChoice)response.choices().get(0);
// 构建 Response,但是 completionChoice.text() 明显没有值的,响应格式不正确
return Response.from(completionChoice.text(), OpenAiUtils.tokenUsageFrom(response.usage()),
OpenAiUtils.finishReasonFrom(completionChoice.finishReason()));
}下面是 CompletionResponse 和 CompletionChoice 定义的响应消息,代码如下:
public final class CompletionResponse {
@JsonProperty
private final String id;
@JsonProperty
private final Integer created;
@JsonProperty
private final String model;
@JsonProperty
private final List<CompletionChoice> choices; // 具体响应 choices
@JsonProperty
private final Usage usage;
//...
}
public final class CompletionChoice {
@JsonProperty
private final String text; // 发现了吗,不是从 messages 中获取数据
@JsonProperty
private final Integer index;
@JsonProperty
private final Logprobs logprobs;
@JsonProperty
private final String finishReason;
//...
}最终导致响应的内容没有被解析到,执行语句时,触发异常。