LangChain4j 的 AiServices 工具类

到目前为止,我们一直在介绍像 ChatModel、ChatMessage、ChatMemory 等底层组件。在这个层面进行开发具有很高的灵活性,能给你完全的自由度,但这也迫使你编写大量的样板代码。由于由大语言模型(LLM)驱动的应用通常不仅需要单个组件,还需要多个组件协同工作(例如,提示词模板、聊天记忆、大语言模型、输出解析器、检索增强生成(RAG)组件:嵌入模型和存储),并且经常涉及多次交互,因此对所有这些组件进行编排就变得更加繁琐。

我们希望你专注于业务逻辑,而非底层实现细节。因此,LangChain4j 中目前有两个高层概念可以在这方面提供帮助:AI 服务(AI Services)和链(Chains)。

链(旧版)

Chains(链)的概念源自 Python 的 LangChain(在 LCEL 引入之前)。其理念是为每个常见用例(如聊天机器人、RAG 等)配备一个 Chain。Chains 组合多个低级组件并协调它们之间的交互。它们的主要问题是,如果你需要自定义某些内容,它们会过于僵化。

LangChain4j 目前仅实现了两个 Chains(ConversationalChain 和 ConversationalRetrievalChain),并且目前我们不打算再添加更多。

简单示例:

package com.hxstrive.langchain4j.chains;

import dev.langchain4j.chain.ConversationalChain;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.openai.OpenAiChatModel;

public class SimpleChainsDemo {
    // 推荐:将OPEN_API_KEY设置成环境变量, 避免硬编码或随着代码泄露
    // 注意,设置完环境变量记得重启IDEA,不然可能环境变量不会生效
    private static final String API_KEY = System.getenv("OPEN_API_KEY");

    public static void main(String[] args) {
        // 创建 ChatModel 实现类(OpenAI 为例)
        ChatModel chatModel = OpenAiChatModel.builder()
                .baseUrl("https://api.xty.app/v1")
                .apiKey(API_KEY)
                .modelName("gpt-3.5-turbo")
                .temperature(0.7)
                .logRequests(true)
                .logResponses(true)
                .build();

        // 使用 ConversationalChain
        ConversationalChain conversationalChain = ConversationalChain.builder()
                .chatModel(chatModel) // 设置底层模型
                .build();

        // 发起会话
        String answer = conversationalChain.execute("你好");
        System.out.println(answer);
    }
}

AI 服务(AI Services)

我们提出了另一种名为 AI 服务的解决方案,专为 Java 量身定制。其理念是将与大型语言模型(LLMs)及其他组件交互的复杂性隐藏在一个简单的应用程序编程接口(API)背后。

这种方法与 Spring Data JPA 或 Retrofit 非常相似:你声明性地定义一个具有所需 API 的接口,而 LangChain4j 会提供一个实现该接口的对象(代理)。你可以将 AI 服务视为应用程序中服务层的一个组件。它提供 AI 服务,因此得名。

AI 服务处理最常见的操作:

  • 为大语言模型格式化输入

  • 解析来自大语言模型的输出

它们还支持更高级的功能:

  • 聊天记忆

  • 工具

  • 检索增强生成(RAG)

AI 服务可用于构建有状态的聊天机器人,以促进双向交互,也可用于自动化那些每次调用大语言模型(LLM)都是相互独立的流程。

让我们来看一个最简单的 AI 服务。之后,我们将探讨更复杂的例子。

最简单的 AI 服务

首先,我们定义一个接口,它包含一个单一的方法,即 chat,该方法接收一个 String 作为输入,并返回一个 String。

interface Assistant {
    // userMessage 是用户输入的消息
    // 返回值是 AI 回复的内容呢
    String chat(String userMessage);
}

然后,我们创建一个低级组件 ChatModel,这些组件将在我们的 AI 服务内部使用。在这种情况下,我们只需要 ChatModel:

ChatModel model = OpenAiChatModel.builder()
    .apiKey(System.getenv("OPENAI_API_KEY"))
    .modelName(GPT_4_O_MINI)
    .build();

最后,我们可以使用 AiServices 类来创建我们的 AI 服务实例:

// 这里 LangChain4j 将动态创建一个 Assistant 接口的代理对象,实现调用大模型的具体操作
Assistant assistant = AiServices.create(Assistant.class, model);

注意:在 Quarkus 和 Spring Boot 应用程序中,自动配置会处理 Assistant bean 的创建。这意味着您无需调用 AiServices.create(...),只需在需要的地方注入 / 自动装配 Assistant 即可。

现在我们可以使用 Assistant:

String answer = assistant.chat("Hello");
System.out.println(answer); // Hello, how can I help you?

完整示例代码

完整的示例代码如下:

package com.hxstrive.langchain4j.aiServices;

import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;

public class SimpleAiServicesDemo {
    // 推荐:将OPEN_API_KEY设置成环境变量, 避免硬编码或随着代码泄露
    // 注意,设置完环境变量记得重启IDEA,不然可能环境变量不会生效
    private static final String API_KEY = System.getenv("OPEN_API_KEY");

    // 定义业务接口
    interface Assistant {
        // userMessage 是用户输入的消息
        // 返回值是 AI 回复的内容呢
        String chat(String userMessage);
    }

    public static void main(String[] args) {
        // 创建 ChatModel 实现类(OpenAI 为例)
        ChatModel chatModel = OpenAiChatModel.builder()
                .baseUrl("https://api.xty.app/v1")
                .apiKey(API_KEY)
                .modelName("gpt-3.5-turbo")
                .temperature(0.7)
                .logRequests(true)
                .logResponses(true)
                .build();

        // 使用 AiServices 创建服务
        Assistant assistant = AiServices.builder(Assistant.class)
                .chatModel(chatModel)
                .build();

        // 发起对话
        String answer = assistant.chat("你好! ");
        System.out.println(answer);
    }
}

运行示例,输出如下:

15:56:34.252 [main] INFO dev.langchain4j.http.client.log.LoggingHttpClient -- HTTP request:
- method: POST
- url: https://api.xty.app/v1/chat/completions
- headers: [Authorization: Beare...00], [User-Agent: langchain4j-openai], [Content-Type: application/json]
- body: {
  "model" : "gpt-3.5-turbo",
  "messages" : [ {
    "role" : "user",
    "content" : "你好! "
  } ],
  "temperature" : 0.7,
  "stream" : false
}

15:56:38.052 [main] INFO dev.langchain4j.http.client.log.LoggingHttpClient -- HTTP response:
- status code: 200
- headers: [:status: 200], ....
- body: {
    "id": "chatcmpl-GJnq5oEvtHm5UT6gTu5EOgp0e0Tvo",
    "object": "chat.completion",
    "created": 1768982197,
    "model": "gpt-3.5-turbo-0613",
    "choices": [
        {
            "index": 0,
            "message": {
                "role": "assistant",
                "content": "你好!😊  \n很高兴见到你,有什么我可以帮你的吗?"
            },
            "finish_reason": "stop"
        }
    ],
    "usage": {
        "prompt_tokens": 11,
        "completion_tokens": 28,
        "total_tokens": 39
    },
    "system_fingerprint": "fp_b28b39ffa8"
}

你好!😊  
很高兴见到你,有什么我可以帮你的吗?

👉更多 LangChain4j 关于 AI Services 的知识请继续阅读后续章节……

  

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