JAVA用框架SpringAI实现人工智能(二)openAi 聊天的实现

Spring AI 核心功能

一、对话模型
1、对话模型概念
Chat Completion API 帮助开发人员轻松将 AI 聊天完成功能融入应用程序。它利用预训练的语言模型,如 GPT(Generative pre-trained Transformer),以自然语言生成对用户输入的类人响应。

		 API 通常通过向人工智能模型发送提示或部分对话来工作,人工智能模型会依据其训练数据和自然语言模式理解,生成对话。然后将完成的响应返回给应用程序,应用程序可以将其呈现给用户或用于进一步处理。
		![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/837bf46333694b0cb0034e5fe15d1e65.png#pic_center)

   
	2、call 和 stream 方法分表对应大模型的两种输出方式:

		a、非流式输出 call:等待大模型把回答结果全部生成后输出给用户;
		
		b、流式输出 stream:逐个字符输出,一方面符合大模型生成方式的本质,另一方面当模型推理效率不是很高时,流式输出比起全部生成后再输出大大提高用户体验。
package com.cesske.demo.controller;

import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import reactor.core.publisher.Flux;

import javax.annotation.Resource;

/**
 * openAi 聊天的实现
 */
public class ChatController {

    /**
     * 自动注入的
     */
    @Resource
    private OpenAiChatModel openAiChatModel;

    /**
     * 聊天的方法。底层调用的openAi的方法
     * RequestParam 接受参数
     * msg 就是我们提的问题
     *
     * @return
     */
    @RequestMapping("/ai/chat")
    public String chat(@RequestParam("msg") String msg) {
        String called = openAiChatModel.call(msg);
        return called;
    }
    /**
     * 聊天的方法。底层调用的openAi的方法
     * RequestParam 接受参数
     * msg 就是我们提的问题
     * ChatResponse 返回的是一个josn串
     * chatResponse.getResult().getOutput().getContent();只获取文本
     * @return
     */

    @RequestMapping("/ai/chat2")
    public Object chat2(@RequestParam("msg") String msg){
        ChatResponse chatResponse = openAiChatModel.call(new Prompt(msg));
        return chatResponse.getResult().getOutput().getContent();
    }

    /**
     *OpenAiChatOptions.builder() 传入的一个参数,可以控制大模型的设置
     * @param msg
     * @return
     */

    @RequestMapping("/ai/chat3")
    public Object chat3(@RequestParam("msg") String msg){
        ChatResponse chatResponse = openAiChatModel.call(new Prompt(msg, OpenAiChatOptions.builder()
                //.withModel("gpt-4-32k")  //gpt的版本 ,32K是参数,参数越高,回答问题越准确
                .withTemperature(0.4F)  //温度值,温度越高,回答的准确率越低,温度越低,回答的准确率越高
                .build()));
        return chatResponse.getResult().getOutput().getContent();
    }

    /**
     *OpenAiChatOptions.builder() gpt的可选参数
     * @param msg
     * @return
     */
    @RequestMapping("/ai/chat4")
    public Object chat4(@RequestParam("msg") String msg){
        Flux<ChatResponse> flux = openAiChatModel.stream(new Prompt(msg, OpenAiChatOptions.builder()
                //.withModel("gpt-4-32k")  //gpt的版本 ,32K是参数,参数越高,回答问题越准确
                .withTemperature(0.4F)  //温度值,温度越高,回答的准确率越低,温度越低,回答的准确率越高
                .build()));
        return flux.collectList();
    }
}

二、提示词模板
1、提示词是引导大模型生成特定输出的输入,提示词的设计和措辞会极大地影响模型的响应结果。

		[推荐当前受欢迎的5中开发语言] 就是一个最简单的提示词。在 AI 领域,提示的结构随着时间的推移不断发展,最初的提示只是简单的字符串,随着时间的推移,提示词开始包含特定输入的占位符,例如 "USER:"、"ASSISTANT" 这些,大模型可以识别这些占位符,并给出更符合用户需求的内容输出。

		OpenAI 后来引入了一种更具条理的方法。在他们的模型中,提示不再仅仅是简单的文本字符串,而是由一系列带有特定角色的消息构成。尽管每条消息依然是文本形式,但它们各自被赋予了明确的角色。这些角色不仅帮助分类消息,还进一步澄清了大模型提示词中每个部分的上下文和目的。这种结构化的方法极大地提升了与大模型沟通的准确性和效率,因为提示词中的每个元素在都承载着独特且清晰的功能。

		下面是一个带有角色信息的 prompt 示例,可以看到 prompt 是包括对话的上下文,可以让模型更好的理解用户的意图。
{"role":"user","content":"你好"},
{"role":"assistant","content":"你好,请问有什么我可以帮助你的吗?无论你有什么问题或需要帮助,我都会尽力回答和协助你。请随时告诉我你的需求。"},
{"role":"user","content": "我在上海,周末可以去哪里玩?"},
{"role":"assistant","content": "上海是一个充满活力和文化氛围的城市,有很多适合周末游玩的地方。以下是几个值得推荐的地方:\n\n1. 上海科技馆:上海科技馆是中国大陆最大的科技馆之一,有许多互动展览和科学实验室,可以让您了解科技的发展历史和最新成果。\n2. 上海博物馆:上海博物馆是一座集艺术、历史和文化于一体的博物馆,有许多精美的艺术品和文物,可以让您深入了解中国和世界的文化历史。\n3. 外滩:外滩是上海的标志性景点之一,有许多高楼大厦和繁华的商业街区,是欣赏黄浦江美景和城市风貌的好去处。\n4. 上海迪士尼乐园:上海迪士尼乐园是世界上最大的迪士尼主题公园之一,有许多精彩的游乐项目和演出,可以让您尽情享受娱乐和欢乐。\n5. 上海野生动物园:上海野生动物园是一个以自然保护为主题的野生动物园,有许多珍稀动物和植物,可以让您近距离接触大自然。\n\n这些地方都是上海周末游玩的好去处,可以根据自己的兴趣和需求选择合适的行程。"},
{"role":"user","content": "上海有哪些美食"}

Spring AI 适配了主流大模型,有不同的角色供使用:
在这里插入图片描述
在 Spring AI 代码中对应不同的枚举值:

public enum MessageType {

    USER("user"),

    ASSISTANT("assistant"),

    SYSTEM("system"),

    FUNCTION("function");
}
 2、提示词模板
 在 Spring AI 与大模型交互的过程中,处理提示词的方式与 Spring MVC 中管理 “视图 View” 的方式有些相似。首先要创建包含动态内容占位符的模板,然后,这些占位符会根据用户请求或应用程序中的其他代码进行替换。另一个类比是 JdbcTemplate 中的语句,它包含可动态替换的占位符。

下面是一个使用提示词模板的简单例子,在提示词模板中,{占位符} 可以用 Map 中的变量动态替换。

PromptTemplate promptTemplate = new PromptTemplate(“Tell me a {adjective} joke about {topic}”);
Prompt prompt = promptTemplate.create(Map.of(“adjective”, adjective, “topic”, topic));
return chatClient.call(prompt).getResult();

3、示例

@RequestMapping("/ai/prompt")
    public Response prompt(@RequestParam(value = "name") String name,
                           @RequestParam(value = "voice") String voice) {
        String userText = "给我推荐上海的至少三个旅游景点";

        UserMessage userMessage = new UserMessage(userText);

        String systemText = "你是一个有用的人工智能助手,可以帮助人们查找信息,\n" +
                "        你的名字是{name},\n" +
                "        你应该用你的名字和{voice}的风格回复用户的请求。";

        SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemText);
        Map<String, Object>  map = new HashMap<>();
        map.put("name",name);
        map.put("voice", voice);
        Message systemMessage = systemPromptTemplate.createMessage(map);
        List<Message> msg = new ArrayList<>();
        msg.add(userMessage);
        msg.add(systemMessage);
        Prompt prompt = new Prompt(msg);
        List<Generation> response = openAiChatModel.call(prompt).getResults();
        StringBuilder result = new StringBuilder();
        for (Generation generation : response) {
            String content = generation.getOutput().getContent();
            result.append(content);
        }
        return Response.ok(result);
    }

调用示例:

localhost:8080/ai/prompt?name=小二&voice=幽默

{
"errno": 0,
"msg": "success",
"data": "嘿,我是小二!上海是一个充满魅力的城市,有很多值得一游的景点。我给你推荐三个:\n\n1. 东方明珠塔:作为上海的标志性建筑,东方明珠塔是上海的地标之一。你可以乘坐电梯到达塔顶,欣赏整个上海城市的美景。\n\n2. 外滩:外滩是上海最著名的观光区之一,这里有许多欧洲风格的建筑,可以欣赏到黄浦江两岸的美景,尤其在夜晚灯火辉煌。\n\n3. 田子坊:这里是上海的老街区,保留了许多传统的建筑和文化。你可以在这里漫步,感受上海的历史和文化氛围。\n\n希望你能在上海玩得开心!如果还有其他问题,随时问我哦~"
}
  • 12
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cesske

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值