txtai RAG 管线实战:用 Embeddings 检索与 LLM 生成构建检索增强生成
2026/9/15 15:19:36 网站建设 项目流程

txtai RAG 管线实战:用 Embeddings 检索与 LLM 生成构建检索增强生成

【免费下载链接】txtai💡 All-in-one AI framework for semantic search, LLM orchestration and language model workflows项目地址: https://gitcode.com/GitHub_Trending/tx/txtai

本指南深入讲解 txtai 中的 RAG(Retrieval Augmented Generation,检索增强生成)管线:如何将提示词、上下文数据存储与生成式模型三者结合,从自有数据中抽取知识并生成可引用答案。读完本文,你将掌握 RAG 管线的 Python 与配置驱动两种用法、底层检索与生成流程,以及输出格式、系统提示、流式响应等进阶参数的完整配置方案。

RAG 管线是什么

txtai 的 RAG 管线把三个组件拼接在一起,构成一条完整的"检索 → 增强 → 生成"链路(见 RAG 官方文档):

  • 上下文数据存储(context data store):可以是带原文内容的 embeddings 数据库,也可以是带关联输入文本的 similarity(相似度)实例;
  • 生成式模型(generative model):可以是提示词驱动的大语言模型(LLM)、抽取式问答模型(extractive question-answering)或自定义管线;
  • 提示词(prompt):把检索到的上下文与用户问题组织成模型可执行的指令模板。

从源码实现看,RAG 类继承自Pipeline(rag.py),其类注释明确说明:"通过将提示词、上下文数据存储和生成式模型结合在一起,从内容中抽取知识"。这意味着 RAG 不只是"向量检索 + 聊天",它还能复用 txtai 的问答、相似度等基础能力,灵活性很高。

快速上手:Python 示例

下面的例子完整复现官方文档的入门场景:先构建一个带原文内容的 embeddings 索引,再创建 RAG 管线,最后提问。

from txtai import Embeddings, RAG # Input data data = [ "US tops 5 million confirmed virus cases", "Canada's last fully intact ice shelf has suddenly collapsed, " + "forming a Manhattan-sized iceberg", "Beijing mobilises invasion craft along coast as Taiwan tensions escalate", "The National Park Service warns against sacrificing slower friends " + "in a bear attack", "Maine man wins $1M from $25 lottery ticket", "Make huge profits without work, earn up to $100,000 a day" ] # Build embeddings index embeddings = Embeddings(content=True) embeddings.index(data) # Create the RAG pipeline rag = RAG(embeddings, "Qwen/Qwen3-0.6B", template=""" Answer the following question using the provided context. Question: {question} Context: {context} """) # Run RAG pipeline rag("What was won?")

要点说明:

  • Embeddings(content=True)表示索引时保存原文内容,这是 RAG 能"抽取知识"的前提——生成阶段需要把命中片段的原文作为上下文喂给模型;
  • RAG的第一个参数传入 embeddings 实例,第二个参数是生成模型路径;
  • 模板中必须包含{question}{context}两个占位符,分别会被替换为输入问题和检索到的上下文。

直接传入 Chat 模板

许多指令微调模型遵循固定的 chat 模板,你可以把整段模板(含系统、用户、助手角色标记)直接传给template。模板格式随模型而异:

# Prompts with chat templating can be directly passed # The template format varies by model rag = RAG(embeddings, "Qwen/Qwen3-0.6B", template=""" <|im_start|>system You are a friendly assistant.<|im_end|> <|im_start|>user Answer the following question using the provided context. Question: {question} Context: {context} <|im_start|>assistant """ ) rag("What was won?")

通过 system 参数自动构建对话消息

当提供system参数时,输入会自动转换为 chat 消息。从源码看(rag.py),prompts方法会在检测到self.system时,把提示词包装成[{"role": "system", ...}, {"role": "user", ...}]两条消息,交由底层生成器处理。

rag = RAG( embeddings, "openai/gpt-oss-20b", system="You are a friendly assistant", template=""" Answer the following question using the provided context. Question: {question} Context: {context} """) rag("What was won?")

额外的 LLM 选项

__call__时可以把 LLM 参数作为附加参数传入:

  • stream=True:以流式方式返回 RAG 响应;
  • defaultrole="user":字符串输入始终转换为用户消息(LLM 管线的defaultrole还支持"auto"自动推断与"prompt"保持原始提示词,见 LLM 管线文档);
  • stripThink=True:移除模型输出的思考文本(thinking text)。
rag("What was won?", stream=True, defaultrole="user", stripThink=True)

从 LLM 实现 可以看到,stripthink的默认行为是:流式输出时为False,非流式时为True;思考文本的清理通过正则移除<think>...</think>等标记(见 generation.py)。

RAG 管线内部工作原理

从源码结构看,RAG 的__call__主要经历四个阶段(rag.py):

  1. 输入规范化:字符串问题转换为(name, query, question, snippet)元组,字典输入按["name", "query", "question", "snippet"]字段抽取;
  2. 上下文检索:对每个 query 执行相似度打分(score),排序后取前context条(默认 3 条)拼接为上下文;
  3. 提示词构建:用模板格式化{question}{context},必要时附加 system 消息(prompts方法);
  4. 生成与格式化:调用底层模型得到答案,再按output格式输出(apply方法)。

检索阶段:query → score → 过滤

query方法(rag.py)实现了一套细粒度的过滤逻辑:

  • 支持必需/禁止关键词:query 中以+开头的词(如+Giants)要求上下文必须包含,以-开头的词要求不能包含;
  • score >= minscore才纳入匹配(minscore默认0.0);
  • 命中片段 token 数必须达到mintokens(默认0.0)。

score方法(rag.py)根据相似度实例类型选择打分路径:

  • 相似度实例为Similarity管线时,调用self.similarity(queries, texts)
  • 传入texts时,调用embeddings.batchsimilarity做批量相似度;
  • 未传texts时,调用embeddings.batchsearch直接对索引做语义搜索(需要 embeddings 开启content=True)。

生成阶段:三种模型形态

load方法(rag.py)根据路径与任务类型决定加载哪种模型:

  • task == "question-answering":加载Questions抽取式问答管线,直接以"问题 + 上下文"为输入返回原文片段;
  • 否则走LLM管线(llm.py),内部由GenerationFactory根据模型路径自动推断后端(factory.py):Hugging Face Transformers、llama.cpp(GGUF 路径)、LiteLLM(如ollama/...)、LiteRT-LM 与 OpenCode;
  • 传入非字符串路径时,直接返回该对象作为自定义管线使用。

answers方法(rag.py)据此分派:Questions模型直接调用self.model(questions, contexts),生成式模型则先经prompts构建提示词再调用self.model(prompts, **kwargs)

输出格式化:default / flatten / reference

apply方法(rag.py)控制返回结构:

output 取值返回格式说明
default(默认)(name, answer)每行包含名称与答案
flatten答案列表仅返回答案字符串序列
reference(name, answer, reference)额外返回与该答案最匹配的上下文元素 id,便于做引用标注

reference模式通过terms提取查询关键词、再对答案与 top-n 上下文重新打分来确定引用来源(rag.py)。此外,若输入元组的snippet标志为真,snippets方法会把答案替换为包含它的完整上下文原文(rag.py)。官方测试 testrag.py 验证了这三种输出模式。

构造参数详解

RAG.__init__的完整签名与默认值(rag.py):

参数默认值说明
similarity必填相似度实例(embeddings 或 similarity 管线)
path必填模型路径,支持 LLM、Questions 或自定义管线
quantizeFalse推理前是否量化模型
gpuTrue是否使用 GPU 推理(仅在有 GPU 时生效)
modelNone可选的已有管线模型对象(外部加载模型时使用)
tokenizerNoneTokenizer 类;未设置时若相似度实例为加权稀疏模型则默认使用Tokenizer
minscoreNone0.0纳入上下文匹配的最低分数
mintokensNone0.0纳入上下文匹配的最低 token 数
contextNone3纳入上下文的最匹配片段数(top-n)
task自动检测模型任务:language-generationsequence-sequencequestion-answering
output"default"输出格式:default/flatten/reference
template"{question} {context}"提示词模板,必须含{question}{context}
separator" "上下文片段拼接分隔符
systemNone系统提示词,提供后自动转为 chat 消息
kwargs透传给底层管线模型的额外关键字参数

需要特别说明:template的默认值是"{question} {context}",即不写模板时 RAG 也能工作(直接拼接问题与上下文);task未指定时,GenerationFactory.method先解析路径归属的生成框架,再交由Models.task推断具体任务类型。

配置驱动示例:YAML + Workflows + API

除了 Python 直接调用,RAG 管线也能用配置声明。管线在配置中使用小写类名实例化,并通过工作流或 API 运行。

config.yml

# Allow documents to be indexed writable: True # Content is required for extractor pipeline embeddings: content: True rag: path: Qwen/Qwen3-0.6B template: | Answer the following question using the provided context. Question: {question} Context: {context} workflow: search: tasks: - action: rag

注意writable: True允许向索引写入文档,embeddings.content: True保存原文——这两项是 RAG 能检索并输出原文上下文的前提。

通过 Workflows 运行

from txtai import Application # Create and run pipeline with workflow app = Application("config.yml") app.add([ "US tops 5 million confirmed virus cases", "Canada's last fully intact ice shelf has suddenly collapsed, " + "forming a Manhattan-sized iceberg", "Beijing mobilises invasion craft along coast as Taiwan tensions escalate", "The National Park Service warns against sacrificing slower friends " + "in a bear attack", "Maine man wins $1M from $25 lottery ticket", "Make huge profits without work, earn up to $100,000 a day" ]) app.index() list(app.workflow("search", ["What was won?"]))

app.add写入文档、app.index()建立索引,workflow("search", ...)触发配置中名为search的工作流,其任务action: rag指向 RAG 管线。

通过 API 运行

CONFIG=config.yml uvicorn "txtai.api:app" & curl \ -X POST "http://localhost:8000/workflow" \ -H "Content-Type: application/json" \ -d '{"name": "search", "elements": ["What was won"]}'

此外,API 还内置了专门的 RAG 路由(rag.py):GET /rag?query=...运行单条 RAG 查询,POST /batchrag批量处理查询列表,两者均支持maxlengthstreamstripthink参数;stream=True时以StreamingResponse流式返回。

实战案例:从本地文件到 RAG 问答

仓库自带的 rag_quickstart.py 展示了一条完整的数据落地链路:收集本地文件 → 文本抽取与分块 → 建立 embeddings 索引 → 构建 RAG 管线。核心代码如下:

from txtai import Embeddings, RAG from txtai.pipeline import Textractor # Step 1: Collect files from local directory (defaults to "data") path = "data" files = [os.path.join(path, f) for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))] # Step 2: Text Extraction / Chunking textractor = Textractor(backend="docling", sections=True) chunks = [] for f in files: for chunk in textractor(f): chunks.append((f, chunk)) # Step 3: Build an embeddings database embeddings = Embeddings(content=True, path="Qwen/Qwen3-Embedding-0.6B", maxlength=2048) embeddings.index(chunks) # Step 4: Create RAG pipeline template = """ Answer the following question using the provided context. Question: {question} Context: {context} """ rag = RAG( embeddings, "Qwen/Qwen3-0.6B", system="You are a friendly assistant", template=template, output="flatten", ) question = "Summarize the main advancements made by BERT" print(rag(question, maxlength=2048, stripthink=True))

该示例展示了几个值得在生产中采用的实践:

  • 先分块再索引:用Textractor按章节(sections=True)切分长文档,使检索粒度更精细;
  • 检索模型与生成模型分离:向量模型Qwen/Qwen3-Embedding-0.6B负责召回,生成模型Qwen/Qwen3-0.6B负责作答;
  • 输出扁平化output="flatten"直接得到答案字符串,便于下游处理;
  • 思考文本剥离stripthink=True让推理模型的思维链过程不污染最终答案。

数据存储与相似度实例的多种组合

RAG 的上下文来源不局限于 embeddings 索引。官方测试 testrag.py 覆盖了三种典型组合:

  • embeddings 索引 + 搜索testSearch):建立content=True的索引后,rag(question)直接对索引做语义检索取上下文;
  • 外部文本列表testAnswer):rag(question, texts)传入文本列表,RAG 先对文本做相似度打分再取 top-n;
  • Similarity 管线 + Questions 模型testSimilarity):RAG(Similarity("prajjwal1/bert-medium-mnli"), Questions("distilbert-base-cased-distilled-squad"))——左侧用相似度管线做召回,右侧用抽取式问答模型做生成,完全绕开 LLM。

最后一种组合印证了"生成式模型可以是抽取式问答模型"的设计:RAG 并不强制要求大语言模型,轻量级 QA 模型同样可以驱动。

方法参考

RAG 管线对外暴露的核心方法:

  • RAG.__init__(similarity, path, quantize=False, gpu=True, model=None, tokenizer=None, minscore=None, mintokens=None, context=None, task=None, output="default", template=None, separator=" ", system=None, **kwargs):构建管线,参数含义见上文表格;
  • RAG.__call__(queue, texts=None, **kwargs):输入可以是单个字符串、元组/字典或它们的列表;返回格式与output参数一致。queue元素支持(name, query, question, snippet)四元组,其中query用于检索、question用于生成、snippet控制是否返回原文片段。

延伸学习

更多主题请参考 Embeddings 配置文档 与 LLM 管线文档(后者介绍了 Transformers、llama.cpp、LiteLLM、LiteRT-LM、OpenCode 等全部生成后端)。仓库中的 notebook 示例按难度递进覆盖了 RAG 的各个进阶方向:

  • 42_Prompt_driven_search_with_LLMs.ipynb:LLM 提示驱动搜索
  • 52_Build_RAG_pipelines_with_txtai.ipynb:RAG 管线构建与引用生成
  • 53_Integrate_LLM_Frameworks.ipynb:集成 llama.cpp、LiteLLM 与自定义生成框架
  • 55_Generate_knowledge_with_Semantic_Graphs_and_RAG.ipynb:语义图 + RAG 的知识生成
  • 58_Advanced_RAG_with_graph_path_traversal.ipynb:图路径遍历的高级 RAG
  • 62_RAG_with_llama_cpp_and_external_API_services.ipynb:llama.cpp 与外部 API 服务
  • 63_How_RAG_with_txtai_works.ipynb:RAG 流程、API 服务与 Docker 实例
  • 65_Speech_to_Speech_RAG.ipynb:语音到语音的完整 RAG 工作流
  • 73_Chunking_your_data_for_RAG.ipynb:面向 RAG 的数据抽取、分块与索引
  • 75_Medical_RAG_Research_with_txtai.ipynb:PubMed 医学文献分析
  • 77_GraphRAG_with_Wikipedia_and_GPT_OSS.ipynb:深度图搜索驱动的 RAG
  • 79_RAG_is_more_than_Vector_Search.ipynb:Web、SQL 等非向量来源的上下文检索

【免费下载链接】txtai💡 All-in-one AI framework for semantic search, LLM orchestration and language model workflows项目地址: https://gitcode.com/GitHub_Trending/tx/txtai

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

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

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

立即咨询