【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.xdnf.cn/news/19048.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

JavaScript 中字符串和数组的概念解析与多角度对比区分

文章目录 &#x1f4af;前言&#x1f4af;字符串&#xff08;String&#xff09;&#x1f4af;数组&#xff08;Array&#xff09;&#x1f4af;字符串与数组的相同点与不同点&#x1f4af;字符串和数组的实际应用场景&#x1f4af;字符串与数组的互转&#x1f4af;字符串和数组…

4K双模MiniLED显示器哪个好

4K双模MiniLED显示器哪个好&#xff1f;现在市面上的4K双模MiniLED显示器太多了&#xff0c;琳琅满目&#xff0c;今天就给大家列举一下7款当下火热到爆炸的品牌&#xff0c;看看4K双模MiniLED显示器哪个好。 4K双模MiniLED显示器哪个好 - HKC G27M7PRO HKC G27M7Pro 是一款性…

每天五分钟深度学习pytorch:批归一化全连接网络完成手写字体识别

本文重点 前面我们学习了普通的全连接神经网络,后面我们学习了带有激活层的全连接神经网络,本文我们继续进一步升级,我们学习带有批归一化的全连接神经网络,批归一化可以加快神经网络的训练速度,减少过拟合,具体它的原理,大家可以看我们的《每天五分钟深度学习》专栏,…

excel打开csv文件乱码的问题

如图所示&#xff0c;在保存csv文件时已指定编码为utf-8&#xff0c;用excel打开后仍然乱码 解决方法&#xff1a; 在保存csv文件时指定编码为utf-8-sig 该编码方式会在文件开头加入一个 BOM&#xff08;Byte Order Mark&#xff09;&#xff0c;有助于 Excel 正确识别 UTF-8…

QQ音乐 11.3.4 | 魅族定制版,极致简洁,无广告,不限机型

QQ音乐魅族定制版&#xff0c;界面设计极致简洁&#xff0c;没有任何广告干扰&#xff0c;支持听限免歌曲&#xff0c;不限机型使用。用户可以通过微信和QQ直接登录&#xff0c;享受纯净的音乐体验。 大小&#xff1a;94.6M 下载地址&#xff1a; 百度网盘&#xff1a;https:…

使用TensorFlow实现简化版 GoogLeNet 模型进行 MNIST 图像分类

在本文中&#xff0c;我们将使用 TensorFlow 和 Keras 实现一个简化版的 GoogLeNet 模型来进行 MNIST 数据集的手写数字分类任务。GoogLeNet 采用了 Inception 模块&#xff0c;这使得它在处理图像数据时能更高效地提取特征。本教程将详细介绍如何在 MNIST 数据集上训练和测试这…

TON商城与Telegram App:生态融合与去中心化未来的精彩碰撞

随着区块链技术的快速发展&#xff0c;去中心化应用&#xff08;DApp&#xff09;逐渐成为了数字生态的重要组成部分。而Telegram作为全球领先的即时通讯应用&#xff0c;不仅仅满足于传统的社交功能&#xff0c;更在区块链领域大胆探索&#xff0c;推出了基于其去中心化网络的…

vulhub之log4j

Apache Log4j Server 反序列化命令执行漏洞(CVE-2017-5645) 漏洞简介 Apache Log4j是一个用于Java的日志记录库,其支持启动远程日志服务器。Apache Log4j 2.8.2之前的2.x版本中存在安全漏洞。攻击者可利用该漏洞执行任意代码。 Apache Log4j 在应用程序中添加日志记录最…

web服务nginx实验4:访问控制

4-1&#xff1a;基于不同用户的访问控制&#xff1a; 安装软件&#xff1a; 创建HTTP基本认证用户密码文件&#xff0c;tom&#xff0c;密码&#xff1a;1&#xff0c;lisa&#xff0c;密码&#xff1a;1&#xff1a; -c&#xff1a;表示创建一个新的密码文件。如果该文件已经…

基于FastAPI实现本地大模型API封装调用

关于FastAPI FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Python Web 框架&#xff0c;用于构建基于标准 Python 类型提示的 API。它以简洁、直观和高效的方式提供工具&#xff0c;特别适合开发现代 web 服务和后端应用程序。 问题&#xff1a;_pad() got an un…

数字化点亮库布其沙漠的绿色梦想

Bentley 应用程序助力提升设计和施工效率&#xff0c;提前六周交付设计成果 清洁能源为沙漠带来新活力 库布其光伏治沙项目&#xff08;以下简称“该项目”&#xff09;位于内蒙古鄂尔多斯市库布其沙漠&#xff0c;占地约 10 万亩&#xff0c;是中国单体规模最大的光伏治沙项目…

基于单片机的风能太阳能供电的路灯智能控制系统设计(论文+源码)

1系统总体设计 本课题为风能太阳能供电的路灯智能控制系统设计&#xff0c;系统的主要功能设计如下&#xff1a; &#xff08;1&#xff09; 供电模块&#xff1a;采用太阳能板以及风机模拟风扇充电&#xff0c;经过充电电路给锂电池进行充电。再由锂电池给照明模块以及整个项…

Linux Centos7 Rocky网卡配置

目录 1.Vmare 虚拟机配置 &#xff08;1&#xff09;打开虚拟机输入ip a&#xff0c;查看ip网段&#xff0c;若为192.168.81.135 &#xff08;2&#xff09;在Vmare上的虚拟网络配置器配置 &#xff08;3&#xff09;确保电脑有VMnet1 VMnet8 2.Linux虚拟机Centos配置 &#…

MySQL索引原理之查询优化

MySQL索引原理之查询优化 1、慢查询定位 开启慢查询日志 查看 MySQL 数据库是否开启了慢查询日志和慢查询日志文件的存储位置的命令如下&#xff1a; SHOW VARIABLES LIKE %slow_query_log%通过如下命令开启慢查询日志&#xff1a; SET global slow_query_log 1; SET global …

ArchGuard 架构分析器发布:多语言、跨项目架构数据生成,助力 AI 时代知识挖掘...

TL;DR&#xff1a;https://github.com/archguard/archguard 过去的几个月里&#xff0c;我们一直在探索用 AI 辅助跨项目、跨大量微服务的系统的开发。其中一个重要的话题就是&#xff0c;从现有的软件架构去生成知识&#xff0c;文档是落后、多版本的&#xff0c; 只有代码才保…

NLP论文速读(多伦多大学)|利用人类偏好校准来调整机器翻译的元指标

论文速读|MetaMetrics-MT: Tuning Meta-Metrics for Machine Translation via Human Preference Calibration 论文信息&#xff1a; 简介&#xff1a; 本文的背景是机器翻译&#xff08;MT&#xff09;任务的评估。在机器翻译领域&#xff0c;由于不同场景和语言对的需求差异&a…

工程车识别算法平台LiteAIServer算法定制工程车类型检测算法:建筑工地安全管理的得力助手

随着科技的飞速发展&#xff0c;智能化技术正在逐步改变我们的生活方式&#xff0c;特别是在交通管理和安全管理领域。其中&#xff0c;算法定制LiteAIServer工程车类型检测算法以其高效、准确和实时的特性&#xff0c;成为了建筑工地管理、矿山开采以及物流运输等多个领域的重…

机器学习2

三、特征工程 接机器学习1 4、特征降维 4.2、主成分分析PCA 从原始特征空间中找到一个新的坐标系统&#xff0c;使得数据在新坐标轴上的投影能够最大程度地保留数据的方差&#xff0c;同时减少数据的维度。 保留信息/丢失信息信息保留的比例 from sklearn.decomposition imp…

【Linux之权限】提升篇

前言 在前两篇文章里&#xff0c;我们已经学习了Linux中权限的理论、实践和重点&#xff0c;接下来我们将进一步提升对Linux权限的全面认知。虽是拓展&#xff0c;其实还是重点。 本文内容并不多&#xff0c;那我们就开始吧。 目录的权限该如何理解呢&#xff1f; 如果我想进…

亮数据结合AI大模型,实现数据自由

目录 一、获取网络数据的挑战1、反爬虫机制的威胁2、IP封锁与访问频率控制3、数据隐私与法律合规 二、亮数据动态代理&#xff1a;数据采集的最佳拍档1、高质量IP资源2、智能调度与自动切换3、合规与隐私保护4、多场景应用支持 三、使用亮数据代理 IP进行网络数据抓取1、引入 r…