SpringAI使用总结

基本使用

ChatModel和ChatClient

SpringAi支持非常多的模型,为了统一处理,SpringAi声明了ChatModel接口,各个模型的starter中有ChatModel对应的实现。

当我们引入ollama的依赖后

        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-ollama</artifactId>
        </dependency>

可以在程序中搜索到OllamaChatModel在这里插入图片描述

ChatClient是获取与模型进行对话获取响应的入口,需要给ChatClient提供ChatModel,ChatClient也是一个接口,不过SpringAi提供了默认的实现。
在这里插入图片描述
在这里插入图片描述

简单对话

这里调用的是本地的ollama中的模型,需要提前下载对应的模型。当然也可以通过api key调用远程的模型服务。

1、引入ollama starter依赖

        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-ollama</artifactId>
        </dependency>

2、配置

spring:
  ai:
    ollama:
      base-url: http://localhost:11434
      chat:
        model: deepseek-r1:14b

3、创建ChatClient

@Configuration
public class MyAiConfig {
    
    
    @Bean
    public ChatClient chatClient(ChatModel chatModel) {
        return ChatClient.builder(chatModel).build();
    }
    
}

4、对话controller编写

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



    @Autowired
    private ChatClient chatClient;


    @GetMapping("/chat1")
    public String chat(@RequestParam String message) {
        return chatClient.prompt(message).call().content();
    }
}

5、测试结果,可以看到模型输出了响应。
在这里插入图片描述

流式输出

由于大模型生成响应可能比较慢,为了提高用户体验,所以出现了流式输出,即不等待大模型回答完成后,把输出一次性传输到客户端,而是将输出不断地传输到客户端。

    @GetMapping("/chat2")
    public Flux<String> chat1(@RequestParam String message) {
        return chatClient.prompt().user(message).stream().content();
    }

预设角色

在创建ChatClient的时候,可以给模型设置角色,这样模型会按照设置的角色来回答问题。
通过defaultSystem方法预设角色。

    @Bean
    public ChatClient chatClient(ChatModel chatModel) {
        return ChatClient.builder(chatModel).defaultSystem("你是一名医生,擅长诊断病情并提供对应的治疗方案").build();
    }

prompt(提示词)

SpringAi中主要有以下几类提示词模板:

  1. PromptTemplate:通用的提示词模板类,用于构建包含占位符的提示语句;适用于需要动态替换变量的任意提示内容;
  2. AssistantPromptTemplate:专门用于生成模型助手角色的提示词模板,当需要定义 AI 助手的行为或初始指令时使用;
  3. FunctionPromptTemplate:用于生成与函数调用相关的提示词模板;当需要模型根据特定函数描述进行推理或调用时使用;
  4. SystemPromptTemplate:用于生成系统级别的提示词模板,通常用于设置模型的整体行为;用于生成系统级别的提示词模板,通常用于设置模型的整体行为;

示例

通过@Value注解加载提示词模板

    @Value("classpath:/my-prompt-template.st")
    private Resource systemResource;


    @GetMapping("/chat4")
    public String chat4(@RequestParam String message) {
        SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemResource);
        Prompt prompt = systemPromptTemplate.create();
        return chatClient.prompt(prompt).user(message).call().content();
    }

提示词模板内容

你是我的好朋友,请用东北话回答问题,回答问题的时候适当添加表情符号。
今天是 {{current_date}}。

输出:
在这里插入图片描述

function call(工具调用)

使用@Tool注解定义工具

public class DateTimeUtil {


    /**
     * @Tool注解:
     *      1、name:工具的名称。如果未提供,则将使用方法名称。AI 模型在调用工具时使用此名称来识别工具。因此,不允许在同一个类中有两个同名的工具
     *      2、returnDirect:工具结果是应直接返回给客户端还是传递回模型
     *      3、description:工具的描述,模型可以使用它来了解何时以及如何调用工具
     * @return
     */
    @Tool(name = "",
            description = "Get the current date and time in the user's timezone")
    public String getCurrentTime() {
        return LocalDateTime.now().atZone(LocaleContextHolder.getTimeZone().toZoneId()).toString();
    }


    /**
     * @ToolParam注解:
     *      1、required:参数是必需的还是可选的。默认情况下,所有参数都被视为必需参数
     *      2、description:description:参数的描述,模型可以使用该描述来更好地了解如何使用它
     * @param time
     */
    @Tool(name = "setAlarm", description = "Set a user alarm for the given time")
    void setAlarm(@ToolParam(description = "Time in ISO-8601 format") String time) {
        LocalDateTime alarmTime = LocalDateTime.parse(time, DateTimeFormatter.ISO_DATE_TIME);
        System.out.println("Alarm set for " + alarmTime);
    }


}

通过tools方法添加工具,模型会自动调用工具

chatClient.prompt().tools(new DateTimeUtil()).user(message).call().content();

由于我使用的是本地的deepseek-r1不支持tool,报错了,这里就不放测试结果了。

 [400] Bad Request - {"error":"registry.ollama.ai/library/deepseek-r1:14b does not support tools"}

参考

  1. Spring文档
  2. Spring Ai视频教程
<think>好的,我现在需要帮助用户了解如何在SpringAI使用RAG功能。首先,我得确认用户的需求。他们提到了SpringAI的RAG实现和使用方法,所以需要详细说明步骤和相关配置。 接下来,我需要回忆一下SpringAI的相关文档。SpringAI是一个集成AI功能的框架,支持RAG,结合了检索和生成。根据用户提供的引用内容,RAG主要是通过检索现有文档来增强生成结果的准确性,比如引用[1]和[2]提到的内容。因此,我需要将SpringAI的RAG实现与这些概念联系起来。 然后,我应该分步骤讲解实现过程。首先,用户需要添加SpringAI的依赖,比如Maven或Gradle配置。然后配置API密钥,比如OpenAI或Azure的,这属于基础设置。接下来是文档处理,可能需要使用DocumentReader来加载文档,比如PDF或文本文件,并进行分块和向量化存储,这里可能涉及到向量数据库如Redis或PgVector,这部分需要详细说明。 然后是检索增强生成的具体实现,需要结合检索器和生成模型。用户可能需要配置RetrievalAugmentor,设置相关的参数,如topK和相似度阈值。这里可以引用用户提供的引用[3]提到的查询分析,说明检索部分如何优化查询结果。 另外,用户提供的引用[4]提到FlashRAG工具包,可能和高效实现相关,虽然SpringAI可能不直接使用,但可以提一下优化效率的方法,比如模块化设计或缓存策略。 还需要考虑代码示例,给出一个简单的实现,比如如何加载文档、配置RAG链,并生成回答。同时,要指出常见问题,比如分块大小、向量模型选择,以及如何监控性能。 最后,生成相关问题,帮助用户进一步探索,比如性能优化、与其他框架对比、处理中文的挑战以及评估方法。这些问题需要覆盖用户可能关心的后续步骤。 总结一下,回答的结构应该是:简介SpringAI的RAG,分步实现方法,代码示例,注意事项,以及相关问题。确保使用正确的中文术语,并引用用户提供的资料来支持关键点,比如在检索部分引用[3]的查询分析,在效率部分提到引用[4]的工具包。</think>### SpringAI RAG 实现与使用指南 #### 1. **SpringAI RAG 核心组件** SpringAI 的 RAG 实现基于以下模块: - **文档加载器**:支持 PDF、TXT、HTML 等格式的文档加载(如 `ResourceDocumentReader`) - **文本分块器**:将文档切分为语义连贯的片段,常用 `TokenTextSplitter`[^3] - **向量存储**:集成 Redis、PgVector 等向量数据库,用于存储文档块向量 - **检索器**:基于相似度检索相关文档块(如 `VectorStoreRetriever`) - **生成模型**:调用 OpenAI、Azure OpenAI 等 LLM 生成最终答案 #### 2. **实现步骤** **步骤 1:添加依赖** ```xml <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-openai-spring-boot-starter</artifactId> <version>0.8.0</version> </dependency> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-pgvector-store</artifactId> </dependency> ``` **步骤 2:配置向量存储** ```yaml spring: ai: vectorstore: pgvector: host: localhost database: rag_db user: postgres ``` **步骤 3:构建 RAG 链** ```java @Bean public RetrievalAugmentor retrievalAugmentor(VectorStore vectorStore) { return new VectorStoreRetriever(vectorStore, 5); // 检索 Top5 相关块 } @Bean public PromptTemplate promptTemplate() { return new PromptTemplate("基于以下上下文回答:\n{context}\n\n问题:{question}"); } @Bean public RAGChain ragChain(RetrievalAugmentor augmentor, ChatClient chatClient) { return new RAGChain(augmentor, chatClient, promptTemplate()); } ``` #### 3. **关键优化点** - **查询重写**:使用 `QueryAnalyzer` 对原始问题进行意图解析和关键词扩展 - **混合检索**:结合向量检索与传统 BM25 算法提升召回率 - **上下文压缩**:通过 `ContextCompressor` 剔除冗余信息(如引用[4]中 FlashRAG 的模块化设计) #### 4. **使用示例** ```java String answer = ragChain.call( "如何预防糖尿病?", List.of(new Document("health_guide.pdf")) // 动态加载文档 ); ``` #### 5. **注意事项** - **分块策略**:中文建议 200-400 字符/块,重叠率 10% - **向量模型**:优先选用多语言模型如 `text-embedding-3-large` - **监控**:通过 `RAGMetrics` 监控检索命中率与生成质量
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值