【langchain4j】AIservices能够实现更加灵活的chain

文章目录

    • AI service介绍
      • 如何工作的
      • AiServices提供的能力
      • 支持的返回形式
    • 简单的例子:接收用户消息,并按规定返回
      • 接收单个变量
      • 接收更多动态变量
    • advanced RAG
    • Chaining multiple AI Services:多个AiSerives合并到一起
    • 相关教程:[LangChain4j AiServices Tutorial](https://www.sivalabs.in/langchain4j-ai-services-tutorial/)

AI service介绍

AI Service提供了比chain更加简单、灵活的能力

AI Services provide a simpler and more flexible alternative to chains.

langchain4j在# Introduction 也介绍了:

Chains:为每个常见用例建立一个链,例如聊天机器人、RAG 等。链组合了多个低级组件并协调它们之间的交互。它们的主要问题是,如果您需要定制某些东西,它们就太僵化了。 LangChain4j 仅实现了两个 Chain(ConversationalChain 和 ConversationalRetrievalChain)。

推荐使用AiService,而且langchain4j也不会开发更多的链

Represents a chain step that takes an input and produces an output. Chains are not going to be developed further, it is recommended to use AiServices instead.

如何工作的

AiServices提供了调用大模型的能力:将用户输入的信息转换为ChatMessage

[!NOTE]

  • 用户定义接口,AiServices转换这个接口
    You provide the Class of your interface to AiServices along with the low-level components, and AiServices creates a proxy object implementing this interface. Currently, it uses reflection, but we are considering alternatives as well. This proxy object handles all the conversions for inputs and outputs. In this case, the input is a single String, but we are using a ChatLanguageModel which takes ChatMessage as input.

  • 将用户的消息转换为UserMessage并调用的ChatLanguageModel
    So, AiService will automatically convert it into a UserMessage and invoke ChatLanguageModel. Since the output type of the chat method is a String, after ChatLanguageModel returns AiMessage, it will be converted into a String before being returned from the chat method.

 

AiServices提供的能力

参考代码:dev.langchain4j.service.AiServices

目前AiServices提供了以下能力:

message相关

  • message templates:Static system message templates, configured via @SystemMessage annotation on top of the method
    • system message templates:Dynamic system message templates, configured via systemMessageProvider(Function)
    • user message templates:Static user message templates, configured via @UserMessage annotation on top of the method
    • Dynamic user message templates, configured via method parameter annotated with @UserMessage

ChatMemory相关

  • Single (shared) ChatMemory, configured via chatMemory(ChatMemory)
  • Separate (per-user) ChatMemory, configured via chatMemoryProvider(ChatMemoryProvider) and a method parameter annotated with @MemoryId

RAG的能力

  • RAG, configured via contentRetriever(ContentRetriever) or retrievalAugmentor(RetrievalAugmentor)

相关工具

  • Tools, configured via tools(List) or tools(Object…) and methods annotated with @Tool

输出结构

  • Various method return types (output parsers), see more details below

返回流

  • Streaming (use TokenStream as a return type)

StructuredPrompt:ing结构化提示作为方法参数?

  • Structured prompts as method arguments (see @StructuredPrompt)

自动审核

  • Auto-moderation, configured via @Moderate annotation

注意暂不支持多模态

AI services currently do not support multimodality, please use the low-level API for this.

 

支持的返回形式

定义的接口返回形式是灵活的,可按需选择

  1. 直接回答:如果你想直接获取模型生成的文本,可以使用 StringAiMessage。这对于简单的对话或问题回答非常有用。
  2. 集合类型:如果你希望模型将回答作为一个有序集合返回,比如以列表或项目符号的形式列出多个项,可以使用 List<String>Set<String>
  3. 分类任务:如果你希望模型执行分类任务(比如判断文本的类别),你可以使用枚举类型(Enum)或布尔值(boolean)。这意味着模型会返回一个有限的类别集合或一个简单的真/假值。
  4. 数据提取:当你希望从模型的回答中提取特定数据时,可以使用基本类型(如 intDouble 等)或者 Java 的日期、时间和数字类型(如 DateLocalDateTimeBigDecimal 等)。例如,你可以从模型的回答中提取一个特定的数字或者日期。
  5. 自定义对象:如果你希望模型返回的结果是某个自定义的 Java 对象(POJO),你可以定义自己的 Java 类并让 LLM 将答案映射为这些对象。这对于需要结构化输出的场景非常有用。
  6. 访问额外信息(如令牌使用量):如果你希望不仅获取模型的核心输出,还希望获取额外的元数据(如令牌使用量、来源信息等),你可以使用 Result<T> 类型。在这种情况下,T 代表你想要的具体数据类型,比如 Result<String>Result<MyCustomPojo>
  7. JSON 模式:对于自定义 POJO,使用 JSON 格式来接收数据是一种常见做法。如果 LLM 支持 JSON 格式,OpenAI 模型支持通过设置 responseFormat("json_object") 来启用 JSON 模式,这使得从模型的响应中提取结构化数据更加容易。

简单的说,langchain4j会基于你定义的返回格式而返回,而不是像llm只返回markdown格式的内容。
这比langchain确实要灵活

 

简单的例子:接收用户消息,并按规定返回

接收单个变量

  1. 定义接口+注解(不同注解代表不同类型的消息)可以接收Prompt消息
  2. 返回值可由用户自定义的类型返回,如下表示了:用户定义了四种情绪,langchain4j根据用户的输入,基于大模型只返回对应的感情词。
//因为只有一个变量,不用使用注解定义接收的变量名
public class Test {  public static void main(String[] args) {  SentimentAnalyzer assistant = AiServices  .builder(SentimentAnalyzer.class)  .chatLanguageModel(  OpenAiChatModel.withApiKey(OPENAI_API_KEY)) // Deprecated it should use OpenAI LLM  .build();  Sentiment sentiment = assistant.analyzeSentimentOf("I love you"); //输出结果是用户自定义的枚举中的一个 System.out.println(sentiment); // POSITIVE  }  
}  enum Sentiment {  POSITIVE, NEUTRAL, NEGATIVE  
}  interface SentimentAnalyzer {  @UserMessage("Analyze sentiment of {{it}}")  Sentiment analyzeSentimentOf(String text);  
}

 

接收更多动态变量

接收两个变量需要通过注解来说明,文本(system、user的Prompt)中哪些变量被替换

/**
* 接收user和system的消息
* 动态接收language、text的值
*/
interface Translator {  @SystemMessage("You are a professional translator into {{language}}")  @UserMessage("Translate the following text: {{text}}")  String translate(@V("text") String text, @V("language") String language);  
}

了解了AiServices的基础使用,下面我们尝试一些RAG的能力
 

advanced RAG

提供如下能力:

  • QueryTransformer:转换查询
  • QueryRouter:路由查询
  • ContentRetriever:检索query
  • ContentAggregator:内容聚合
  • ContentInjector:内容注入

如下图展示了这些组件是如何配合构成一个复杂的chain
在这里插入图片描述

过程如下:

  1. 用户生成一个 UserMessage,该消息被转换为一个 Query。
  2. QueryTransformer 将 Query 转换为一个或多个 Query。
  3. 每个 Query 由 QueryRouter 路由到一个或多个 ContentRetriever。
  4. 每个 ContentRetriever 为每个 Query 检索相关的内容。
  5. ContentAggregator 将所有检索到的内容合并成一个最终的排序列表。
  6. 这个内容列表被注入到原始的 UserMessage 中。
  7. 最后,包含原始查询和注入的相关内容的 UserMessage 被发送到 LLM。

 

Chaining multiple AI Services:多个AiSerives合并到一起

AI Services可以与chain、LLM的if/elseswitchfor/while进行结合

[!NOTE]
AI Services can be used as and combined with regular (deterministic) software components:

  • You can call one AI Service after another (aka chaining).
  • You can use deterministic and LLM-powered if/else statements (AI Services can return a boolean).
  • You can use deterministic and LLM-powered switch statements (AI Services can return an enum).
  • You can use deterministic and LLM-powered for/while loops (AI Services can return int and other numerical types).
  • You can mock an AI Service (since it is an interface) in your unit tests.
  • You can integration test each AI Service in isolation.
  • You can evaluate and find the optimal parameters for each AI Service separately.

如下连接两个AiServices的例子:
基于大模型的返回,java判断如果是简单的问候则直接输出预知好的文字,AiServices:ChatBot。


//1.我们使用了成本较低的 **Llama2** 来完成判断文本是否为问候语的简单任务,而使用成本较高的 **GPT-4** 结合内容检索器(RAG)来处理更复杂的任务。
//2.可以分别对 **GreetingExpert** 和 **ChatBot** 进行评估,找到每个子任务的最优参数,或者从长远来看,甚至为每个特定子任务微调一个小型的专用模型。package com.qihoo.middle.nltosql.langchain4j.service;  import dev.langchain4j.service.AiServices;  
import dev.langchain4j.service.SystemMessage;  
import dev.langchain4j.service.UserMessage;  public class Test {  public static void main(String[] args) {  GreetingExpert greetingExpert = AiServices.create(GreetingExpert.class, llama2);  ChatBot chatBot = AiServices.builder(ChatBot.class)  .chatLanguageModel(gpt4)  .contentRetriever(milesOfSmilesContentRetriever)  .build();  MilesOfSmiles milesOfSmiles = new MilesOfSmiles(greetingExpert, chatBot);  String greeting = milesOfSmiles.handle("Hello");  System.out.println(greeting); // Greetings from Miles of Smiles! How can I make your day better?  String answer = milesOfSmiles.handle("Which services do you provide?");  System.out.println(answer); // At Miles of Smiles, we provide a wide range of services ...  }  
}  
interface GreetingExpert {  @UserMessage("Is the following text a greeting? Text: {{it}}")  boolean isGreeting(String text);  
}  interface ChatBot {  @SystemMessage("You are a polite chatbot of a company called Miles of Smiles.")  String reply(String userMessage);  
}  class MilesOfSmiles {  private final GreetingExpert greetingExpert;  private final ChatBot chatBot;  //通过java的逻辑来判断与大模型对话的意图。public String handle(String userMessage) {  if (greetingExpert.isGreeting(userMessage)) {  return "Greetings from Miles of Smiles! How can I make your day better?";  } else {  return chatBot.reply(userMessage);  }  }  
}

对于更复杂AiServices的交互逻辑,我们可以通过使用java的设计模型来串联起这些复杂的逻辑。

 

相关教程:LangChain4j AiServices Tutorial

  • LangChain4j AiServices Tutorial by Siva

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/61107.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【UGUI】背包的交互01(道具信息跟随鼠标+道具信息面板显示)

详细程序逻辑过程 初始化物品栏&#xff1a; 在 Awake 方法中&#xff0c;通过标签找到提示框和信息面板。 循环生成10个背包格子&#xff0c;并为每个格子设置图标和名称。 为每个格子添加 UInterMaager232 脚本&#xff0c;以便处理交互事件。 关闭提示框和信息面板&#…

同步互斥相关习题10道 附详解

PV操作 2016 某系统允许最多10个进程同时读文件F&#xff0c;当同时读文件F的进程不满10个时&#xff0c;欲读该文件的其他文件可立即读&#xff0c;当已有10个进程在读文件F时读&#xff0c;其他欲读文件F的进程必须等待&#xff0c;直至有进程读完后退出方可去读 在实现管…

Postman之数据提取

Postman之数据提取 1. 提取请求头\request中的数据2. 提取响应消息\response中的数据3. 通过正在表达式提取4. 提取cookies数据 本文主要讲解利用pm对象对数据进行提取操作&#xff0c;虽然postman工具的页面上也提供了一部分的例子&#xff0c;但是实际使用时不是很全面&#…

【专题】数据库原理与应用之故障恢复

1. 数据库故障恢复概述 数据库的可恢复性&#xff1a; DBMS能把数据库从被破坏、不正确的状态、恢复到最近一个正确的状态。 恢复管理任务的种类&#xff1a; 一是在未发生故障而系统正常运行时&#xff0c;采取一些必要措施为恢复工作打基础。 二是在发生故障后进行恢复处…

EXCEL 或 WPS 列下划线转驼峰

使用场景&#xff1a; 需要将下划线转驼峰&#xff0c;直接在excel或wps中第一行使用公式&#xff0c;然后快速刷整个列格式即可。全列工下划线转为格式&#xff0c;使用效果如下&#xff1a; 操作步骤&#xff1a; 第一步&#xff1a;在需要显示驼峰的一列&#xff0c;复制以…

MODBUS TCP转CANOpen网关

Modbus TCP转CANopen网关 型号&#xff1a;SG-TCP-COE-210 产品用途 本网关可以实现将CANOpen接口设备连接到MODBUS TCP网络中&#xff1b;并且用户不需要了解具体的CANOpen和Modbus TCP 协议即可实现将CANOpen设备挂载到MODBUS TCP接口的 PLC上&#xff0c;并和CANOpen设备…

分布式----Ceph部署

目录 一、存储基础 1.1 单机存储设备 1.2 单机存储的问题 1.3 商业存储解决方案 1.4 分布式存储&#xff08;软件定义的存储 SDS&#xff09; 1.5 分布式存储的类型 二、Ceph 简介 三、Ceph 优势 四、Ceph 架构 五、Ceph 核心组件 #Pool中数据保存方式支持两种类型&…

自动驾驶系列—面向自动驾驶的模型迭代:工具、平台与最佳实践

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

Spring Boot3自定义starter

1、加入必要依赖 plugins {id javaid org.springframework.boot version 3.2.6id io.spring.dependency-management version 1.1.5 } group org.example.test.starter version 1.1.0jar{enabledtrue// resolveMainClassName }java {toolchain {languageVersion JavaLanguage…

AI开发-计算机视觉库-OpenCV

1 需求 官网&#xff1a;OpenCV - Open Computer Vision Library 2 接口 3 示例 import cv2image cv2.imread("./data/train/1_1.jpg") print(type(image)) 4 参考资料

delphi fmx android 离线人脸识别

搜遍全网都没有找到delphi android 能用的 离线人脸识别,无需注册什么开发者 有这方面需求的可以用fsdk 这边用的luxand.FSDK8.0 android下的注册号要自己找下 1,用老猫的工具将android 下的sdk,FSDK.java 编译成FSDK.jar 老猫的工具 2,用上面的工具将FSDK.jar 生成de…

RabbitMQ教程:工作队列(Work Queues)(二)

RabbitMQ教程&#xff1a;工作队列&#xff08;Work Queues&#xff09;&#xff08;二&#xff09; 一、引言 在快节奏的软件开发世界中&#xff0c;我们经常面临需要异步处理任务的场景&#xff0c;比如在Web应用中处理耗时的图片处理或数据分析任务。这些任务如果直接在用…

乐维网管平台(七):网络稳定与高效的“安全锦囊”

试想一下&#xff0c;你给电脑升级了一个软件&#xff0c;升级完成后发现有BUG&#xff0c;经常无故卡死&#xff0c;这时候想回退或重新安装旧版本…相对地&#xff0c;一家企业的网络管理员&#xff0c;在对公司的核心交换机进行复杂的配置调整时&#xff0c;一个小小的疏忽&…

时代变迁对传统机器人等方向课程的巨大撕裂

2020年之后&#xff0c;全面转型新质课程规划&#xff0c;传统课程规划全部转为经验。 农耕-代表性生产关系-封建分配制度主要生产力-人力工业-代表性生产关系-资本分配制度工业分为机械时代&#xff0c;电气时代&#xff0c;信息时代&#xff1b;主要生产力-人力转为人脑&…

Spring6 AOP 面向切面编程

1. 概念 面向切面编程&#xff1a;一种编程思想。proxy动态代理&#xff08;实现了这种思想&#xff09;&#xff1a;在原方法执行时&#xff0c;给原方法的前面或着后面增加其他的方法。增加的方法并不会写在原方法中 原方法就是目标方法&#xff0c;增加的方法就是代理方法 …

计算机组成与原理(2) basic of computer architecture

Instruction Set Architecture (ISA) 和 Hardware System Architecture (HSA) 是计算机体系结构中两个重要的层次&#xff0c;它们各自的职责和作用如下&#xff1a; Instruction Set Architecture (ISA) 定义 ISA是指令集体系结构&#xff0c;是硬件和软件之间的接口。它定义…

window的wsl(Ubuntu)安装kafka步骤

环境&#xff1a;Win11 WSL(Linux子系统Ubuntu) apache-zookeeper-3.9.3-bin kafka_2.12-3.8.1 思路&#xff1a;apache上分别下载zookeeper和kafka&#xff0c;在wsl环境安装。在kafka上创建消息的topic&#xff0c;发送消息&#xff0c;接受消息&#xff0c;验证是否安…

数据结构树和二叉树知识点和递归序列

二叉树知识点 一.树的概念1.1关于树的名词解释 二.二叉树的概念1. 二叉树性质&#xff1a; 三.满二叉树与完全二叉树递归前序遍历递归中序遍历递归后续遍历 一.树的概念 树是一种非线性数据结构&#xff0c;它是由n个或大于n个的结点来组成具有层次关系的一个集合&#xff08;…

速通前端篇 —— CSS

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;速通前端 目录 CSS的介绍 基本语法规范 CSS选择器 标签选择器 class选择器 id选择器 复合选择器 通配符选择器 CSS常见样式 颜…

使用 Elastic 3 步实现基于 OTel 的原生 K8s 和应用可观测性

作者&#xff1a;来自 Elastic Bahubali Shetti Elastic 的 OpenTelemetry 发行版现已支持 OTel Operator&#xff0c;可使用 EDOT SDK 自动检测应用程序&#xff0c;并管理 EDOT OTel Collector 的部署和生命周期以实现 Kubernetes 可观察性。了解如何通过 3 个简单步骤进行配…