案例:Spring AI + RAG 打造“啤酒推荐师”

293 阅读2分钟

🍺 案例:Spring AI + RAG 打造“啤酒推荐师”

——AI调酒师在线营业,比人类更懂IPA配烤肉


1. 场景设定:啤酒界的“百科全书”

想象一个场景:用户问“什么啤酒配烟熏肉最合适?”,传统大模型可能只会回答“试试深色啤酒”——这就像让一个只喝过白开水的人推荐红酒。但结合RAG的Spring AI,瞬间变身“啤酒老饕”,能精准推荐“Smoked Porter Ale,酒精度8%,苦度36 IBU,带有咖啡和摩卡风味,完美搭配烟熏肉的油脂感”。


2. 数据准备:22,000种啤酒的“知识库”

数据来源:一个包含啤酒名称、酒精度(ABV)、苦度(IBU)、描述的JSON数据集,比如:

{  
  "id": "00gkb9",  
  "name": "Smoked Porter Ale",  
  "description": "The Porter Pounder...dry hopping",  
  "abv": 8,  
  "ibu": 36  
}  

加载到Redis:通过RagDataLoader类,在应用启动时将数据转换为向量并存入Redis:

// 创建JSON阅读器,指定关键字段  
JsonReader loader = new JsonReader(file, "name", "abv", "ibu", "description");  
// 自动注入VectorStore,将文档插入Redis  
vectorStore.add(loader.get());  

至此,Redis中已存储了22,000种啤酒的“风味密码”。


3. 代码实现:四步搞定RAG流程

① RAG服务层RagService类处理用户查询,核心代码如下:

public Generation retrieve(String message) {  
    // 1. 检索最相关的啤酒文档  
    List<Document> docs = store.similaritySearch(SearchRequest.query(message).withTopK(5));  
    // 2. 构建提示词模板,结合上下文和用户问题  
    Prompt prompt = new Prompt(List.of(  
        new SystemMessage("你是一个啤酒专家,根据以下信息回答:" + docs),  
        new UserMessage(message)  
    ));  
    // 3. 调用大模型生成回答  
    return client.call(prompt).getResult();  
}  

② 对外接口:通过RagController暴露HTTP端点:

@PostMapping("/chat")  
public Message recommendBeer(@RequestBody String question) {  
    return Message.of(ragService.retrieve(question).getContent());  
}  

4. 效果演示:AI的“精准投喂”

用户提问

curl http://localhost:8080/chat -d "What beer pairs well with smoked meats?"  

AI响应

推荐IPA或烟熏波特艾尔!

  • Smoked Porter Ale(ABV 8%,IBU 36):烟熏麦芽与咖啡风味,完美平衡烟熏肉的油腻感。
  • Son of Berserker Stout(ABV 6.9%):厚重口感搭配烟熏肉,仿佛在北欧篝火旁狂欢。

5. 技术亮点:Spring AI的“骚操作”

  • 向量检索:利用Redis的语义搜索能力,秒级定位相关啤酒。
  • 动态提示词:将检索结果嵌入提示词,让大模型“有的放矢”,避免胡说八道。
  • 低成本高精度:相比直接喂给大模型长文本,RAG处理1000万字仅需$0.11,成本降低千倍。

6. 彩蛋:AI的“职业病”

如果你问“怎么选西瓜?”,这位“啤酒推荐师”可能会回答:“根据我的啤酒数据库,西瓜汁配小麦啤酒更解渴哦!”——毕竟,它连挑瓜都要先查资料!