Springboot集成Spring AI和Milvus,验证RAG构建过程

在当今信息爆炸的时代,如何高效地管理和利用海量的知识数据成为了企业和开发者面临的重大挑战。基于AI的大模型和检索增强生成(RAG, Retrieval-Augmented Generation)技术为这一难题提供了全新的解决方案。通过结合向量数据库、Embedding技术以及先进的大语言模型,我们可以构建一个强大的本地知识库系统,并实现高效的检索增强生成流程。

本文将详细介绍如何使用Spring AI、Milvus 和 Spring AI Alibaba 开源框架,搭建并验证一个基于AI大模型的本地知识库系统。我们将深入探讨各个关键知识点,包括向量数据库的使用、Embedding生成、大语言模型的选择与应用、文档切片技术、重排序算法的设计,以及如何充分利用Spring AI框架来简化开发过程。通过这一系列步骤,我们将展示如何从零开始构建一个完整的RAG流程,并验证其在实际应用中的效果。

1、前提条件

  • JDK为17以上版本,本人使用的jdk21版本;
  • SpringBoot版本为3.x以上,本项目使用的是SpringBoot 3.3.3版本;
  • 本文采用了阿里巴巴的Qwen大模型进行实验与验证,但您同样可以选择使用DeepSeek大模型作为替代方案。若选用阿里巴巴的AI服务,则需首先在阿里云平台上开通相应的大型模型服务,并获取所需的API密钥,以便在后续代码中调用。具体的开通与配置步骤,请参阅阿里云大模型服务平台“百炼”的相关文档和指南如何获取API Key_大模型服务平台百炼(Model Studio)-阿里云帮助中心。这样可以确保您能够顺利地集成和使用这些先进的AI资源。
  • 提前安装部署好Milvus数据库,本文示例使用的Milvus2.5.4版本

2、添加maven依赖

创建springboot工程后,在pom.xml文件里引入第三方Jar包。

        <dependency>
            <groupId>com.alibaba.cloud.ai</groupId>
            <artifactId>spring-ai-alibaba-starter</artifactId>
            <version>${spring-ai-alibaba.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-pdf-document-reader</artifactId>
            <version>${spring-ai.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-milvus-store</artifactId>
            <version>${spring-ai.version}</version>
        </dependency>

本示例使用的是milvus2.5.4最新版本,Java sdk 接口参考文档:About - Milvus java sdk v2.5.x

注意使用sdk版本跟milvus版本的对应关系,milvus2.5.x版本建议使用sdk2.5.2以上版本,否则可能会出现一些诡异问题。

Pom.xml完整内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.yuncheng</groupId>
    <artifactId>spring-ai-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>21</maven.compiler.source>
        <maven.compiler.target>21</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring-ai.version>1.0.0-M5</spring-ai.version>
        <spring-ai-alibaba.version>1.0.0-M5.1</spring-ai-alibaba.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.3</version>
        <relativePath/>
    </parent>

    <dependencies>

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

        <dependency>
            <groupId>com.alibaba.cloud.ai</groupId>
            <artifactId>spring-ai-alibaba-starter</artifactId>
            <version>${spring-ai-alibaba.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-pdf-document-reader</artifactId>
            <version>${spring-ai.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-milvus-store</artifactId>
            <version>${spring-ai.version}</version>
        </dependency>

    </dependencies>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </repository>
        <repository>
            <id>aliyun</id>
            <name>aliyun Repository</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        </repository>
    </repositories>
    
</project>

3、配置yml文件

#配置milvus向量数据库的IP、端口以及阿里云AI服务的api-key

server:
  port: 8080
milvus:
  host: 192.168.3.17
  port: 19530
spring:
  application:
    name: spring-ai-helloworld
  ai:
    dashscope:
      api-key: sk-b90ad31bb3eb4a158524928354f37dc5

4、创建VectorStore初始化类

以下源代码定义了一个Spring配置类 VectorStoreConfig,用于配置和初始化与Milvus向量数据库的连接以及基于Spring AI框架的向量存储(Vector Store)。


import io.milvus.client.MilvusServiceClient;
import io.milvus.param.ConnectParam;
import io.milvus.param.IndexType;
import io.milvus.param.MetricType;
import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.ai.embedding.TokenCountBatchingStrategy;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.ai.vectorstore.milvus.MilvusVectorStore;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class VectorStoreConfig {

    @Value("${milvus.host}")
    private String host;
    @Value("${milvus.port}")
    private Integer port;

    /**
     * 定义一个名为 milvusServiceClient 的Bean,用于创建并返回一个 MilvusServiceClient 实例。
     */
    @Bean
    public MilvusServiceClient milvusServiceClient() {
        return new MilvusServiceClient(
                ConnectParam.newBuilder()
                        .withHost(host)
                        .withPort(port)
                        .build());
    }

    /**
     * 定义一个名为 vectorStore2 的Bean,用于创建并返回一个 VectorStore 实例。
     * 使用 MilvusVectorStore.builder 方法构建向量存储对象,并设置以下参数:
     * collectionName:集合名称为 "vector_store_02"。
     * databaseName:数据库名称为 "default"。
     * embeddingDimension:嵌入维度为 1536。
     * indexType:索引类型为 IVF_FLAT,这是一种常见的近似最近邻搜索索引类型。
     * metricType:度量类型为 COSINE,用于计算向量之间的余弦相似度。
     * batchingStrategy:使用 TokenCountBatchingStrategy 策略进行批量处理。
     * initializeSchema:设置为 true,表示在构建时初始化数据库模式。
     */
    @Bean(name = "vectorStore2")
    public VectorStore vectorStore(MilvusServiceClient milvusClient, EmbeddingModel embeddingModel) {
        return MilvusVectorStore.builder(milvusClient, embeddingModel)
                .collectionName("vector_store_02")
                .databaseName("default")
                .embeddingDimension(1536)
                .indexType(IndexType.IVF_FLAT)
                .metricType(MetricType.COSINE)
                .batchingStrategy(new TokenCountBatchingStrategy())
                .initializeSchema(true)
                .build();
    }
}

以上代码展示了如何在Spring应用中集成Milvus向量数据库,并配置相应的向量存储组件,以支持高效的向量检索和相似度计算。主要完成了以下任务:

  • 连接到Milvus向量数据库:通过 MilvusServiceClient 连接到指定的Milvus服务实例。
  • 配置向量存储:使用 MilvusVectorStore 类构建并配置一个向量存储实例,包括设置集合名称、数据库名称、嵌入维度、索引类型、度量类型等参数。
  • 集成嵌入模型:结合Spring AI的嵌入模型(EmbeddingModel),实现对文本或其他数据的嵌入表示,并将其存储在向量数据库中。

5、创建RAG逻辑处理类

这段源代码定义了一个Spring Boot控制器 DocumentEmbeddingController02,用于处理文档嵌入、向量存储和基于检索增强生成(RAG)的聊天响应。

注意:在本示例中,Spring Boot工程的 `resources/data/` 目录下放置了一个名为 `spring_ai_alibaba_quickstart.pdf` 的PDF文件。该文件将被解析并进行向量化处理,以便后续的检索增强生成(RAG)流程能够基于此文档内容进行检索和验证。通过这一过程,可以评估RAG在本地知识库检索中的准确性和有效性。用户可以根据需要替换为自己的PDF文档,以进行类似的验证和测试。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.document.Document;
import org.springframework.ai.document.DocumentReader;
import org.springframework.ai.reader.pdf.PagePdfDocumentReader;
import org.springframework.ai.transformer.splitter.TokenTextSplitter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import java.io.IOException;
import com.alibaba.cloud.ai.advisor.RetrievalRerankAdvisor;
import com.alibaba.cloud.ai.model.RerankModel;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import java.nio.charset.StandardCharsets;
import java.util.List;

@RestController
@RequestMapping("/milvus2")
public class DocumentEmbeddingController02 {
    private static final Logger log = LoggerFactory.getLogger(DocumentEmbeddingController02.class);

    @Value("classpath:/prompts/system-qa.st")
    private Resource systemResource;

    @Value("classpath:/data/spring_ai_alibaba_quickstart.pdf")
    private Resource springAiResource;

    @Autowired
    @Qualifier("vectorStore2")
    private VectorStore vectorStore;

    @Autowired
    private  ChatModel chatModel;

    @Autowired
    private  RerankModel rerankModel;

    /**
     * 处理PDF文档的解析、分割和嵌入存储。
     * 使用 PagePdfDocumentReader 解析PDF文档并生成 Document 列表。
     * 使用 TokenTextSplitter 将文档分割成更小的部分。
     * 将分割后的文档添加到向量存储中,以便后续检索和生成。
     */
    @GetMapping("/insertDocuments")
    public void insertDocuments() throws IOException {
        // 1. parse document
        DocumentReader reader = new PagePdfDocumentReader(springAiResource);
        List<Document> documents = reader.get();
        log.info("{} documents loaded", documents.size());

        // 2. split trunks
        List<Document> splitDocuments = new TokenTextSplitter().apply(documents);
        log.info("{} documents split", splitDocuments.size());

        // 3. create embedding and store to vector store
        log.info("create embedding and save to vector store");
        vectorStore.add(splitDocuments);
    }

    /**
     * 根据用户输入的消息生成JSON格式的聊天响应。
     * 创建一个 SearchRequest 对象,设置返回最相关的前2个结果。
     * 从 systemResource 中读取提示模板。
     * 使用 ChatClient 构建聊天客户端,调用 RetrievalRerankAdvisor 进行检索和重排序,并生成最终的聊天响应内容。
     */
    @GetMapping(value = "/ragJsonText", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
    public String ragJsonText(@RequestParam(value = "message",
            defaultValue = "如何使用spring ai alibaba?") String message) throws IOException {

        SearchRequest searchRequest = SearchRequest.builder().topK(2).build();

        String promptTemplate = systemResource.getContentAsString(StandardCharsets.UTF_8);

        return ChatClient.builder(chatModel)
                .defaultAdvisors(new RetrievalRerankAdvisor(vectorStore, rerankModel, searchRequest, promptTemplate, 0.1))
                .build()
                .prompt()
                .user(message)
                .call()
                .content();
    }

    /**
     * 根据用户输入的消息生成流式聊天响应。
     * 类似于 ragJsonText 方法,但使用 stream() 方法以流的形式返回聊天响应。
     * 返回类型为 Flux<ChatResponse>,适合需要实时更新的场景。
     */
    @GetMapping(value = "/ragStream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ChatResponse> ragStream(@RequestParam(value = "message",
            defaultValue = "如何使用spring ai alibaba?") String message) throws IOException {

        SearchRequest searchRequest = SearchRequest.builder().topK(2).build();

        String promptTemplate = systemResource.getContentAsString(StandardCharsets.UTF_8);

        return ChatClient.builder(chatModel)
                .defaultAdvisors(new RetrievalRerankAdvisor(vectorStore, rerankModel, searchRequest, promptTemplate, 0.1))
                .build()
                .prompt()
                .user(message)
                .stream()
                .chatResponse();
    }

}

这段代码展示了如何在Spring应用中集成文档解析、向量存储和基于AI的聊天响应生成,适用于构建智能问答系统或知识管理系统。

6、创建prompts模板

在springboot工程的resources\prompts目录下,创建一个prompts模板文件system-qa.st,文件内容如下:

上下文信息如下:
---------------------
{question_answer_context}
---------------------
根据上下文和提供的历史信息,而不是先验知识,回复用户问题。
如果答案不在上下文中,请通知用户您无法回答该问题。

7、测试验证RAG

7.1、在向量库中创建Collection

以上代码编写完成后,启动springboot工程,启动时会在Milvus数据库中自动创建vectorStore2的collection,创建向量表的逻辑是由上述VectorStoreConfig 类控制的。

生成的collection集合中的doc_id、content、metadata、embedding这几个字段是默认生成的,当然用户也可以指定字段名称。

7.2、导入本地PDF文档到向量库

浏览器中输入:http://localhost:8080/milvus2/insertDocuments

执行成功后,也可以通过Milvus自带的webui工具查看。

7.3、RAG检索测试

浏览器中输入:http://localhost:8080/milvus2/ragJsonText

调用本方法时,默认使用检索关键词“如何使用spring ai alibaba?”。我们期望检索增强生成(RAG)系统能够返回与 `spring_ai_alibaba_quickstart.pdf` 文档中的相关内容,并提供最优结果。通过这一过程,可以验证RAG是否依据本地知识库文档进行准确检索和输出。以下是RAG的实际返回结果,其内容与刚刚导入的本地PDF文件高度一致,从而证实了系统的检索准确性和有效性。这表明RAG能够正确地从本地知识库中提取并生成相关响应。

8、RAG执行过程源代码解读

以上示例是如何实现RAG的,通过断点调试,找到了com.alibaba.cloud.ai.advisor.RetrievalRerankAdvisor类,其中有两个关键方法before和doRerank,官方代码如下:

protected List<Document> doRerank(AdvisedRequest request, List<Document> documents) {
    if (CollectionUtils.isEmpty(documents)) {
       return documents;
    }

    var rerankRequest = new RerankRequest(request.userText(), documents);
    RerankResponse response = rerankModel.call(rerankRequest);
    logger.debug("reranked documents: {}", response);
    if (response == null || response.getResults() == null) {
       return documents;
    }

    return response.getResults()
       .stream()
       .filter(doc -> doc != null && doc.getScore() >= minScore)
       .sorted(Comparator.comparingDouble(DocumentWithScore::getScore).reversed())
       .map(DocumentWithScore::getOutput)
       .collect(toList());
}

private AdvisedRequest before(AdvisedRequest request) {

    var context = new HashMap<>(request.adviseContext());

    // 1. Advise the system text.
    String advisedUserText = request.userText() + System.lineSeparator() + this.userTextAdvise;

    var searchRequestToUse = SearchRequest.from(this.searchRequest)
       .query(request.userText())
       .filterExpression(doGetFilterExpression(context))
       .build();

    // 2. Search for similar documents in the vector store.
    logger.debug("searchRequestToUse: {}", searchRequestToUse);
    List<Document> documents = this.vectorStore.similaritySearch(searchRequestToUse);
    logger.debug("retrieved documents: {}", documents);

    // 3. Rerank documents for query
    documents = doRerank(request, documents);

    context.put(RETRIEVED_DOCUMENTS, documents);

    // 4. Create the context from the documents.
    String documentContext = documents.stream()
       .map(Document::getText)
       .collect(Collectors.joining(System.lineSeparator()));

    // 5. Advise the user parameters.
    Map<String, Object> advisedUserParams = new HashMap<>(request.userParams());
    advisedUserParams.put("question_answer_context", documentContext);

    return AdvisedRequest.from(request)
       .userText(advisedUserText)
       .userParams(advisedUserParams)
       .adviseContext(context)
       .build();
}

以下我们解读一下这段代码,来理解RAG的执行过程。

这段代码定义了一个名为 `before` 的方法,该方法接收一个 `AdvisedRequest` 对象作为输入,并返回一个新的 `AdvisedRequest` 对象。该方法的主要目的是对用户输入的文本进行预处理、检索相关文档、重排序文档,并生成上下文信息,以便后续处理。以下是详细的步骤和功能说明:

1)方法签名

```java

private AdvisedRequest before(AdvisedRequest request) {

```

- **`before` 方法**:这是一个私有方法,接收一个 `AdvisedRequest` 对象作为参数,并返回一个新的 `AdvisedRequest` 对象。

2)初始化上下文

```java

var context = new HashMap<>(request.adviseContext());

```

- 创建一个新的 `HashMap` 对象 `context`,并从输入的 `request` 中复制现有的建议上下文(`adviseContext`)。

3构建建议的用户文本

```java

String advisedUserText = request.userText() + System.lineSeparator() + this.userTextAdvise;

```

- 将输入请求中的用户文本(`userText`)与预先定义的用户文本建议(`userTextAdvise`)拼接在一起,并使用系统换行符(`System.lineSeparator()`)分隔它们,形成新的建议用户文本(`advisedUserText`)。

 4)构建搜索请求

```java

var searchRequestToUse = SearchRequest.from(this.searchRequest)

    .query(request.userText())

    .filterExpression(doGetFilterExpression(context))

    .build();

```

- 使用 `SearchRequest.from(this.searchRequest)` 方法从现有的搜索请求模板创建一个新的搜索请求对象。

- 设置查询文本为 `request.userText()`。

- 调用 `doGetFilterExpression(context)` 方法生成过滤表达式,并将其应用到搜索请求中。

- 最终构建并返回新的搜索请求对象 `searchRequestToUse`。

 5)执行相似度搜索

```java

logger.debug("searchRequestToUse: {}", searchRequestToUse);

List<Document> documents = this.vectorStore.similaritySearch(searchRequestToUse);

logger.debug("retrieved documents: {}", documents);

```

- 记录调试信息,输出构建好的 `searchRequestToUse`。

- 使用向量存储(`vectorStore`)执行相似度搜索,获取与查询文本最相关的文档列表(`documents`)。

- 记录调试信息,输出检索到的文档列表。

6)文档重排序

```java

documents = doRerank(request, documents);

```

- 调用 `doRerank` 方法对检索到的文档进行重排序,以优化其相关性顺序,并更新文档列表 `documents`。

7)更新上下文

```java

context.put(RETRIEVED_DOCUMENTS, documents);

```

- 将重排序后的文档列表添加到上下文 `context` 中,键名为 `RETRIEVED_DOCUMENTS`。

8)生成文档上下文

```java

String documentContext = documents.stream()

    .map(Document::getText)

    .collect(Collectors.joining(System.lineSeparator()));

```

- 将文档列表中的每个文档的文本内容提取出来,并使用系统换行符连接成一个字符串 `documentContext`。

9)构建建议的用户参数

```java

Map<String, Object> advisedUserParams = new HashMap<>(request.userParams());

advisedUserParams.put("question_answer_context", documentContext);

```

- 创建一个新的 `HashMap` 对象 `advisedUserParams`,并从输入请求中复制现有的用户参数(`userParams`)。

- 将生成的文档上下文(`documentContext`)作为键值对 `"question_answer_context"` 添加到用户参数中。

10)返回新的 `AdvisedRequest` 对象

```java

return AdvisedRequest.from(request)

    .userText(advisedUserText)

    .userParams(advisedUserParams)

    .adviseContext(context)

    .build();

```

- 使用 `AdvisedRequest.from(request)` 方法从输入请求创建一个新的 `AdvisedRequest.Builder`。

- 设置新的用户文本(`advisedUserText`)、用户参数(`advisedUserParams`)和建议上下文(`context`)。

- 构建并返回新的 `AdvisedRequest` 对象。

总结

RetrievalRerankAdvisor.before() 方法主要完成以下任务:

1. **初始化上下文**:从输入请求中复制现有的建议上下文。

2. **构建建议的用户文本**:将用户输入的文本与预先定义的建议文本拼接在一起。

3. **构建搜索请求**:根据用户输入的文本和上下文生成搜索请求。

4. **执行相似度搜索**:在向量存储中查找与查询文本最相关的文档。

5. **文档重排序**:对检索到的文档进行重排序,优化其相关性顺序。

6. **更新上下文**:将重排序后的文档列表添加到上下文中。

7. **生成文档上下文**:将文档列表中的文本内容拼接成一个字符串。

8. **构建建议的用户参数**:将生成的文档上下文作为用户参数的一部分。

9. **返回新的请求对象**:构建并返回包含所有更新信息的新 `AdvisedRequest` 对象。

这段代码展示了如何通过一系列步骤对用户输入进行预处理,并生成优化后的请求对象,以便后续的检索增强生成(RAG)流程能够更准确地从本地知识库中检索相关信息。

9、结束语

通过本文的详细讲解和实践示例,我们成功展示了如何使用Spring AI、Milvus 和 Spring AI Alibaba 开源框架,搭建并验证一个基于AI大模型的本地知识库系统,并实现了完整的检索增强生成(RAG)流程。在这个过程中,我们深入探讨了多个关键技术点:

  • 向量数据库:通过Milvus的强大向量存储和相似度搜索功能,我们能够高效地管理和检索大规模的Embedding数据。
  • Embedding生成:利用预训练的语言模型生成高质量的文本嵌入,为后续的相似度搜索和重排序提供了坚实的基础。
  • 大语言模型选型:根据具体需求选择合适的大语言模型,并评估其在不同场景下的表现,确保系统的高效性和准确性。
  • 文档切片:通过对长文档进行合理切片,保证每个片段都能被有效处理,提升了整体系统的性能和灵活性。
  • 重排序算法:设计并实现高效的重排序算法,进一步优化检索结果的相关性,提升用户体验。
  • SpringAI框架使用:借助Spring AI提供的丰富工具和便捷接口,简化了整个开发流程,提高了代码的可维护性和扩展性。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

用React实现一个登录界面

使用React来创建一个简单的登录表单。以下是一个基本的React登录界面示例&#xff1a; 1. 设置React项目 如果你还没有一个React项目&#xff0c;你可以使用Create React App来创建一个。按照之前的步骤安装Create React App&#xff0c;然后创建一个新项目。 2. 创建登录组…

Python爬虫实战:股票分时数据抓取与存储 (1)

在金融数据分析中&#xff0c;股票分时数据是投资者和分析师的重要资源。它能够帮助我们了解股票在交易日内的价格波动情况&#xff0c;从而为交易决策提供依据。然而&#xff0c;获取这些数据往往需要借助专业的金融数据平台&#xff0c;其成本较高。幸运的是&#xff0c;通过…

通过BingAPI爬取Bing半个月内壁纸

通过BingAPI爬取Bing半个月内壁纸 一、前言二、爬虫代码三、代码说明 一、前言 爬取Bing搜索网站首页壁纸的方式主要有两种&#xff0c;第一种为间接爬取&#xff0c;即并不直接对Bing网站发起请求&#xff0c;而是对那些收集汇总了Bing壁纸的网站发起请求&#xff0c;爬取图片…

matlab汽车动力学半车垂向振动模型

1、内容简介 matlab141-半车垂向振动模型 可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 4、参考论文 略

在Ubuntu24.04上安装Stable-Diffusion1.10.1版本

之前曾介绍过在Ubuntu22.04上安装Stable-Diffusion&#xff1a; 在Ubuntu22.04上部署Stable Diffusion_ubuntu stable dif-CSDN博客 这个安装我们使用conda python虚拟机。这次我们介绍的是在Ubuntu24.04安装Stable-Diffusion的最新版本V1.10.1&#xff08;截止到今天最新版&…

功能测试与接口测试详解

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 本文主要分为两个部分&#xff1a; 第一部分&#xff1a;主要从问题出发&#xff0c;引入接口测试的相关内容并与前端测试进行简单对比&#xff0c;总结两者之前的…

IDEA集成DeepSeek

使用版本: IDEA 2024.3&#xff0c;Python3.11 通过CodeGPT插件安装&#xff1a; 1. 安装Python环境&#xff0c;安装完成后python --version验证是否成功 2. DeepSeek官网获取API Key 3. IDEA中安装CodeGPT插件 文件->设置->插件&#xff0c;搜"CodeGPT" …

DeepSeek笔记(二):DeepSeek局域网访问

如果有多台电脑&#xff0c;可以通过远程访问&#xff0c;实现在局域网环境下多台电脑共享使用DeepSeek模型。在本笔记中&#xff0c;首先介绍设置局域网多台电脑访问DeepSeek-R1模型。 一、启动Ollama局域网访问 1.配置环境变量 此处本人的操作系统是Windows11&#xff0c;…

计算机视觉-OpenCV图像处理

1.Matplotlib数据可视化&#xff08;绘制图像直方图、可视化矩阵&#xff09; # Matplotlib 数据可视化&#xff08;绘制图像直方图、可视化矩阵&#xff09; # 本节主要讲解如何使用 Matplotlib 绘制图像直方图和可视化矩阵。 # 1. 绘制图像直方图 # 2. 可视化矩阵# 1. 绘制图…

golangAPI调用deepseek

目录 1.deepseek官方API调用文档1.访问格式2.curl组装 2.go代码1. config 配置2.模型相关3.错误处理4.deepseekAPI接口实现5. 调用使用 3.响应实例 1.deepseek官方API调用文档 1.访问格式 现在我们来解析这个curl 2.curl组装 // 这是请求头要加的参数-H "Content-Type:…

闭源大语言模型的怎么增强:提示工程 检索增强生成 智能体

闭源大语言模型的怎么增强 提示工程 检索增强生成 智能体 核心原理 提示工程:通过设计和优化提示词,引导大语言模型进行上下文学习和分解式思考,激发模型自身的思维和推理能力,使模型更好地理解和生成文本,增强其泛用性和解决问题的能力。检索增强生成:结合检索的准确…

《计算机视觉》——角点检测和特征提取sift

角点检测 角点的定义&#xff1a; 从直观上理解&#xff0c;角点是图像中两条或多条边缘的交点&#xff0c;在图像中表现为局部区域内的灰度变化较为剧烈的点。在数学和计算机视觉中&#xff0c;角点可以被定义为在两个或多个方向上具有显著变化的点。比如在一幅建筑物的图像…

具身智能在智能巡检机器人中的应用——以开关柜带电操作机器人为例

随着机器人技术和人工智能的迅速发展&#xff0c;具身智能在各行业的应用日益广泛&#xff0c;尤其是在电力行业中的智能巡检领域。传统的电力巡检和维护工作通常需要人工操作&#xff0c;存在着高温、高压、强电磁场等危险环境&#xff0c;且效率较低。开关柜带电操作机器人作…

基于SpringBoot实现的大学社团平台系统实现功能八

一、前言介绍&#xff1a; 1.1 项目摘要 随着高校社团活动的日益丰富和多样化&#xff0c;学生对于社团管理和参与的需求也在不断增加。传统的社团管理方式往往存在效率低下、信息不透明等问题&#xff0c;无法满足现代学生对于便捷、高效社团管理的需求。因此&#xff0c;利…

Unity使用反射进行Protobuf(CS/SC)协议,json格式

protobuf生成的协议,有挺多协议的.利用反射生成dto进行伪协议的响应 和 发送请求 应用场景: 请求(CS)_后端先写完了(有proto接口了),前端还没搞完时(暂还没接入proto),后端可使用此请求,可自测 响应(SC)_可自行构建一个响应(有些特殊数据后端下发不了的),对数据进行测试 // 请…

使用synchronized解决高并发场景

synchronized能很好的解决高并发所带来的超卖等问题&#xff0c;但是synchronized也有属于它的缺陷&#xff0c;就是只适合单机模式&#xff0c;如果同时开启多个实例&#xff0c;那么还是会出现超卖的情况&#xff0c;下面就介绍一下synchronized使用方法&#xff0c;十分的简…

【Pytorch 库】自定义数据集相关的类

torch.utils.data.Dataset 类torch.utils.data.DataLoader 类自定义数据集示例1. 自定义 Dataset 类2. 在其他 .py 文件中引用和使用该自定义 Dataset torch_geometric.data.Dataset 类torch_geometric.data.Dataset VS torch.utils.data.Dataset 详细信息&#xff0c;参阅 tor…

Softing线上研讨会 | 自研还是购买——用于自动化产品的工业以太网

| 线上研讨会时间&#xff1a;2025年1月27日 16:00~16:30 / 23:00~23:30 基于以太网的通信在工业自动化网络中的重要性日益增加。设备制造商正面临着一大挑战——如何快速、有效且经济地将工业以太网协议集成到其产品中。其中的关键问题包括&#xff1a;是否只需集成单一的工…

Wireshark 输出 数据包列表本身的值

在 Wireshark 中&#xff0c;如果你想输出数据包列表本身的值&#xff08;例如&#xff0c;将数据包的摘要信息、时间戳、源地址、目的地址等导出为文本格式&#xff09;&#xff0c;可以使用 导出为纯文本文件 的功能。以下是详细步骤&#xff1a; 步骤 1&#xff1a;打开 Wir…

解压rar格式的软件有哪些?8种方法(Win/Mac/手机/网页端)

RAR 文件是一种常见的压缩文件格式&#xff0c;由尤金・罗谢尔&#xff08;Eugene Roshal&#xff09;开发&#xff0c;因其扩展名 “rar” 而得名。它通过特定算法将一个或多个文件、文件夹进行压缩&#xff0c;大幅减小存储空间&#xff0c;方便数据传输与备份。然而&#xf…