(9)批量生成文章并同步存入 MySQL 和 Redis

目录

利用我现有的 Java 业务逻辑,结合大模型(LLM)自动生成能力,编写一个集成测试类。


🍥一、技术选型

  1. LangChain4j (ChatLanguageModel):调用我本地的 Ollama (Gemma 3),让它扮演不同领域的学者。
  2. Spring Boot Test / CommandLineRunner:用于触发批量执行逻辑。
  3. 现有业务 Service (PostService):直接复用我写好的 publishArticle 方法。

🍥二、具体实现步骤(附流程图)

  1. 准备种子数据(学科与用户)
    在数据库里先手动准备好几个用户(User ID: 1, 2, 3...)和话题(Topic ID: 1, 2, 3...)。
  2. 编写批量生成脚本 (DataGeneratorService)
    在 src/test/java 下或者 service 包下创建一个工具类。
  3. 写一个单元测试来触发脚本

🍥三、核心代码实现

1. 文章生成Prompt设计

需要考虑能被程序解析所以提示词中采用格式约束,减少数据清洗的成本。

java 复制代码
// 在 DataGeneratorService 中定义指令模板
String promptTemplate = """
    你是一个【%s】领域的资深专家。
    请撰写一篇前沿的学术博客,要求:
    1. 标题必须具有专业性(包含行业黑话)。
    2. 正文约300字,逻辑严密,描述该领域的一个具体技术问题或趋势。
    3. 严格遵守输出格式,不得包含任何开场白:
       标题: [此处填标题]
       内容: [此处填正文]
    """;

// 调用时动态注入学科名称
String finalPrompt = String.format(promptTemplate, topic.getName());
String aiResponse = chatModel.generate(finalPrompt);

2. 数据解析逻辑

大模型的输出有时会带有不可控的空格或换行,直接解析容易报错。于是我利用较为健壮的边界搜索算法提取核心内容。

利用try-catch 捕获和边界判定。

java 复制代码
/**
 * 健壮的文本提取逻辑
 * @param text  LLM返回的全文本
 * @param start 标识符(如"标题:")
 * @param end   结束标识符(如"内容:")
 */
private String parse(String text, String start, String end) {
    try {
        int startIndex = text.indexOf(start);
        if (startIndex == -1) return "未知标题";
        startIndex += start.length();

        int endIndex = (end == null || text.indexOf(end) == -1) 
                       ? text.length() 
                       : text.indexOf(end);

        // 过滤首尾空格及特殊字符
        return text.substring(startIndex, endIndex).trim();
    } catch (Exception e) {
        log.error("解析文本块失败: {}", e.getMessage());
        return "数据解析异常";
    }
}

3. 自动化的Ingestion Pipeline(双路写入)

这是整个流程的灵魂:复用生产环境的业务逻辑。通过调用现有的 postService,确保了每一条合成数据都完美经历了 MySQL 持久化与 Redis 向量化。

利用 MyBatis 的 useGeneratedKeys,使向量库中的 articleId 元数据与 MySQL 的自增 ID 严丝合缝地关联(PostMapper.xml中)。

java 复制代码
public void generateBatchData(int countPerTopic) {
        // 1. 动态获取数据库里现有的所有分类
        List<Topic> dbTopics = topicMapper.findAll();
        if (dbTopics.isEmpty()) {
            System.err.println("❌ 数据库 topic 表是空的,请先添加分类!");
            return;
        }

        for (Topic topic:dbTopics) {
            for (int i = 0; i < countPerTopic; i++) {
                // 1. 让 AI 产生一篇伪学术文章
                String prompt = String.format(
                        "你是一个%s领域的专家。请写一篇简短的学术博客。要求:" +
                                "1. 标题新颖且具有专业性。2. 正文约300-500字,包含具体的专业术语。3. 只返回结果,格式为 标题:xxx 内容:xxx",
                        topic.getTitle()
                );

                String aiResponse = chatModel.generate(prompt);


                // 构造 Post 对象
                Post post = new Post();
                post.setTitle(parse(aiResponse, "标题:", "内容:"));
                post.setContent(parse(aiResponse, "内容:", null));

                // 2. 使用数据库里真实的 ID
                post.setTopic_id(topic.getId());

                // 设置一个默认的 userID(确保该用户在 user 表里存在)
                post.setUser_id(1L);

                // 4. ⭐ 触发核心业务逻辑
                // 此处会同步触发:MySQL保存 -> 文本切片 -> 语义向量化 -> RedisStack存入
                postService.publishArticle(post);

                System.out.println("已为分类 [" + topic.getTitle() + "] 生成文章");
            }
        }
    }

🍥四、效果展示

前端:

Redis Stack:

相关推荐
czlczl200209254 小时前
理解 MySQL 行锁:两阶段锁协议与热点更新优化
数据库·mysql
AllData公司负责人4 小时前
通过Postgresql同步到Doris,全视角演示AllData数据中台核心功能效果,涵盖:数据入湖仓,数据同步,数据处理,数据服务,BI可视化驾驶舱
java·大数据·数据库·数据仓库·人工智能·python·postgresql
哆啦A梦15884 小时前
20, Springboot3+vue3实现前台轮播图和详情页的设计
javascript·数据库·spring boot·mybatis·vue3
渣渣盟5 小时前
Mysql入门到精通全集(SQL99)包含关系运算,软考数据库工程师复习首选
数据库·mysql·oracle
dishugj5 小时前
HANA 数据库的核心进程架构
数据库
2301_782040455 小时前
CSS Flex布局中如何实现导航栏与Logo的左右分布_利用justify-content- space-between
jvm·数据库·python
.柒宇.6 小时前
Redis主从复制集群搭建详解
数据库·redis·缓存·主从复制
2301_808414386 小时前
MySQL中的函数
数据库·mysql
Mahir086 小时前
MySQL 数据一致性的基石:三大日志( redo log/undo log/binlog)与两阶段提交(Prepare 阶段和Commit 阶段)深度解密
数据库·后端·mysql·面试
x***r1517 小时前
dbeaver-ce-24.1.3-x86_64-setup安装步骤详解(附DBeaver数据库管理与SQL编写教程)
数据库·sql