all-in-rag 实战:从「尖叫牛蛙」菜谱到 C8 尝尝咸淡 RAG 系统的结构化数据源解析
2026/9/24 5:40:37 网站建设 项目流程
  • 教程
  • 人工智能
  • 大模型
  • RAG

【免费下载链接】all-in-rag

🔍大模型应用开发实战一:RAG 技术全栈指南,在线阅读地址:https://datawhalechina.github.io/all-in-rag/

项目地址:https://gitcode.com/datawhalechina/all-in-rag
点击查看免费下载

本篇以 all-in-rag 仓库 C8 章实战项目(尝尝咸淡 RAG 系统)中的一份典型菜谱文档「尖叫牛蛙」为核心样本,完整还原其原料清单、用量计算与烹饪操作全流程,并深入剖析这类 Markdown 菜谱文档如何在 数据准备模块 中被加载、增强元数据、按标题分块,最终经混合检索与查询路由支撑起"今天吃什么"的智能问答。读完本文,你将掌握一份结构化菜谱从"静态 Markdown 文件"到"可检索可问答的知识库单元"的完整链路,并可直接对照源码复现。

一、菜谱文档在仓库中的定位

在 all-in-rag 仓库的 C8 章中,构建了一个名为"尝尝咸淡 RAG 系统"的食谱智能问答项目,其灵感来自社区菜谱仓库 HowToCook——用统一 Markdown 格式记录菜品制作方法。仓库将所有菜谱数据组织在data/C8/cook/dishes/下,按菜品分类建目录,例如:

  • meat_dish/(荤菜)
  • vegetable_dish/(素菜)
  • soup/(汤品)
  • dessert/(甜品)
  • aquatic/(水产)
  • breakfast/(早餐)
  • staple/(主食)
  • condiment/(调料)
  • drink/(饮品)

本文要讲的「尖叫牛蛙」就位于data/C8/cook/dishes/meat_dish/尖叫牛蛙/尖叫牛蛙.md,是一道典型的"荤菜"四星难度(困难级)菜谱。对照data/C8/cook/dishes/template/示例菜/示例菜.md模板可知,仓库对每道菜谱的文件结构有严格要求:标题统一为"菜名 + 的做法"、正文按"必备原料和工具 / 计算 / 操作 / 附加内容"四个二级标题组织、难度用 ★ 数量表达。这种高度规整的结构,正是后文 RAG 分块与元数据提取能够"开箱即用"的前提。

二、尖叫牛蛙菜谱全解:原料、用量与操作

2.1 菜品简介与难度

尖叫牛蛙是一道容易上手的菜,一般初学者 1-2 小时即可完成。味道鲜美且具有开胃功效,特别适合食欲不佳时食用,老少皆宜(能吃辣者更佳)。原文档给出的难度评级为:

预估烹饪难度:★★★★

四星对应仓库源码中的"困难"等级——在 data_preparation.py 的_enhance_metadata中,通过正则re.search(r'★+', content)精确匹配连续星号数量,再按映射{5: '非常困难', 4: '困难', 3: '中等', 2: '简单', 1: '非常简单'}自动生成难度元数据,这意味着尖叫牛蛙文档入库后会被自动打上difficulty = 困难的标签。

2.2 必备原料和工具

原文档列出的原料清单如下(共 15 项),请按此准备:

  • 牛蛙肉
  • 泡姜
  • 泡椒
  • 野山椒(也可以用干红辣椒替代)
  • 青红辣椒
  • 大蒜
  • 豆瓣酱(推荐郫县豆瓣)
  • 盐巴
  • 胡椒粉
  • 生粉(干淀粉也可)
  • 啤酒(推荐雪花)
  • 料酒
  • 藤椒油(可选)
  • 猪油(可选)
  • 葱花

2.3 用量计算(每份)

本菜固定按 1 份制作,每份精确用量如下,请完整保留:

原料用量说明
牛蛙肉块800g买 3 斤活蛙,建议挑小个头,肉质更鲜嫩
泡姜20-30 克看口味,重口可多放
泡椒5-10 克视吃辣承受能力,不能吃辣建议减半至 2.5 克(微微辣)
野山椒10 克
青红辣椒20 克
大蒜30-50 克按口味调整,最好不低于 30 克
豆瓣酱20-30 克重口选 30 克,清淡选 20 克(这道菜很难太清淡)
盐巴15 克其中腌制阶段分两次使用(见操作)
胡椒粉10 克腌制用 5 克,焖煮用 5 克
啤酒400-500ml去腥抓洗用 50ml 以上,焖煮用 400ml
料酒10ml腌制用
藤椒油5-10ml可选,焖煮阶段加 5ml
生粉30 克干淀粉可平替,腌制裹粉用
猪油20ml没有可用食用油替代
食用油200ml宽油过油用,锅底平可再加 100ml,另保留 50ml 炒料
葱花5 克出锅点缀

2.4 操作步骤(完整版)

原文档共 10 步,是这道菜的灵魂,逐条保留如下:

  1. 牛蛙肉洗净后控干水分,加入 10 克以上的盐巴和 50ml 以上的啤酒,用手抓 5 分钟,去除牛蛙肉的腥味。
  2. 对着清水冲洗,直至不再流出血水和杂质,控干水分,放到合适的器皿中,准备腌制。
  3. 加入 5 克盐、30 克生粉、10ml 料酒、5 克胡椒粉,用手抓均匀,腌制 5-10 分钟。
  4. 将泡姜、泡椒、野山椒切丝或切片(根据自己刀工选择),青红辣椒切成圈圈,大蒜拨开即可。
  5. 起锅烧热,加入 200ml 食用油(锅底比较平的可以再加 100ml),烧至 6 成油温(有小气泡出现),将腌制好的牛蛙倒入,快速过油炸制,10 秒钟后捞出(不能超时太多,否则蛙肉会老柴)。
  6. 捞出蛙肉后控油,并将锅中的热油倒出到碗中,保留 30ml,加入 20ml 猪油(如果没有,则在锅中保留总共 50ml 食用油)。
  7. 待油温 6 成热,加入泡姜、泡椒、野山椒、大蒜,炒出香味,加入豆瓣酱 20 克,中火翻炒至出红油(时间控制在 30 秒),倒入 400ml 啤酒。
  8. 倒入炸过的牛蛙肉,用勺子推着翻,不要用力搅拌,加入 5 克胡椒粉,加入 5ml 藤椒油,中火慢焖 3 分钟。
  9. 加大火力,大火收汁半分钟,加入青红辣椒圈,再煮 10 秒准备起锅。
  10. 盛到盆里,撒上葱花,开动!

2.5 附加技巧

  • 控干水分的时候可以选择漏勺按压。
  • 生粉抓揉时要均匀覆盖蛙肉。

三、从菜谱到知识库:源码级数据链路解析

一份像「尖叫牛蛙」这样的菜谱 Markdown 文档,是如何进入 RAG 知识库并被检索问答的?C8 项目的 main.py 在build_knowledge_base()中依次调用数据准备、索引构建模块完成入库,链路如下。

3.1 数据加载与元数据增强

data_preparation.py 的load_documents()会递归遍历data_path(默认../../data/C8/cook,见 config.py)下所有.md文件,直接读取原文保持 Markdown 格式,并为每个文档生成基于相对路径的确定性 MD5parent_id

随后_enhance_metadata()依据文件路径与内容自动打标签:

  • 分类(category):通过路径片段匹配CATEGORY_MAPPING,命中meat_dish即标记为"荤菜";
  • 菜名(dish_name):取文件名去扩展名,即"尖叫牛蛙";
  • 难度(difficulty):用正则★+精确匹配连续星号,4 颗星映射为"困难"。

于是用户问"有没有困难的荤菜"时,系统即可通过metadata_filtered_search直接过滤出此类文档——这正是 main.py 中_extract_filters_from_query做的事:从问题中识别分类关键词(荤菜/素菜/汤品…)与难度关键词(非常简单/简单/中等/困难/非常困难),组合成过滤条件。

3.2 Markdown 结构感知分块

chunk_documents()使用MarkdownHeaderTextSplitter按标题层级分块:

headers_to_split_on = [ ("#", "主标题"), # 菜品名称 ("##", "二级标题"), # 必备原料、计算、操作等 ("###", "三级标题") # 简易版本、复杂版本等 ]

并设置strip_headers=False保留标题便于理解上下文。以尖叫牛蛙为例,会被分割成"主标题(菜名+简介+难度)""必备原料和工具""计算""操作""附加内容"等若干子块,每个子块继承父文档元数据,并建立chunk_id -> parent_id的父子映射。这对应 01_env_architecture.md 中强调的设计理念——"小块检索、大块生成":用小而精确的子块匹配具体问题(如"尖叫牛蛙需要什么调料"命中"必备原料和工具"),生成阶段再通过get_parent_documents()取回完整父文档,保证上下文完整。

3.3 混合检索与 RRF 重排

retrieval_optimization.py 中hybrid_search()同时执行 FAISS 向量检索(embedding 模型为BAAI/bge-small-zh-v1.5)与 BM25 关键词检索,各取 5 个候选,再用 RRF(Reciprocal Rank Fusion)融合:

rrf_score = 1.0 / (k + rank + 1) # k = 60

按融合分数排序后截取top_k(默认 3)返回。向量检索负责语义,BM25 负责精确关键词,两者互补,确保"尖叫牛蛙怎么做"这类口语化问题也能稳定命中。

3.4 查询路由与生成

generation_integration.py 的query_router()将用户问题分为三类:

  • list:要菜品列表/推荐(如"推荐几个简单的素菜");
  • detail:要具体做法(如"尖叫牛蛙怎么做")——命中后走generate_step_by_step_answer,LLM 会按"菜品介绍 / 所需食材 / 制作步骤 / 制作技巧"输出结构化答案;
  • general:其他一般性问题。

detailgeneral查询还会先经过query_rewrite()做智能重写(具体明确的查询保持原样,模糊查询补全烹饪术语)。最终由配置中的kimi-k2-0711-preview模型(config.py,temperature=0.1, max_tokens=2048)结合检索到的完整父文档生成答案。读者可运行python code/C8/main.py(需配置MOONSHOT_API_KEY)体验,交互式提问"尖叫牛蛙怎么做"即可得到基于本文菜谱的分步指导。

四、小结

「尖叫牛蛙」这份菜谱文档,既是可独立照做的家常菜教程,也是 C8 尝尝咸淡 RAG 系统中一个结构规范、标签完整的知识库样本:路径决定分类、星级决定难度、标题决定分块、正文决定检索质量。对照 data_preparation.py、retrieval_optimization.py、generation_integration.py 与 main.py 源码,可以完整复现从"静态菜谱"到"可问答知识库"的每一个环节。想要扩展菜谱库时,只需参照 示例菜模板 的结构新增 Markdown 文件并重启系统重建索引即可,无需改动任何代码。

  • 教程
  • 人工智能
  • 大模型
  • RAG

【免费下载链接】all-in-rag

🔍大模型应用开发实战一:RAG 技术全栈指南,在线阅读地址:https://datawhalechina.github.io/all-in-rag/

项目地址:https://gitcode.com/datawhalechina/all-in-rag
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询