当前位置: 首页 > news >正文

01、聊天与语言模型

一、简单说明模型

LLM目前有两种API提供

  • LanguageModel:接收一个a作为输入并返回一个b作为输出,这种是已经过时的
  • ChatLanguageModel:接收多个输入,然后返回相应的输出

ChatLanguaggeModel是LangChain4j中LLM交互低级API,它提供了最大的功能和灵活性。除此之外还有一个高级API(AIService)。

ChatLanguageModel还支持的模型有:

  • EmbeddingModel:把文本转换为Embedding
  • ImageModel:用来生成和编辑图片
  • ModerationModel:这个模型可以检查文本中是否包含有害内容
  • ScoringModel:可以根据查询对多段文本进行评分(排名),实际上就是用来确定每段文本与查询的关联性,这个对于RAG来说是非常有用的

二、ChatLanguageModel的API

ChatLanguageModel是一个接口,其定义如下:

public interface ChatLanguageModel {

  
    default String generate(String userMessage) {
        return generate(UserMessage.from(userMessage)).content().text();
    }

    
    default Response<AiMessage> generate(ChatMessage... messages) {
        return generate(asList(messages));
    }

    
    Response<AiMessage> generate(List<ChatMessage> messages);

    
    default Response<AiMessage> generate(List<ChatMessage> messages, List<ToolSpecification> toolSpecifications) {
        throw new IllegalArgumentException("Tools are currently not supported by this model");
    }

   
    default Response<AiMessage> generate(List<ChatMessage> messages, ToolSpecification toolSpecification) {
        throw new IllegalArgumentException("Tools are currently not supported by this model");
    }

    @Experimental
    default ChatResponse chat(ChatRequest request) {
        throw new UnsupportedOperationException();
    }

    @Experimental
    default Set<Capability> supportedCapabilities() {
        return emptySet();
    }
}

注意:现在我们看的是关于LangChain4j 0.36.2版本!!

三、关于ChatMessage

这个表示是一个聊天消息,当前有四种类型的聊天消息,每种消息的“来源”对应其中一种

  1. UserMessage:来自己于用户的消息,这里指的用户可以是应用使用的最终用户或者是应用本身,它是相对于LLM大语言模型来说的
  2. AiMessage:由AI生成的消息,通常是为了响应
  3. ToolExecutionResultMessage:聊天过程中执行相关的工具(函数)的结果
  4. SystemMessage:来自己系统的消息,通常用来定义LLM在对话中的角色说明(指定AI应该如何表现以及以何种方式回答...)
  5. CustomMessage:可以包含任意属性的自定义消息,这种消息不是所有的大模型语言都支持,只有支持它的才可以使用

使用多个ChatMessage

我们看到接口中方法定义为什么我们要使用多个ChatMessage?

注意:我们在于LLM进行聊天对话时,它本质上是无状态的,它们是不会维护对话状态的,如果要支持多论对话并且让AI理解对话的上下文,那么就需要使用到多个ChatMessage。因为这个时候我们就需要把多论对话中的所有聊天消息告诉AI,让它了解整个上下文的情况,从而达到一个有状态的假象。

如下所示:

UserMessage firstUserMessage = UserMessage.from("你好,我叫鹏鹏");
AiMessage firstAiMessage = model.generate(firstUserMessage).content();
UserMessage secondUserMessage = UserMessage.from("我叫什么名字?");
AiMessage secondAiMessage = model.generate(firstUserMessage,firstAiMessage,SecondUserMessage).content();

向上面这样手动去维护与管理这些消息是很麻烦的,实际的使用中我们会使用ChatMemory(先了解后续会说)

关于UserMessage

在UserMessage这个类中我们可以看到下面这个方法:

public static UserMessage userMessage(Content... contents) {
    return from(contents);
}

这个方法可以传入多个Content,最终得到一个UserMessage对象

而Content是一个接口,它有如下一些实现(不同的实现可以传入不同类型的内容)

  • TextContent
  • ImageContent
  • AudioContent
  • VideoContent
  • PdfFileContent

通过这些不同的Content我们就可以把不同类型的内容转为UserMessage,然后传给LLM,如下所示:

UserMessage userMessage = UserMessage.from(
	TextContent.from("请描述下面的图片信息"),
    ImageContent.from("https://ex.com/myCat.png")
);
Response<AiMessage> response = model.generate(userMessage);
TextContent

它是最为简单的一种,就是把一个普通的文本转为一个字符串

UserMessage.from(TextContent.from("Hello")) 与 UserMessage.from("Hello")这两者没有任何区别。

一次可以向UserMessage当中提供一个或多个TextContent

UserMessage userMessage = UserMessage.from(TextContext.from("Hello"),
                                          TextContext.from("你好啊!"));
ImageContent

根据不同的LLM提供商,ImageContent可以从URL地址或者Base64的二进制数据来提供ImageContent

如下所示,使用Base64的二进数据来提供ImageContent

byte[] imageBytes = readBytes("D:\\myImage\\hi.png");
String imgData = Base64.getEncoder().encodeToString(imageBytes);
ImageContent imageContent = ImageContent.from(imgData,"image/png");
UserMessage userMessage = UserMessage.from(imageContent);
AudioContent

它类似于ImageContent,它表示的是音频内容

VideoContent

它类似于ImageContent,它表示的是视频内容

PdfFileContent

它类似于ImageContent,表示的是PDF文件的二进制内容

四、实践示例

POM依赖

<dependencies>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j-dashscope-spring-boot-starter</artifactId>
        <!-- 添加排除项 -->
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-simple</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <!-- lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>

    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j</artifactId>
    </dependency>
</dependencies>

其中SpringBoot指定版本为:3.3.5,langchain4j指定版本为0.36.2

yml配置

langchain4j:
  dashscope:
    chat-model:
      api-key: sk-09a****************3686d6c4cfb
      #model-name: deepseek-v3
      model-name: qwen-max-latest

chat:
  systemMessage: 你是普京,接下来以普京的语气来进行对话

其中aipkey是在阿里百炼平台申请的aipkey,这里要使用时需要替换为自已申请好的apikey

主启动

@SpringBootApplication
public class ChatApplication {

    public static void main(String[] args) {
        SpringApplication.run(ChatApplication.class, args);
    }
}

controller

@Slf4j
@RestController
@RequestMapping("/chat")
public class ChatController {

    // 注入聊天大语言模型
    @Resource
    private ChatLanguageModel chatLanguageModel;

    @Value("${chat.systemMessage}")
    private String systemMessage;


    @GetMapping("/simple")
    public String chat(@RequestParam("message") String message) {
        UserMessage userMessage = UserMessage.from(message);
        Response<AiMessage> generate = chatLanguageModel.generate(userMessage);
        log.info("generate: {}", generate);
        return generate.content().text();
    }

    @GetMapping("/sys/simple")
    public String chatSys(@RequestParam("message") String message) {
        Response<AiMessage> aiResponse;
        UserMessage userMessage = UserMessage.from(message);
        if (systemMessage != null && !systemMessage.isEmpty()) {
            SystemMessage systemMessage = SystemMessage.from(this.systemMessage);
            aiResponse = chatLanguageModel.generate(List.of(systemMessage, userMessage));
        } else {
            aiResponse = chatLanguageModel.generate(userMessage);
        }
        if (aiResponse == null) {
            return "大模型未返回任何内容~~~";
        }
        log.info("generate: {}", aiResponse);
        return aiResponse.content().text();
    }
}

这其中有两个不同的请求,一个是简单的聊天请求,另一个是我们指定了特定的SystemMessage的请求。

相关文章:

  • [python]IsaacGym安装
  • 多线程编程
  • Android应用退出后不在任务栏显示
  • 如何做好需求管理培训
  • Rk3588,Opencv读取Gmsl相机,Rga yuv422转换rgb (降低CPU使用率)
  • 2.1.1~2词法分析的手工构造
  • 判断一个操作是不是允许
  • 3.23学习总结
  • 运筹优化梳理
  • [M模拟] lc2116. 判断一个括号字符串是否有效(思维+括号匹配问题+问题分析+代码实现)
  • 交换机远程登录
  • 基于Python的智慧金融风控系统的设计与实现
  • 银河麒麟桌面版包管理器(五)
  • 计算机操作系统(五) 前趋图和程序执行与进程的描述(附带图谱表格更好对比理解))
  • MySQL 死锁问题分析与解决方案
  • 机房布局和布线的最佳实践:如何打造高效、安全的机房环境
  • fopen和open 等区别是什么?文件描述符与文件描述指针区别
  • 如何防御大模型中的 Prompt 攻击?
  • 跨境电商独立站B端站与C端站有什么不同
  • stress-ng命令详解
  • 北方首场高温将进入鼎盛阶段,江南华南多地需警惕降雨叠加致灾
  • 解锁儿时愿望!潘展乐战胜孙杨,全国冠军赛男子400自夺冠
  • 遭车祸罹难的村医遇“身份”难题:镇卫生院否认劳动关系,家属上诉后二审将开庭
  • 本周看啥|《歌手》今晚全开麦直播,谁能斩获第一名?
  • 俄乌官员即将在土耳其会谈,外交部:支持俄乌开启直接对话
  • 魔都眼|锦江乐园摩天轮“换代”开拆,新摩天轮暂定118米