Datawhale all-in-rag 食谱数据实战:以「小炒肉」为例的 Markdown 结构化菜谱与 RAG 全链路解析
2026/9/23 14:45:34 网站建设 项目流程
  • 教程
  • 人工智能
  • 大模型
  • RAG

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

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

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

导读

本文以开源仓库 Datawhale all-in-rag 的 C8 章节食谱知识库中的 小炒肉.md 为分析样本,完整还原这道湘式家常菜从原料配比、腌制到出锅的 10 步做法,并以此为窗口,深入解析该菜谱文档在仓库 RAG(检索增强生成)系统中所扮演的数据角色:Markdown 结构感知分块、难度星级元数据解析、混合检索(向量 + BM25 + RRF)与分步骤回答生成的全链路机制。读完本文,你既能照着做出地道的小炒肉,也能理解一份食谱文档如何被「烹饪式」地加工成可检索、可回答的 RAG 知识库语料。

一、小炒肉食谱文档在项目中的定位

小炒肉食谱是 data/C8 食谱数据集下meat_dish(荤菜)分类的一篇标准 Markdown 菜谱。在仓库的目录设计中,每道菜都以独立 Markdown 文件存放,路径本身携带了分类信息:

  • 分类依据:路径中的目录名meat_dish会被映射为「荤菜」;
  • 菜品名称:文件名小炒肉会被提取为dish_name元数据;
  • 难度等级:文档正文中的星级★★★会被解析为「中等」。

这份文档是 code/C8 中「尝尝咸淡」食谱 RAG 系统的输入语料之一。整个系统围绕data/C8/cook下的全部菜谱构建索引,用户提问「小炒肉怎么做」「推荐几个荤菜」时,系统会先检索相关菜谱,再由大模型组织回答。

二、必备原料与工具清单

原文档完整罗列了制作小炒肉所需的原料与调料(摘自 小炒肉.md):

  • 五花肉
  • 朝天椒
  • 小米椒
  • 豆豉
  • 豆瓣酱
  • 老抽
  • 淀粉

从配料结构看,这是一道典型的「干煸五花 + 双椒 + 豉香」风味菜:朝天椒提供干香,小米椒提供鲜辣,豆豉与豆瓣酱叠加发酵酱香,老抽上色、淀粉锁水,是湘式小炒中「煸香 + 酱香 + 辣香」三味合一的代表做法。

三、每份用量计算(原料配比表)

原文档按「每份」给出精确配比(摘自 小炒肉.md):

原料用量(每份)备注
五花肉500g主料,建议选肥瘦相间的三层五花
朝天椒4 条干香辣味
小米椒4 颗鲜辣味
豆豉10g可根据个人口味 ±5g
豆瓣酱10g可根据个人口味 ±5g
老抽10ml上色
淀粉10g腌制用,锁住肉汁
1-2g腌制底味
0.5-1 根切段,出锅前增香
2 瓣煸香
食用油15ml煸炒用油

配比要点:豆豉与豆瓣酱均给出 ±5g 的浮动空间,说明这两味酱料是风味弹性最大的变量——喜重口可加到 15g,喜清淡可减至 5g;盐仅需 1-2g,因为豆瓣酱与豆豉本身含盐,腌制时注意不要过咸。

四、分步操作:10 步还原小炒肉

原文档的完整操作步骤(摘自 小炒肉.md):

  1. 切肉:五花肉切片。建议切成 2-3mm 的薄片,肥瘦相连,便于快速煸出油脂。
  2. 腌制:肉片放入器皿,加入淀粉、老抽、盐搅拌,腌制半小时。淀粉 + 老抽 + 盐的腌料组合既上色又保水,半小时的静置让肉片充分吸收底味。
  3. 备葱:葱切段。
  4. 备椒:小米椒、朝天椒斜刀切好。斜刀切法增大辣椒与热油的接触面积,更易释放辣味与香气。
  5. 热锅:热锅、倒油(15ml)。
  6. 煸肉:油热后加入五花肉煸炒,炒至变色后盛出。这一步目的是逼出五花肉部分油脂,使肉片边缘微焦、口感干香。
  7. 煸料头:锅中加蒜煸出香味,加入豆豉翻炒均匀。豆豉需经油温激发才会释放豉香。
  8. 下酱:加入豆瓣酱翻炒均匀。豆瓣酱需炒出红油,酱香才充分。
  9. 合炒:加入炒好的五花肉继续翻炒均匀,让肉片均匀裹上酱料。
  10. 收尾:加入小米椒、朝天椒、葱段翻炒 40 秒后出锅。辣椒与葱段不宜久炒,40 秒恰好断生并保持脆感。

五、从菜谱到语料:Markdown 结构感知分块

小炒肉这道菜谱之所以能被 RAG 系统有效检索,关键在于其规范的 Markdown 标题结构。仓库的数据准备模块 data_preparation.py 使用MarkdownHeaderTextSplitter按三级标题分块:

headers_to_split_on = [ ("#", "主标题"), # 菜品名称 ("##", "二级标题"), # 必备原料、计算、操作等 ("###", "三级标题") # 简易版本、复杂版本等 ] markdown_splitter = MarkdownHeaderTextSplitter( headers_to_split_on=headers_to_split_on, strip_headers=False # 保留标题,便于理解上下文 )

对应到小炒肉文档,它会被切分为「主标题(小炒肉的做法)」「二级标题(必备原料和工具)」「二级标题(计算)」「二级标题(操作)」等独立 chunk。strip_headers=False意味着每个 chunk 都保留标题文本,使检索到的片段自带语义上下文——当用户问「小炒肉需要什么原料」时,系统能直接命中「必备原料和工具」这一块。

分块后,每个子块还会被打上chunk_idparent_idchunk_index等元数据,并维护parent_child_map父子映射(见 data_preparation.py),为后续「检索子块 → 回溯完整菜谱」的小块召回 / 父文档生成(Parent Document Retrieval)模式奠定基础。

六、元数据增强:星级如何变成「中等」

数据准备模块会对每篇菜谱自动增强元数据(见 data_preparation.py):

# 提取菜品分类:路径含 meat_dish → '荤菜' # 提取菜品名称:文件名 小炒肉 → '小炒肉' # 分析难度等级(使用正则精确匹配连续星号数量) star_match = re.search(r'★+', content) if star_match: star_count = len(star_match.group()) difficulty_map = {5: '非常困难', 4: '困难', 3: '中等', 2: '简单', 1: '非常简单'} doc.metadata['difficulty'] = difficulty_map.get(star_count, '未知')

小炒肉文档开头的「预估烹饪难度:★★★」会被正则★+匹配到连续 3 颗星,从而映射为难度「中等」。这解释了菜谱文档为什么约定用连续星号而非「三颗星」之类的文字表述——星号长度可直接被正则计算,是机器友好的难度编码方式。

增强后的元数据(category=荤菜dish_name=小炒肉difficulty=中等)会随子块一并进入向量索引,并被检索阶段的元数据过滤和回答生成阶段的上下文格式化所复用。

七、检索与生成:小炒肉如何被「回答」出来

7.1 混合检索 + RRF 重排

索引构建模块 index_construction.py 使用BAAI/bge-small-zh-v1.5嵌入模型在 CPU 上完成向量化,并构建 FAISS 索引;检索优化模块 retrieval_optimization.py 则同时启用向量检索与 BM25 检索,再用 RRF(Reciprocal Rank Fusion)融合排序:

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

当用户问「小炒肉怎么做」时,向量检索负责语义匹配「做法 / 操作」类片段,BM25 则精确命中「小炒肉」这一关键词,两者经 RRF 融合后按 config.py 中的top_k=3返回 Top-3 子块。

7.2 查询路由与分步骤回答

主程序 main.py 在检索前先用大模型对问题路由:list(推荐列表)/detail(具体做法)/general(一般问题)。「小炒肉怎么做」会被路由为detail,随后触发generate_step_by_step_answer——生成集成模块 generation_integration.py 中的烹饪导师提示词会要求 LLM 按「菜品介绍 / 所需食材 / 制作步骤 / 制作技巧」组织回答,且明确「优先使用原文中的实用技巧,如果原文的附加内容与烹饪无关或为空,可以省略」——小炒肉文档的「附加内容」章节为空,模型将基于制作步骤总结要点。

检索到的子块会通过get_parent_documents回溯到完整菜谱(见 data_preparation.py),保证生成阶段拿到的是包含原料、用量、操作在内的整篇小炒肉文档,而非零散片段。

八、动手实践:运行与提问

code/C8目录下按 requirements.txt 安装依赖,设置MOONSHOT_API_KEY环境变量后运行 main.py:

export MOONSHOT_API_KEY=your_key_here python main.py

系统默认数据路径为../../data/C8/cook,可覆盖 config.py 中的data_pathembedding_modelllm_modeltop_ktemperature等配置。可尝试的提问:

  • 「小炒肉怎么做」→ 路由为 detail,返回分步骤制作指导;
  • 「推荐几道荤菜」→ 路由为 list,返回去重后的菜品名列表;
  • 「有没有中难度的菜」→ 触发元数据过滤,命中difficulty=中等的菜谱。

九、小结

一份看似简单的小炒肉菜谱,在 Datawhale all-in-rag 的 C8 食谱 RAG 系统中完成了「文档加载 → 元数据增强(分类 / 菜名 / 难度)→ 结构感知分块 → 向量 + 关键词混合索引 → 路由 + 重写 + 检索 + 分步生成」的完整数据旅程。理解这份菜谱文档的格式约定(星号难度、标题层级、分类目录),也就掌握了为 RAG 知识库设计高质量结构化语料的核心要领——无论是菜谱,还是任何领域的技术文档,良好的结构本身就是最好的「可检索性设计」。

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

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

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

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

相关推荐

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

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

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

立即咨询