编辑
2025-07-14
AI
00

目录

RAG
架构图
基本链路
LLM和RAG对比
pdf读取
需求用例生成
总结

RAG

Retrieval-Augmented Generation

检索增强生成,一种结合信息检索和生成模型的技术,RAG 模型通过将检索和生成两个过程结合起来,利用外部知识库来增强生成模型的能力

架构图

大致理解:

bash
+-------------------+ +-------------------+ +-------------------+ | 用户输入 Query | --> | 检索器 Retriever | --> | 相关文档片段列表 | +-------------------+ +-------------------+ +-------------------+ | v +-------------------+ | 生成器 Generator | | (融合 Query 和 | | 相关文档生成答案) | +-------------------+ | v +-------------------+ | 最终生成回答 | +-------------------+

更细维度理解:

bash
[用户输入 Query] | v +--------------------+ | 查询编码器 (Query Encoder) | | (BERT/Transformer等) | +--------------------+ | v (查询向量) +--------------------+ | 文档检索器 (Vector Search) | <--- [知识库文档集合的文档向量] +--------------------+ | v (Top-K 相关文档) +--------------------+ | 文档编码器 (Document Encoder) | +--------------------+ | v (文档向量) +-------------------------------------+ | 结合 Query 向量与文档向量融合 | | (有的实现会拼接文本,有的用交叉注意力)| +-------------------------------------+ | v +--------------------+ | 生成器(Seq2Seq模型,如BART、T5) | | 以 Query + 检索文档上下文为输入 | +--------------------+ | v [生成最终答案]

基本链路

document.txt内容

bash
第一回 灵根育孕源流出 心性修持大道生 混沌未分天地乱,茫茫渺渺无人见。自从盘古破鸿蒙,开辟从兹清浊辨。 覆载群生仰至仁,发明万物皆成善。欲知造化会元功,须看西游释厄传。 话说东胜神洲傲来国,有一座花果山,山顶一块仙石,自开天辟地以来,吸收日月精华,孕育灵气。忽一日,石裂诞生一石猴,五官俱备,四肢皆全。那猴在山中学会行走跳跃,灵明异常。山中群猴见之,皆以为王,尊为“美猴王”。 一日,众猴嬉戏水帘洞,言道:“谁敢潜入瀑布之后,吾等拜之为王。”石猴奋勇向前,纵身跃入水帘,得一洞天福地。众猴大喜,齐拜为王,美猴王自此称雄花果山。 美猴王心有所思,曰:“生老病死,实为苦事,吾欲访道求仙。”遂辞群猴,泛海而行,历尽艰辛,拜入须菩提祖师门下,得名“孙悟空”,学得长生不老之术、七十二变、筋斗云等法术,名动三界。 然因嬉闹天宫,大闹龙宫地府,被天尊压于五行山下,待唐僧西行取经,方得重见天日。后随唐僧历经九九八十一难,终成正果,封为斗战胜佛。 此正是:天不生我齐天大圣,万古如长夜。大闹天宫虽狂傲,修得正果亦称奇。 第一回 宴桃园豪杰三结义 斩黄巾英雄首立功 话说天下大势,分久必合,合久必分。周末七国分争,并入于秦。及秦灭之后,楚、汉分争,又并入于汉。 汉室自高祖斩白蛇而起,传至灵帝,政衰朝纲不振。时有黄巾贼张角作乱,号称“太平道”,率众起义,号称“苍天已死,黄天当立,岁在甲子,天下大吉”。 时有一人,姓张名飞,屠猪为业。见国难当头,感叹道:“国家多难,正宜豪杰奋起!”张飞招募乡勇,愿共讨贼。涿郡之中,有一刘备,乃中山靖王之后,性宽厚仁德,志在匡扶汉室。又有一关羽,年少壮健,义气深重,亦愿共举义旗。 三人志同道合,于桃园中设香案,焚香盟誓: “我们三人,虽异姓,愿结为兄弟。今日之后,生死与共,福祸相依。不得背义忘恩,违背此誓,天人共戮!” 于是张飞为弟,关羽为兄,刘备居中,结为异姓兄弟,世称“桃园三结义”。 三人起兵讨贼,连破黄巾,立下首功,威名渐显。

先将模型下载到本地 huggingface.io(网络太差了)

bash
from sentence_transformers import SentenceTransformer model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2') model.save("/root/local_models/all-MiniLM-L6-v2")

文档.txt --> 向量化 + 建索引 --> 检索相关片段 --> DeepSeek 生成回答

一个基本的RAG阅读文档能力并打印,

qa.run(...) 会自动:

把问题转为向量;

在 FAISS 中找最相关的文档段落;

把文档段 + 问题输入给 DeepSeek;

返回回答。

bash
(venv) root@ECS-2642685781:~# python3 Python 3.12.3 (main, Jun 18 2025, 17:59:45) [GCC 13.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> >>> >>> from langchain_community.document_loaders import TextLoader >>> from langchain_community.vectorstores import FAISS >>> # from langchain_community.embeddings import HuggingFaceEmbeddings >>> from langchain_huggingface import HuggingFaceEmbeddings >>> from langchain.chains import RetrievalQA >>> from langchain_openai import ChatOpenAI >>> >>> import os >>> >>> # 设置 DeepSeek API >>> os.environ["OPENAI_API_KEY"] = "sk-your key" >>> os.environ["OPENAI_API_BASE"] = "https://api.deepseek.com/v1" >>> >>> # 1. 加载文档 >>> loader = TextLoader("document.txt") >>> docs = loader.load() >>> >>> # 2. 向量化(建议用 HuggingFace 本地 embedding,避免调 API 计费) >>> embedding = HuggingFaceEmbeddings(model_name="/root/local_models/all-MiniLM-L6-v2") # 可选 model_name,如 all-MiniLM-L6-v2 >>> db = FAISS.from_documents(docs, embedding) # 将文档转为向量,建立索引数据库 >>> >>> # 3. 构建 RAG 问答链 >>> llm = ChatOpenAI(model="deepseek-chat", temperature=0) #初始化了一个 LLM,实际调用的是 DeepSeek 模型 >>> qa = RetrievalQA.from_chain_type( # 创建了一个结合 retriever + LLM 的问答系统 ... llm=llm, ... retriever=db.as_retriever() ... ) >>> >>> # 4. 提问 >>> if __name__ == '__main__': ... question = "这篇文档主要讲了什么?" ... answer = qa.run(question) ... print(f"Q: {question}\nA: {answer}") ... <stdin>:3: LangChainDeprecationWarning: The method `Chain.run` was deprecated in langchain 0.1.0 and will be removed in 1.0. Use :meth:`~invoke` instead. Q: 这篇文档主要讲了什么? A: 这篇文档主要讲了两部中国古典名著的开篇故事: 1. **《西游记》第一回**:讲述了孙悟空(美猴王)的诞生和早期经历。包括他从花果山仙石中诞生、成为猴王、为求长生不老而拜师学艺(获得七十二变、筋斗云等神通),以及因大闹天宫被压五行山下的故事。最后点明他后来跟随唐僧西天取经并修成正果。 2. **《三国演义》第一回**:讲述了东汉末年黄巾起义时期,刘备、关羽、张飞三人"桃园三结义"的故事。描述了三人因国家动乱而结为异姓兄弟,共同起兵讨伐黄巾军并立下首功的经过。 两段文字都是中国四大名著的开篇章节,分别交代了主要人物的出身和故事背景。 >>>

LLM和RAG对比

非RAG,直接对话大模型

bash
>>> from langchain_openai import ChatOpenAI >>> llm = ChatOpenAI(model="deepseek-chat", temperature=0) >>> >>> # 不依赖任何上下文或文档 >>> question = "孙悟空是怎么出生的?" >>> answer = llm.invoke(question) >>> >>> print(f"[非RAG问答]\nQ: {question}\nA: {answer}") [非RAG问答] Q: 孙悟空是怎么出生的? A: content='孙悟空的出生在中国古典名著《西游记》中有详细描述,其来历充满神话色彩。以下是关键情节:\n\n1. **仙石孕育** \n 孙悟空诞生于东胜神洲傲来国的花果山。山顶有一块高三丈六尺五寸(象征周天365度)、围圆二丈四尺(对应二十四节气)的**仙石**,自开天辟地以来吸收日月精华,内育仙胞。\n\n2. **石破天惊** \n 一日仙石迸裂,产出一颗石卵,见风后化作一只**石猴**(即孙悟空)。出生时双目射出金光,直冲凌霄宝殿,惊动了玉皇大帝。\n\n3. **天地异象** \n 玉帝派千里眼、顺风耳探查,得知是花果山石猴出世,认为“乃天地精华所生”,未予深究,为后续大闹天宫埋下伏笔。\n\n4. **文化寓意** \n - **反叛象征**:无父无母的设定暗喻对传统宗法秩序的挑战。 \n - **道教元素**:石头尺寸暗合天文历法,体现道教“天人合一”思想。 \n - **原型争议**:有学者认为其形象可能受印度神猴哈奴曼或中国无支祁传说影响。\n\n补充细节: \n- 吴承恩在原著第一回“灵根育孕源流出”重点描写了这一情节。 \n- 动画电影《大圣归来》等改编作品常以巨石崩裂场景致敬原著。 \n- 福建武夷山、江苏连云港等地均有所谓“孙悟空出生地”的旅游景点,但均属民间附会。\n\n这一诞生过程奠定了孙悟空超越三界、不受束缚的角色基调,成为全书反抗精神的图腾式开场。' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 381, 'prompt_tokens': 7, 'total_tokens': 388, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 0}, 'prompt_cache_hit_tokens': 0, 'prompt_cache_miss_tokens': 7}, 'model_name': 'deepseek-chat', 'system_fingerprint': 'fp_8802369eaa_prod0623_fp8_kvcache', 'id': '5fee4aa6-4704-47a2-90f5-e13c92f6ce6d', 'service_tier': None, 'finish_reason': 'stop', 'logprobs': None} id='run--6a6f1ea9-b7d4-4662-9eee-7cbdc72ca8ed-0' usage_metadata={'input_tokens': 7, 'output_tokens': 381, 'total_tokens': 388, 'input_token_details': {'cache_read': 0}, 'output_token_details': {}} >>>

RAG,再对话大模型

bash
>>> from langchain_community.document_loaders import TextLoader >>> from langchain_community.vectorstores import FAISS >>> from langchain_huggingface import HuggingFaceEmbeddings >>> from langchain.chains import RetrievalQA >>> from langchain_openai import ChatOpenAI >>> >>> import os >>> os.environ["OPENAI_API_KEY"] = "sk-your key" >>> os.environ["OPENAI_API_BASE"] = "https://api.deepseek.com/v1" >>> >>> # 加载文档 >>> loader = TextLoader("document.txt") >>> docs = loader.load() >>> >>> # 向量化:本地模型 >>> embedding = HuggingFaceEmbeddings(model_name="/root/local_models/all-MiniLM-L6-v2") >>> db = FAISS.from_documents(docs, embedding) >>> >>> # 构建 RAG QA >>> llm = ChatOpenAI(model="deepseek-chat", temperature=0) >>> qa = RetrievalQA.from_chain_type( ... llm=llm, ... retriever=db.as_retriever() ... ) >>> >>> # RAG 问答 >>> question = "孙悟空是怎么出生的?" >>> answer = qa.run(question) >>> print(f"[RAG问答]\nQ: {question}\nA: {answer}") [RAG问答] Q: 孙悟空是怎么出生的? A: 根据《西游记》第一回的描述,孙悟空的出生非常神奇: 他是由东胜神洲傲来国花果山顶的一块仙石孕育而生的。这块仙石自开天辟地以来就存在,长期吸收日月精华,孕育灵气。突然有一天,仙石迸裂,从中诞生出一只石猴。这只石猴生来就五官俱全,四肢齐备,能够行走跳跃,灵性非凡。 后来这只石猴因为勇敢地跳入水帘洞,被群猴尊为"美猴王",也就是后来的孙悟空。 >>> exit()

pdf读取

原pdf内容部分信息

bash
3) 更新方式分为手动更新和自动更新 手动更新: 业务流脚本列表 tab, 触发“ 更新用例关联” 即可实时更新当前项目业务流 与 devops 用例的关联状态和关联 devops 用例 id( 其他字段为实时更新--最近一次执 行时间、 执行状态) 自动更新: 每天凌晨 1:00, 平台会定时自动更新前一天的数据, 根据业务流与关联用 例的唯一性【框架 id+业务流 id+用例 id】 进行匹配并更新
bash
from langchain_community.document_loaders import TextLoader from langchain_community.vectorstores import FAISS from langchain_huggingface import HuggingFaceEmbeddings from langchain.chains import RetrievalQA from langchain_openai import ChatOpenAI import os os.environ["OPENAI_API_KEY"] = "sk-your key" os.environ["OPENAI_API_BASE"] = "https://api.deepseek.com/v1" # # 加载文档, 从文件中读取文本内容,并封装成 LangChain 需要的文档对象(Document 列表) # loader = TextLoader("document.txt") # docs = loader.load() from langchain_community.document_loaders import PyPDFLoader loader = PyPDFLoader("自定义框架-allure类型操作手册.pdf") docs = loader.load() # 向量化:本地模型 embedding = HuggingFaceEmbeddings(model_name="./local_models/all-MiniLM-L6-v2") # 句子级语义嵌入 (Sentence Embedding) db = FAISS.from_documents(docs, embedding) # 使用 FAISS 将所有向量构建为一个 内存中的向量索引(IndexFlatL2) # 构建 RAG QA llm = ChatOpenAI(model="deepseek-chat", temperature=0) qa = RetrievalQA.from_chain_type( llm=llm, retriever=db.as_retriever() ) # RAG 问答 question = "更新方式分为手动更新和自动更新?" answer = qa.run(question) print(f"[RAG问答]\nQ: {question}\nA: {answer}")

输出结果

bash
/home/lixuefu/env_langchain-test/bin/python /home/lixuefu/langchain-test/rag-pdf.py /home/lixuefu/langchain-test/rag-pdf.py:33: LangChainDeprecationWarning: The method `Chain.run` was deprecated in langchain 0.1.0 and will be removed in 1.0. Use :meth:`~invoke` instead. answer = qa.run(question) [RAG问答] Q: 更新方式分为手动更新和自动更新? A: 是的,根据提供的上下文,更新方式分为以下两种: 1. **手动更新** - 操作路径:在「业务流脚本列表」tab中触发【更新用例关联】按钮 - 功能:实时更新当前项目的业务流与DevOps用例的关联状态、关联用例ID(其他字段如最近执行时间、执行状态也会实时更新) 2. **自动更新** - 触发时间:每天凌晨1:00 - 规则:平台自动更新前一天的数据,根据业务流与关联用例的唯一性(框架ID+业务流ID+用例ID)进行匹配更新 > 注意:手动更新可即时生效,自动更新为定时任务。具体规则可参考“数据更新说明”中的悬浮提示。 Process finished with exit code 0

需求用例生成

bash
from langchain_community.document_loaders import TextLoader from langchain_community.vectorstores import FAISS from langchain_huggingface import HuggingFaceEmbeddings from langchain.chains import RetrievalQA from langchain_openai import ChatOpenAI import os os.environ["OPENAI_API_KEY"] = "sk-your key" os.environ["OPENAI_API_BASE"] = "https://api.deepseek.com/v1" # # 加载文档, 从文件中读取文本内容,并封装成 LangChain 需要的文档对象(Document 列表) # loader = TextLoader("document.txt") # docs = loader.load() from langchain_community.document_loaders import PyPDFLoader loader = PyPDFLoader("登录注册流程全梳理.pdf") docs = loader.load() # 向量化:本地模型 embedding = HuggingFaceEmbeddings(model_name="./local_models/all-MiniLM-L6-v2") # 句子级语义嵌入 (Sentence Embedding) db = FAISS.from_documents(docs, embedding) # 使用 FAISS 将所有向量构建为一个 内存中的向量索引(IndexFlatL2) # 构建 RAG QA llm = ChatOpenAI(model="deepseek-chat", temperature=0) qa = RetrievalQA.from_chain_type( llm=llm, retriever=db.as_retriever() ) # RAG 问答 question = "假如你是一名资深测试工程师,麻烦根据文档,编写登录注册的测试用例,要求尽可能覆盖所有的场景" answer = qa.run(question) print(f"[RAG问答]\nQ: {question}\nA: {answer}")
bash
/home/lixuefu/env_langchain-test/bin/python /home/lixuefu/langchain-test/rag-pdf.py /home/lixuefu/langchain-test/rag-pdf.py:33: LangChainDeprecationWarning: The method `Chain.run` was deprecated in langchain 0.1.0 and will be removed in 1.0. Use :meth:`~invoke` instead. answer = qa.run(question) [RAG问答] Q: 假如你是一名资深测试工程师,麻烦根据文档,编写登录注册的测试用例,要求尽可能覆盖所有的场景 A: # 登录注册测试用例 ## 一、一键登录测试用例 ### 1. 正常流程 - **用例1**: 首次使用一键登录功能,验证能否成功注册新账号 - **用例2**: 已注册用户使用一键登录,验证能否成功登录 - **用例3**: 验证一键登录后用户信息是否正确显示 ### 2. 异常流程 - **用例4**: 网络异常情况下尝试一键登录,验证错误提示 - **用例5**: 设备不支持一键登录功能时,验证降级处理 ## 二、手机短信验证码登录/注册测试用例 ### 1. 正常流程 - **用例6**: 新用户使用手机号+验证码注册,验证注册流程 - **用例7**: 已注册用户使用手机号+验证码登录,验证登录流程 - **用例8**: 验证短信验证码5分钟内有效 - **用例9**: 验证短信验证码成功一次后重置计数 ### 2. 异常流程 - **用例10**: 输入错误验证码,验证提示信息 - **用例11**: 使用过期验证码登录,验证提示信息 - **用例12**: 1天内连续5次发送验证码未验证,第6次需要图形验证码 - **用例13**: 输入非11位手机号,验证格式校验 - **用例14**: 输入非13/14/15/16/17/18/19开头的手机号,验证格式校验 ## 三、密码登录测试用例 ### 1. 正常流程 - **用例15**: 正确手机号+密码登录,验证登录成功 - **用例16**: 验证上次登录手机号自动填充功能 - **用例17**: 点击"忘记密码"跳转重置密码页 ### 2. 异常流程 - **用例18**: 同一账号/设备连续6次错误密码,验证滑块验证码弹出 - **用例19**: 滑块验证通过后,验证错误计数清零 - **用例20**: 未注册账号尝试密码登录,验证提示信息 - **用例21**: 未勾选协议条款点击登录,验证晃动效果和提示 - **用例22**: 密码输入框特殊字符测试 ## 四、重置密码测试用例 ### 1. 正常流程 - **用例23**: 通过手机号+验证码成功重置密码 - **用例24**: 重置密码后使用新密码登录 - **用例25**: 验证上次登录手机号自动填充功能 ### 2. 异常流程 - **用例26**: 同一账号/设备超过5次验证码请求,第6次需要图形验证码 - **用例27**: 输入错误图形验证码,验证提示信息 - **用例28**: 设置过短/过长密码,验证系统处理 - **用例29**: 验证码输入非6位数字,验证格式校验 ## 五、安全规则测试用例 ### 1. 图形验证码规则 - **用例30**: 验证1天内连续5次发送验证码未验证,第6次需要图形验证码 - **用例31**: 验证过自然天后计数重置 - **用例32**: 验证成功验证一次后计数重置 ### 2. 滑块验证规则 - **用例33**: 验证同一账号/设备连续6次错误密码后弹出滑块 - **用例34**: 滑块验证通过后错误计数清零 - **用例35**: 滑块验证失败后继续计数 ## 六、兼容性测试用例 - **用例36**: 不同机型测试一键登录功能 - **用例37**: 不同网络环境测试登录流程 - **用例38**: 不同操作系统版本测试滑块验证功能 ## 七、性能测试用例 - **用例39**: 验证短信验证码发送响应时间 - **用例40**: 高并发场景下登录接口性能测试 - **用例41**: 滑块验证服务响应时间测试 ## 八、UI/UX测试用例 - **用例42**: 验证协议条款晃动效果 - **用例43**: 验证各页面手机号输入框格式提示 - **用例44**: 验证错误提示信息的准确性和友好性 以上测试用例覆盖了文档中提到的所有业务规则、正常逻辑和异常逻辑场景,包括一键登录、短信验证码登录、密码登录、重置密码等核心功能,以及相关的安全规则和用户体验要求。 Process finished with exit code 0

总结

「知识库 + 向量检索 + LLM 问答」的全套链路

bash
| 模块 | 是否用了 | 说明 | | ------------- | ---- | ------------------- | | 文档加载 | ✅ | PDF 转文本 | | 文本向量化 | ✅ | 本地 MiniLM 模型 | | 向量索引构建(知识库) | ✅ | FAISS | | 检索器 Retriever | ✅ | `db.as_retriever()` | | 大模型生成 | ✅ | `ChatOpenAI` | | RAG 流程封装 | ✅ | `RetrievalQA` |

本文作者:lixf6

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!