langchain4j+ai模型 硅谷小智 智慧医疗实战项目案例

文章目录

前言

博主介绍:✌目前全网粉丝4W+,csdn博客专家、Java领域优质创作者,博客之星、阿里云平台优质作者、专注于Java后端技术领域。

涵盖技术内容:Java后端、大数据、算法、分布式微服务、中间件、前端、运维等。

博主所有博客文件目录索引:博客目录索引(持续更新)

CSDN搜索:长路

视频平台:b站-Coder长路

前言

开源项目地址:https://gitee.com/changluJava/ai-xiaozhi

技术选型描述 & 相关资料

语言:Java

框架:langchain4j + 大模型qwen + function call + RAG增量(向量模型、向量数据库PINECONE)

聊天记忆持久化存储:mongodb

业务数据库(存储相关预约业务):mysql

向量数据库(知识库):向量数据库PINECONE

本文档主要进行梳理实现过程步骤,本项目来源尚硅谷-小智医疗项目:https://www.bilibili.com/video/BV1cpLTz1EVp

资料文档如下:

复制代码
尚硅谷企业级大模型应用项目:小智医疗(LangChain4J)
B站直达:https://www.bilibili.com/video/BV1cpLTz1EVp
百度网盘:https://pan.baidu.com/s/1rvAZP9Cp8uHu43MM7P95eQ?pwd=yyds 提取码: yyds

一、初始化项目

1.1、pom依赖引入

xml 复制代码
<properties>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring-boot.version>3.2.6</spring-boot.version>
    <knife4j.version>4.3.0</knife4j.version>
    <langchain4j.version>1.0.0-beta3</langchain4j.version>
    <mybatis-plus.version>3.5.11</mybatis-plus.version>
    <langchain4j.version>1.0.0-beta3</langchain4j.version>
</properties>

<dependencies>
    <!-- web应用程序核心依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 编写和运行测试用例 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <!--langchain4j高级功能-->
    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j-spring-boot-starter</artifactId>
    </dependency>

</dependencies>

<dependencyManagement>
    <dependencies>
        <!--引入SpringBoot依赖管理清单-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!--引入langchain4j依赖管理清单-->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-bom</artifactId>
            <version>${langchain4j.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!--引入百炼依赖管理清单-->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-community-bom</artifactId>
            <version>${langchain4j.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

1.2、启动器实现 & 配置文件参数

XiaozhiSpringBootApplication.java:

java 复制代码
@SpringBootApplication
public class XiaozhiSpringBootApplication {
    public static void main(String[] args) {
        SpringApplication.run(XiaozhiSpringBootApplication.class, args);
    }
}

application.properties:

properties 复制代码
# web端口
server.port=8080

1.3、引入智能体模型

引入依赖:

xml 复制代码
<!-- 基于open-ai的langchain4j接口:ChatGPT、deepseek都是open-ai标准下的大模型 -->
<!--        <dependency>-->
<!--            <groupId>dev.langchain4j</groupId>-->
<!--            <artifactId>langchain4j-open-ai</artifactId>-->
<!--        </dependency>-->
<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
</dependency>

<!-- 接入阿里云百炼平台 -->
<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId>
</dependency>

application.properties配置参数如下:配置了百炼平台的参数配置,配置好之后,即可注入大模型

properties 复制代码
# 百炼平台
langchain4j.community.dashscope.chat-model.api-key=${DASH_SCOPE_API_KEY}
langchain4j.community.dashscope.chat-model.model-name=qwen-plus-latest
langchain4j.community.dashscope.chat-model.temperature=0.9
# 日志请求打印
langchain4j.open-ai.chat-model.log-requests=true
langchain4j.open-ai.chat-model.log-responses=true

使用方式如下:

java 复制代码
// 注入千问模型
@Autowired
private QwenChatModel qwenChatModel;

1.3、智能体接口定义 & controller接口实现 & 集成接口文档

pom.xml集成接口文档的依赖如下:

xml 复制代码
<!-- 前后端分离中的后端接口测试工具 -->
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
    <version>${knife4j.version}</version>
</dependency>

langchain4j框架内部实现非常完美,对于这个智能体接口我们可以动态通过注解方式去声明选择大模型model、记忆持久化chatMemory组件、functions calling tools工具以及RAG向量化组件(向量化计算 + 向量化数据库配置):

java 复制代码
@AiService(
        wiringMode = AiServiceWiringMode.EXPLICIT,
				chatModel = "qwenChatModel"
)
public interface XiaozhiAgent {

    // 原始返回字符串
		@SystemMessage(fromResource = "xiaozhi-prompt-template.txt")
		String chat(@MemoryId Long memoryId, @UserMessage String userMessage);

}

这里指定了系统提示词,配置文件内容如下:

txt 复制代码
你的名字是"硅谷小智",你是一家名为"北京协和医院"的智能客服。
你是一个训练有素的医疗顾问和医疗伴诊助手。你态度友好、礼貌且言辞简洁。
1、请仅在用户发起第一次会话时,和用户打个招呼,并介绍你是谁。
2、作为一个训练有素的医疗顾问:
    请基于当前临床实践和研究,针对患者提出的特定健康问题,提供详细、准确且实用的医疗建议。请同时考虑可能的病
因、诊断流程、治疗方案以及预防措施,并给出在不同情境下的应对策略。对于药物治疗,请特别指明适用的药品名
称、剂量和疗程。如果需要进一步的检查或就医,也请明确指示。
3、作为医疗伴诊助手,你可以回答用户就医流程中的相关问题,主要包含以下功能:
    AI分导诊:根据患者的病情和就医需求,智能推荐最合适的科室。
    AI挂号助手:实现智能查询是否有挂号号源服务;实现智能预约挂号服务;实现智能取消挂号服务。
4、你必须遵守的规则如下:
    在获取挂号预约详情或取消挂号预约之前,你必须确保自己知晓用户的姓名(必选)、身份证号(必选)、预约科室
    (必选)、预约日期(必选,格式举例:2025-04-14)、预约时间(必选,格式:上午 或 下午)、预约医生(可选)。
    当被问到其他领域的咨询时,要表示歉意并说明你无法在这方面提供帮助。
5、请在回答的结果中适当包含一些轻松可爱的图标和表情。
6、今天是 {{current_date}}。

注意:这里暴露出来的为流式响应对象Flux<String>

java 复制代码
@Tag(name = "硅谷小智")
@RestController
@RequestMapping("/xiaozhi")
public class XiaozhiController {
    @Autowired
    private XiaozhiAgent xiaozhiAgent;

    @Operation(summary = "对话")
    @PostMapping("/chat")
    public String chat(@RequestBody ChatForm chatForm) {
        return xiaozhiAgent.chat(chatForm.getMemoryId(), chatForm.getMessage());
    }
}

由于我们引入了knife4j,我们可以直接通过访问:http://localhost:8080/doc.html#/-v3-api-docs/硅谷小智/chat

来进行测试验证接口。


二、实现用户记忆持久化存储

2.1、引入mongodb的pom依赖

这里我们用户持久化存储记忆会存储到mongodb,引入mongo依赖:

xml 复制代码
<!-- Spring Boot Starter Data MongoDB -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

2.2、创建用户聊天消息实体

java 复制代码
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import nonapi.io.github.classgraph.json.Id;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.mapping.Document;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Document("chat_messages")
public class ChatMessages {

    //唯一标识,映射到 MongoDB 文档的 _id 字段,可指定
    @Id
    private ObjectId messageId;
//    private Long messageId;
    private String content; //存储当前聊天记录列表的json字符串

}

2.3、mongodb的连接配置 & mongoService业务处理

application.properties:

properties 复制代码
#MongoDB
spring.data.mongodb.uri=mongodb://localhost:27017/chat_memory_db
java 复制代码
@Component
public class MongoChatMemoryStore implements ChatMemoryStore {

    @Autowired
    private MongoTemplate mongoTemplate;

    // 根据memoryId查询到一组聊天信息
    @Override
    public List<ChatMessage> getMessages(Object memoryId) {
        Criteria criteria = Criteria.where("memoryId").is(memoryId);
        Query query = new Query(criteria);
        ChatMessages chatMessages = mongoTemplate.findOne(query, ChatMessages.class);
        if(chatMessages == null) return new LinkedList<>();
        // 反序列化
        return ChatMessageDeserializer.messagesFromJson(chatMessages.getContent());
    }

    // 根据查询id,更新一组message
    @Override
    public void updateMessages(Object memoryId, List<ChatMessage> messages) {
        Criteria criteria = Criteria.where("memoryId").is(memoryId);
        Query query = new Query(criteria);
        Update update = new Update();
        update.set("content", ChatMessageSerializer.messagesToJson(messages));
        //根据query条件能查询出文档,则修改文档;否则新增文档
        mongoTemplate.upsert(query, update, ChatMessages.class);
    }

    // 根据memoryId删除一组聊天信息记录
    @Override
    public void deleteMessages(Object memoryId) {
        Criteria criteria = Criteria.where("memoryId").is(memoryId);
        Query query = new Query(criteria);
        mongoTemplate.remove(query, ChatMessages.class);
    }
}

2.4、持久化配置类ChatMemoryProvider

java 复制代码
@Configuration
public class XiaozhiAgentConfig {

    @Autowired
    private MongoChatMemoryStore mongoChatMemoryStore;

    @Bean
    ChatMemoryProvider chatMemoryProviderXiaozhi() {
        // 持久化存储,每个会话最大历史消息保存20条
        return memoryId -> MessageWindowChatMemory.builder()
                .id(memoryId)
                .maxMessages(20)
                .chatMemoryStore(mongoChatMemoryStore)
                .build();
    }
}

.

配置agent的记忆存储组件:

java 复制代码
@AiService(
        wiringMode = AiServiceWiringMode.EXPLICIT,
				chatModel = "qwenChatModel",
   		  chatMemoryProvider = "chatMemoryProviderXiaozhi",
)
public interface XiaozhiAgent {

    // 原始返回字符串
		@SystemMessage(fromResource = "xiaozhi-prompt-template.txt")
		String chat(@MemoryId Long memoryId, @UserMessage String userMessage);

}

三、实现function call 增强业务处理

3.1、目标说明

实现硅谷小智的查询订单、预约订单、取消订单的功能。

用于用户在聊天过程中的提问处理。

3.2、引入mybatisplus的pom依赖 & 配置文件参数

pom.xml:

xml 复制代码
<!-- Mysql Connector -->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
</dependency>
<!--mybatis-plus 持久层-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
    <version>${mybatis-plus.version}</version>
</dependency>

application.properties:

properties 复制代码
# mysql
spring.datasource.url=jdbc:mysql://localhost:3306/guiguxiaozhi?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# mybatis-plus
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

3.3、创建MySQL数据库表

sql 复制代码
CREATE DATABASE `guiguxiaozhi`;

USE `guiguxiaozhi`;

CREATE TABLE `appointment` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`username` VARCHAR(50) NOT NULL,
`id_card` VARCHAR(18) NOT NULL,
`department` VARCHAR(50) NOT NULL,
`date` VARCHAR(10) NOT NULL,
`time` VARCHAR(10) NOT NULL,
`doctor_name` VARCHAR(50) DEFAULT NULL,
PRIMARY KEY (`id`)
);

3.4、预约业务Mapper & service & mapper xml实现

实体类定义:

java 复制代码
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Appointment {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String username;
    private String idCard;
    private String department;
    private String date;
    private String time;
    private String doctorName;
}

mapper:

xml 复制代码
@Mapper
public interface AppointmentMapper extends BaseMapper<Appointment> {
}

// 对应xml配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.changlu.aixiaozhi.mapper.AppointmentMapper">
</mapper>

service:

java 复制代码
public interface AppointmentService extends IService<Appointment> {
    Appointment getOne(Appointment appointment);
}

@Service
public class AppointmentServiceImpl extends ServiceImpl<AppointmentMapper, Appointment>
        implements AppointmentService {
    /**
     * 查询订单是否存在
     *
     * @param appointment
     * @return
     */
    @Override
    public Appointment getOne(Appointment appointment) {
        LambdaQueryWrapper<Appointment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Appointment::getUsername, appointment.getUsername());
        queryWrapper.eq(Appointment::getIdCard, appointment.getIdCard());
        queryWrapper.eq(Appointment::getDepartment, appointment.getDepartment());
        queryWrapper.eq(Appointment::getDate, appointment.getDate());
        queryWrapper.eq(Appointment::getTime, appointment.getTime());
        Appointment appointmentDB = baseMapper.selectOne(queryWrapper);
        return appointmentDB;
    }
}

3.5、function calling Tools创建

AppointmentTools:预约挂号、取消挂号、查询是否有号源。

java 复制代码
// 预约工具类库
@Component
public class AppointmentTools {

    @Autowired
    private AppointmentService appointmentService;

//    @Tool(name = "预约挂号", value = "根据参数,先执行工具方法queryDepartment查询是否可预约,并直接给用户回答是否可预约,并让用户确认所有预约信息,用户确认后再进行预约。")
    @Tool(name="预约挂号", value = "根据参数,先执行工具方法queryDepartment查询是否可预约,并直接给用户回答是否可预约,并让用户确认所有预约信息,用户确认后再进行预约。" +
            "如果用户没有提供具体的医生姓名,请从向量存储中找到一位医生。") // 支持向量化场景时,可基于向量存储中搜索
    public String bookAppointment(Appointment appointment) {
        //查找数据库中是否包含对应的预约记录
        Appointment appointmentDB = appointmentService.getOne(appointment);
        if (appointmentDB == null) {
            appointment.setId(null);//防止大模型幻觉设置了id
            if (appointmentService.save(appointment)) {
                return "预约成功,并返回预约详情";
            } else {
                return "预约失败";
            }
        }
        return "您在相同的科室和时间已有预约";
    }

    @Tool(name = "取消预约挂号", value = "根据参数,查询预约是否存在,如果存在则删除预约记录并返回取消预约成功,否则返回取消预约失败")
    public String cancelAppointment(Appointment appointment) {
        Appointment appointmentDB = appointmentService.getOne(appointment);
        if (appointmentDB != null) {
        //删除预约记录
            if (appointmentService.removeById(appointmentDB.getId())) {
                return "取消预约成功";
            } else {
                return "取消预约失败";
            }
        }
        //取消失败
        return "您没有预约记录,请核对预约科室和时间";
    }

    @Tool(name = "查询是否有号源", value = "根据科室名称,日期,时间和医生查询是否有号源,并返回给用户")
    public boolean queryDepartment(
            @P(value = "科室名称") String name,
            @P(value = "日期") String date,
            @P(value = "时间,可选值:上午、下午") String time,
            @P(value = "医生名称", required = false) String doctorName) {
        System.out.println("查询是否有号源");
        System.out.println("科室名称:" + name);
        System.out.println("日期:" + date);
        System.out.println("时间:" + time);
        System.out.println("医生名称:" + doctorName);
        //TODO 维护医生的排班信息:
        //如果没有指定医生名字,则根据其他条件查询是否有可以预约的医生(有返回true,否则返回false;
        //如果指定了医生名字,则判断医生是否有排班(没有排版返回false)
        //如果有排班,则判断医生排班时间段是否已约满(约满返回false,有空闲时间返回true)
        return true;
    }

}

用于测试信息:

shell 复制代码
你帮我选个最好的医生吧,我的个人信息是:长路,320681200807430024,2025-04-23,上午

3.6、智能体agent增强

java 复制代码
@AiService(
        wiringMode = AiServiceWiringMode.EXPLICIT,
				chatModel = "qwenChatModel",
   		  chatMemoryProvider = "chatMemoryProviderXiaozhi",
  			tools = "appointmentTools", // tools配置
)
public interface XiaozhiAgent {

    // 原始返回字符串
		@SystemMessage(fromResource = "xiaozhi-prompt-template.txt")
		String chat(@MemoryId Long memoryId, @UserMessage String userMessage);

}

四、实现RAG增量

4.1、引入pom.xml依赖(pinecone) & 向量模型配置

xml 复制代码
<!--简单的rag实现
    出现报错embeddingModel cannot be null,需要引入该rag实现
-->
<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-easy-rag</artifactId>
</dependency>

<!-- pinecone向量       -->
<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-pinecone</artifactId>
</dependency>

application.properties:

properties 复制代码
#集成阿里通义千问-通用文本向量-v3
langchain4j.community.dashscope.embedding-model.api-key=${DASH_SCOPE_API_KEY}
langchain4j.community.dashscope.embedding-model.model-name=text-embedding-v3

4.2、向量模型选择与配置

向量模型选择的是阿里通义千问-通用文本向量-v3。

配置了4.1参数之后,注入的实体向量模型就是选择了对应的通用文本向量:

java 复制代码
@Autowired
private EmbeddingModel embeddingModel;

4.3、向量数据库配置集成

需要引入pom:其中有内置embeddingModel向量模型实现

xml 复制代码
<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-easy-rag</artifactId>
</dependency>
java 复制代码
@Autowired
private EmbeddingStore embeddingStore;
@Autowired
private EmbeddingModel embeddingModel;

@Bean
ContentRetriever contentRetrieverXiaozhiPincone() {
    // 方案2:pinecone向量数据库+向量模型
    // 创建一个 EmbeddingStoreContentRetriever 对象,用于从嵌入存储中检索内容
    return EmbeddingStoreContentRetriever
            .builder()
            // 设置用于生成嵌入向量的嵌入模型
            .embeddingModel(embeddingModel)
            // 指定要使用的嵌入存储
            .embeddingStore(embeddingStore)
            // 设置最大检索结果数量,这里表示最多返回 1 条匹配结果
            .maxResults(1)
            // 设置最小得分阈值,只有得分大于等于 0.8 的结果才会被返回
            .minScore(0.8)
            // 构建最终的 EmbeddingStoreContentRetriever 实例
            .build();
}

4.4、智能体agent再次增强向量数据库

同时需要在agent接口上配置好:

java 复制代码
@AiService(
        wiringMode = AiServiceWiringMode.EXPLICIT,
				chatModel = "qwenChatModel",
   		  chatMemoryProvider = "chatMemoryProviderXiaozhi",
  			tools = "appointmentTools", // tools配置
 			  contentRetriever = "contentRetrieverXiaozhiPincone" //配置向量存储基于向量数据库
)
public interface XiaozhiAgent {

    // 原始返回字符串
		@SystemMessage(fromResource = "xiaozhi-prompt-template.txt")
		String chat(@MemoryId Long memoryId, @UserMessage String userMessage);

}

4.5、提前将文本上传向量数据库:上传文件单测

上传的文本如下:

单测编写如下:

.

java 复制代码
@SpringBootTest
public class PineConeTest {

    @Autowired
    private EmbeddingStore embeddingStore;
    @Autowired
    private EmbeddingModel embeddingModel;

    /**
     * 上传向量数据库
     */
    @Test
    public void testUploadKnowledgeLibrary() {
        String documentDir = System.getProperty("user.dir") + "/documents/";
        //使用FileSystemDocumentLoader读取指定目录下的知识库文档
        //并使用默认的文档解析器对文档进行解析
        Document document1 = FileSystemDocumentLoader.loadDocument(documentDir + "医院信息.md");
        Document document2 = FileSystemDocumentLoader.loadDocument(documentDir + "科室信息.md");
        Document document3 = FileSystemDocumentLoader.loadDocument(documentDir + "神经内科.md");
        List<Document> documents = Arrays.asList(document1, document2, document3);
        //文本向量化并存入向量数据库:将每个片段进行向量化,得到一个嵌入向量
        EmbeddingStoreIngestor
                .builder()
                .embeddingStore(embeddingStore)
                .embeddingModel(embeddingModel)
                .build()
                .ingest(documents);
    }

}

自动新建index,新建namespace:


4.6、测试验证是否搜索向量数据库

通过查看mogodb,可以发现用户在询问问题的过程中,就自动会涉及到向量化检索,同时会将问题 & 检索到的内容一并发给ai模型,来进行语言话处理:

**接着是用户发器的一次对ai的请求:**你可以发现,在我们的问题之后,会带有向量话搜索后的提示信息,从而ai能够很好的组织语言将精确的信息内容发送给用户

等同于我们对ai发送了下面这一段话,这个设计思路属实非常nice:


回答的非常好:

五、改造流式输出

5.1、引入pom依赖

xml 复制代码
<!--流式输出-->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
  <groupId>dev.langchain4j</groupId>
  <artifactId>langchain4j-reactor</artifactId>
</dependency>

5.2、选择流式输出模型配置参数

application.properties:

properties 复制代码
# 百炼平台 千问-流式输出
langchain4j.community.dashscope.streaming-chat-model.api-key=${DASH_SCOPE_API_KEY}
langchain4j.community.dashscope.streaming-chat-model.model-name=qwen-plus

5.2、改造agent接口 & controller响应

java 复制代码
@AiService(
        wiringMode = AiServiceWiringMode.EXPLICIT,
//        chatModel = "qwenChatModel",
        streamingChatModel = "qwenStreamingChatModel", // 流式模型
        chatMemoryProvider = "chatMemoryProviderXiaozhi",
        tools = "appointmentTools", // tools配置
        contentRetriever = "contentRetrieverXiaozhiPincone" //配置向量存储基于向量数据库
)
public interface XiaozhiAgent {

    // 原始返回字符串
//    @SystemMessage(fromResource = "xiaozhi-prompt-template.txt")
//    String chat(@MemoryId Long memoryId, @UserMessage String userMessage);

    // 流式返回
    @SystemMessage(fromResource = "xiaozhi-prompt-template.txt")
    Flux<String> chat(@MemoryId Long memoryId, @UserMessage String userMessage);


}
java 复制代码
@Tag(name = "硅谷小智")
@RestController
@RequestMapping("/xiaozhi")
public class XiaozhiController {
    @Autowired
    private XiaozhiAgent xiaozhiAgent;

//    @Operation(summary = "对话")
//    @PostMapping("/chat")
//    public String chat(@RequestBody ChatForm chatForm) {
//        return xiaozhiAgent.chat(chatForm.getMemoryId(), chatForm.getMessage());
//    }

    @Operation(summary = "对话")
    @PostMapping(value = "/chat", produces = "text/stream;charset=utf-8")
    public Flux<String> chat(@RequestBody ChatForm chatForm) {
        return xiaozhiAgent.chat(chatForm.getMemoryId(), chatForm.getMessage());
    }

}

六、前端ui运行,跑通

shell 复制代码
npm install

npm run dev

正常访问聊天即可


额外:ai大模型本地部署

相关技术栈:

  • java大模型框架:langchain4j
  • ai模型:ollama-deepseek
  • ai向量化模型:ollama-bge-large
  • ai向量化存储:chroma,本地化部署

实战项目:

langchain4j相关案例:


整理者:长路 时间:2025.5.27

资料获取

大家点赞、收藏、关注、评论啦~

精彩专栏推荐订阅:在下方专栏👇🏻

更多博客与资料可查看👇🏻获取联系方式👇🏻,🍅文末获取开发资源及更多资源博客获取🍅

相关推荐
带娃的IT创业者1 天前
解密OpenClaw系列08-OpenClaw组件交互关系(2)
软件工程·ai编程·代码规范·ai智能体·openclaw·编程文档·组件设计
小灵不想卷1 天前
LangChain4j 与 SpringBoot 整合
java·后端·langchain4j
TGITCIC3 天前
AI Agent中的 ReAct 和 Ralph Loop对比说明
人工智能·ai大模型·ai agent·ai智能体·agent开发·大模型ai·agent设计模式
yonlingxu4 天前
AI智能体正在吃掉软件,但最大的猎物藏在私域里
ai智能体
TGITCIC5 天前
整理了一套可落地的验证指标体系给到大家
算法·chunk·ai agent·ai智能体·rag增强检索·rag chunk·rag分片
云蝠呼叫大模型联络中心5 天前
从IVR到AI智能体:语音交互技术的三次革命
ai智能体·ivr·多模态交互·语音交互革命·云蝠智能·voiceagent 2.0·实时推理
TGITCIC5 天前
RAG不是万能的,但没有RAG是万万不能的:8种主流架构全景解析
rag·ai agent·ai智能体·ai开发·ai agent开发·rag增强检索·rag架构
deephub6 天前
软件工程原则在多智能体系统中的应用:分层与解耦
人工智能·python·软件工程·大语言模型·ai智能体
Light608 天前
MCP:AI智能体时代的“USB-C接口“,微调终结者还是效率革命?
工具调用·ai智能体·mcp协议·企业ai·上下文管理·微调替代·标准化接口