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以及连接多个服务都没有进行代码示例。先对整个有个感觉,后面会不断进行更新文章对每一部分都进行详细的分析和实战。

相关推荐
诚威_lol_中大努力中10 分钟前
关于VQ-GAN利用滑动窗口生成 高清图像
人工智能·神经网络·生成对抗网络
Q_192849990619 分钟前
基于Spring Boot的个人健康管理系统
java·spring boot·后端
liutaiyi819 分钟前
Redis可视化工具 RDM mac安装使用
redis·后端·macos
Q_192849990626 分钟前
基于Springcloud的智能社区服务系统
后端·spring·spring cloud
xiaocaibao77729 分钟前
Java语言的网络编程
开发语言·后端·golang
中关村科金30 分钟前
中关村科金智能客服机器人如何解决客户个性化需求与标准化服务之间的矛盾?
人工智能·机器人·在线客服·智能客服机器人·中关村科金
逸_33 分钟前
Product Hunt 今日热榜 | 2024-12-25
人工智能
Luke Ewin39 分钟前
基于3D-Speaker进行区分说话人项目搭建过程报错记录 | 通话录音说话人区分以及语音识别 | 声纹识别以及语音识别 | pyannote-audio
人工智能·语音识别·声纹识别·通话录音区分说话人
DashVector1 小时前
如何通过HTTP API检索Doc
数据库·人工智能·http·阿里云·数据库开发·向量检索
说私域1 小时前
无人零售及开源 AI 智能名片 S2B2C 商城小程序的深度剖析
人工智能·小程序·零售