LangChain4j系列:对API 全面认识并接入OpenAI实现对话功能

#LangChain4j系列:带你入门LangChain4j框架 文章对LangChain4j框架有个整体的认识,并使用LowLevel API接入本地大模型以及OpenAI大模型实现简单的对话功能。本篇文章将介绍如何使用 HighLevel API AiServices 。

LangChain4j 支持的LLMs

:------: :------: :------: :------: :------: :------:
Provider 「大模型提供商」 Streaming 「流式调用」 Tools 「 函数调用 」 Image Inputs 「图片输入」 Local 「本地部署」 Native 「支持原生」
Zhipu AI
Qianfan
ChatGLM
Ollama
Hugging Face
OpenAI
Azure OpenAI
Amazon Bedrock
Anthropic
DashScope
Google Vertex AI Gemini
Google Vertex AI PaLM 2
Jlama
LocalAI
Mistral AI
Cloudflare Workers AI

Spring AI框架支持的大模型基本相似。下面我们将详细介绍LangChain4j支持的LLM API。上一节中我们知道LangChain4j支持low-level APIhigh-level API两种。

LangChain4j支持的low-level LLM API

Model 类型

  • LanguageModel:API 非常简单。接收String作为输入并返回String 作为输出。 目前废弃!!!!
  • ChatLanguageModel:取代 LanguageModel,参数:ChatMessage,返回:AiMessage。 对于LanguageModel已不再扩展,可以把这个忘掉了。在实际开发中使用ChatLanguageModel
  • EmbeddingModel:嵌入模型,将文本转换向量。
  • ImageModel:图片模型,可以生成和编辑图片。
  • ModerationModel:模型可以检查文本是否包含有害内容。
  • ScoringModel:可以针对查询对多段文本进行评分(或排名)。

ChatMessage 类型

ChatMessage 有四种类型的聊天消息;

  • UserMessage:用户的消息。用户可以是应用程序的最终用户,也可以是应用程序本身。根据 LLM支持 UserMessage 的模态。可以只包含文本,也可以包含文本和/或图像。
  • AiMessage:由 AI 生成的消息,通常用于响应 UserMessage
  • ToolExecutionResultMessage:是 ToolExecutionRequest 的结果,函数调用时使用,开发人员一般无需关系。
  • SystemMessage:定义扮演什么角色、它应该如何表现、以什么方式回答等的说明,比其他类型的消息优先级更高。 最好不要让最终用户自由访问定义或注入一些输入。通常,它位于对话的开头。
java 复制代码
    Response<AiMessage> generate(ChatMessage... messages);
    Response<AiMessage> generate(List<ChatMessage> messages);

LangChain4j支持的high-level LLM API

low-level API 使用上非常灵活,但是享受了自由的同时也迫使你编写大量的样板代码。

在实现 LLM-powered 应用程序通常不仅需要单个组件,需要多个组件协同工作(例如,提示模板、聊天记忆、LLMs输出解析器、RAG组件:嵌入模型和存储),并且通常涉及多个交互,因此编排它们变得更加繁琐。

为让开发者更专注于业务逻辑,而不是低级实现细节。LangChain4j 中目前有两个高级概念可以帮助解决这个问题:AI ServicesChains

一些注解

  • @AiService:定义一个集成大模型的服务,标注在接口上,无需实现方法。 参数说明:
    • wiringMode:类注入类型,有两种方式,AUTOMATIC「自定注入」 和 EXPLICIT「手动指定名称」。
    • chatModel:指定使用大模型,如果wiringMode =EXPLICIT,则chatModel指定模型的Bean名称。
    • streamingChatModel:指定支持流式响应的大模型,设置规则与wiringMode设置有关系。
    • chatMemory:指定上下文记忆Bean,设置规则与wiringMode设置有关系。
    • chatMemoryProvider:指定上下文记忆Provider,设置规则与wiringMode设置有关系。
    • contentRetriever:xxx 目前还不知道用途 后续补上
    • retrievalAugmentor:目前还不知道用途 后续补上
    • tools:指定需要调用的函数集合,支持函数调用。
  • @Tool:函数定义,可以设置在 @AiService tools的值上。
  • @MemoryId:定义上下文记忆Id,支持上下文记忆能力。
  • @SystemMessage:定义系统消息,定义模版方式两种:字符串/@SystemMessage(fromResource = "my-prompt-template.txt")
  • @UserMessage:定义用户消息,定义模板方式有两种:字符串/@UserMessage(fromResource = "my-prompt-template.txt")
  • @V:定义模板中的参数名称,一般与@SystemMessage或者@UserMessage配合使用,如果方法仅有一个参数可以使用模板中使用{{it}},如果有多个参数需要@V定义名称。
  • @UserName:@UserName注释的方法参数的值将被注入UserMessage的字段"name"
  • @Moderate: 指定方法需要使用审核模型,对输入/输出内容进行检查。

结构化输出

如果要从 LLM接收结构化输出,可以将 AI Service 方法的返回类型更改为 String 其他。 目前支持的类型如下;

  • 字符串 String
  • 基本类型 boolean/byte/short/int/long/float/double
  • 对象类型 Boolean/Byte/Short/Integer/Long/Float/Double/BigDecimal
  • 时间类型 Date/LocalDate/LocalTime/LocalDateTime
  • 集合类型 List<String>/Set<String>
  • 枚举类型 Enum
  • 自定义 POJO。
  • 自定义 Result<T>
  • 大模型回复消息 AiMessage

RAG(检索增强生成)

这个就不在这里详细解释了,会有专栏对 RAG 应用的落地进行详细分析。

Auto-Moderation

自定审核功能封装,方便调用模型,对输入/输出内容进行内容过滤审核,防止一些违规、反动言论、辱骂等信息出现。代码示例如下;

java 复制代码
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.openai.OpenAiModerationModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.Moderate;
import dev.langchain4j.service.ModerationException;

public class ServiceWithAutoModerationExample {

    interface Chat {
        @Moderate
        String chat(String text);
    }

    public static void main(String[] args) {
        OpenAiModerationModel moderationModel = OpenAiModerationModel.withApiKey(ApiKeys.OPENAI_API_KEY);
        Chat chat = AiServices.builder(Chat.class)
                .chatLanguageModel(OpenAiChatModel.withApiKey(ApiKeys.OPENAI_API_KEY))
                // 指定审核模型,在进行大模型生成时,对内容进行审核。
                .moderationModel(moderationModel) 
                .build();
        try {
            chat.chat("I WILL KILL YOU!!!");
        } catch (ModerationException e) {
            System.out.println(e.getMessage());
            // Text "I WILL KILL YOU!!!" violates content policy
        }
    }
}

连接多个AI服务

由LLM应用程序驱动的逻辑变得越复杂,将其分解为更小的部分就越重要,这是软件开发中的常见做法。如果想完成复杂的任务就需要组合一些服务共同完成,LangChain4j支持将多个服务连接起来。

使用high-level API实战

1. 依赖包

pom 复制代码
<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-spring-boot-starter</artifactId>
    <version>${langchain4j.version}</version>
</dependency>
<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-ollama-spring-boot-starter</artifactId>
    <version>${langchain4j.version}</version>
</dependency>

<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
    <version>${langchain4j.version}</version>
</dependency>

2. yml配置

yml 复制代码
server:
  port: 8801
spring:
  application:
    name: chat-service
langchain4j:
  ollama:
    chat-model:
      base-url: http://localhost:11434
      model-name: mistral:latest # qwen:7b
  open-ai:
    chat-model:
      base-url: xxx
      api-key: xx

3. AiService

java 复制代码
package org.ivy.aiservice.service;

import dev.langchain4j.service.spring.AiService;
import dev.langchain4j.service.spring.AiServiceWiringMode;

/**
 * 通过 @AiService 注解声明一个 AI 助手接口,并指定 chatModel 为 openAiChatModel。
 */
@AiService(
        wiringMode = AiServiceWiringMode.EXPLICIT, // 指定注入方式
        chatModel = "openAiChatModel", // 指定chatModel为OpenAiChatModel
        chatMemory = "chatMemory", // 指定上下文记忆
        tools = {"calculator"} // 指定自定义的工具
)
public interface Assistant {
    String chat(String userMessage);
}

4. Tools

java 复制代码
package org.ivy.aiservice.func;

import dev.langchain4j.agent.tool.Tool;
import org.springframework.stereotype.Component;

@Component
public class Calculator {

    @Tool("Calculates the length of a string")
    int stringLength(String s) {
        System.out.println("Called stringLength with s='" + s + "'");
        return s.length();
    }

    @Tool("Calculates the sum of two numbers")
    int add(int a, int b) {
        System.out.println("Called add with a=" + a + ", b=" + b);
        return a + b;
    }

    @Tool("Calculates the square root of a number")
    double sqrt(int x) {
        System.out.println("Called sqrt with x=" + x);
        return Math.sqrt(x);
    }
}

5. Controller

java 复制代码
package org.ivy.aiservice;

import org.ivy.aiservice.service.Assistant;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/hl")
@RestController
public class HighLevelChatController {
    private final Assistant assistant;

    public HighLevelChatController(Assistant assistant) {
        this.assistant = assistant;
    }

    @GetMapping("/chat")
    public String chat(
            @RequestParam(value = "prompt",
                    defaultValue = "What is the square root of the sum of the numbers of letters in the words "hello" and "world"?")
            String prompt) {
        return assistant.chat(prompt);
    }
}

6. 测试结果

借助工具完成复杂的任务处理。

示例代码

Github仓库 参照红框标注的代码即可

总结

先对LLM API 有个简单的认识,对于格式化输出、RAG以及连接多个服务都没有进行代码示例。先对整个有个感觉,后面会不断进行更新文章对每一部分都进行详细的分析和实战。

相关推荐
夜月行者10 分钟前
如何使用ssm实现民族大学创新学分管理系统分析与设计+vue
java·后端·ssm
白总Server20 分钟前
CNN+Transformer在自然语言处理中的具体应用
人工智能·神经网络·缓存·自然语言处理·rust·cnn·transformer
深度学习实战训练营24 分钟前
基于Keras的U-Net模型在图像分割与计数中的应用
人工智能·深度学习·keras
艾伦~耶格尔25 分钟前
IDEA 配置 Git 详解
java·ide·git·后端·intellij-idea
牛右刀薛面26 分钟前
launcher.py: error: the following arguments are required: --output_dir
llm·sft·llamafactory
篝火29 分钟前
MindSearch 部署到Github Codespace 和 Hugging Face Space
人工智能·python·github
白拾35 分钟前
使用Scikit-image进行图像处理入门
图像处理·人工智能
学习前端的小z37 分钟前
【AIGC】ChatGPT提示词解析:如何打造个人IP、CSDN爆款技术文案与高效教案设计
人工智能·chatgpt·aigc
小子不愁38 分钟前
PyTorch训练Celeba
人工智能·pytorch·python·celeba
customer0838 分钟前
【开源免费】基于SpringBoot+Vue.JS洗衣店订单管理系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源