LangChain4j 教程

LangChain4j 的 LanguageModel 接口

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;
    //...
}

最终导致响应的内容没有被解析到,执行语句时,触发异常。

  

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号