<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>RAG on Chang Luo</title>
		<link>https://www.luochang.ink/tags/rag/</link>
		<description>Recent content in RAG on Chang Luo</description>
		<generator>Hugo</generator>
		<language>zh-CN</language>
		
		
		
		
			<lastBuildDate>Sat, 27 Dec 2025 00:00:00 +0000</lastBuildDate>
		
			<atom:link href="https://www.luochang.ink/tags/rag/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>RAG：大模型时代的搜索基座</title>
				<link>https://www.luochang.ink/posts/rag_intro/</link>
				<pubDate>Sat, 27 Dec 2025 00:00:00 +0000</pubDate>
				<guid>https://www.luochang.ink/posts/rag_intro/</guid>
				<description>&lt;blockquote&gt;&#xA;&lt;p&gt;没有一条帆船能吹动自己行驶，它需要外面的风。 &amp;ndash; 因可觅《量子离歌》&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;大模型的训练数据有截止日期，在此之后的事它不知道；大模型的参数量有限，无法容纳所有专业知识。也就是说，大模型在实时性和专业性上都有所欠缺。&lt;/p&gt;&#xA;&lt;p&gt;如何让大模型变得实时且专业呢？最省力的方法是“打小抄”。&lt;strong&gt;知识库&lt;/strong&gt; 就像大模型的“小抄”。在回答问题之前，先瞅一眼小抄，看有没有与问题相关的内容。如果有，就从知识库中取回这段内容，结合大模型的推理能力，生成最终答案。&lt;/p&gt;&#xA;&lt;p&gt;这里「打小抄」的动作，就是 &lt;a href=&#34;https://docs.langchain.com/oss/python/langchain/retrieval&#34;&gt;&lt;strong&gt;RAG&lt;/strong&gt;&lt;/a&gt;（Retrieval-Augmented Generation, 检索增强生成）。&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; 使用知识库可以让大模型的回答有据可依、减少幻觉，代价是需要承担知识库的构建成本。尤其当知识库的规模较大时，有必要想想是否值得支付对价。毕竟，通过扩大知识库的方式提升 Agent 性能，多少有点「用有限对抗无限，用确定对抗不确定」的意思。虽然我们总是在提起 RAG 时提到知识库，但 RAG 是一种检索技术，它可以检索任何内容。比起检索需要手动构建的知识库，用来检索联网内容、历史对话也是可以的，而且性价比很高。你的下一个检索对象，又何必是知识库。&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;一提示词模板&#34;&gt;一、提示词模板&lt;/h2&gt;&#xA;&lt;p&gt;RAG 做的事情并不复杂，就是从知识库中召回与用户问题有关的内容，作为上下文注入到 &lt;strong&gt;提示词模板 (Prompt Template)&lt;/strong&gt; 中。&lt;/p&gt;&#xA;&lt;p&gt;下面是一个提示词模板：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f7f7f7;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{context}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;---&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;基于上面给出的上下文，回答问题。&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;问题：{question}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;回答： &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;使用该模板时，将召回文本填入 &lt;code&gt;{context}&lt;/code&gt;，将用户问题填入 &lt;code&gt;{question}&lt;/code&gt;。然后把填好的提示词模板交给大模型推理。&lt;/p&gt;&#xA;&lt;p&gt;RAG 主要做了两件事：一是从知识库中 &lt;strong&gt;召回&lt;/strong&gt; 与用户问题有关的文本，二是使用提示词模板 &lt;strong&gt;拼接&lt;/strong&gt; 召回文本与用户问题。拼接很容易做到，难度主要集中在召回上。在下一小节中，我将介绍如何召回与用户问题有关的文本。&lt;/p&gt;&#xA;&lt;h2 id=&#34;二向量检索&#34;&gt;二、向量检索&lt;/h2&gt;&#xA;&lt;p&gt;完成「召回与用户问题有关的」这件事，需要用到检索器。实现检索器的方式有 &lt;a href=&#34;https://docs.langchain.com/oss/python/integrations/retrievers&#34;&gt;很多&lt;/a&gt;，比如基于关键词检索的 &lt;a href=&#34;https://docs.langchain.com/oss/python/integrations/retrievers/bm25&#34;&gt;BM25&lt;/a&gt; 算法，但本节主要介绍基于 Embedding 的检索方法：&lt;strong&gt;向量检索&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;h3 id=&#34;1从文本向量化说起&#34;&gt;1）从文本向量化说起&lt;/h3&gt;&#xA;&lt;p&gt;Embedding 是一种将文本转为向量的技术。它的输入是一段文本，输出是一个定长的向量。&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;#34;好喜欢你&amp;#34; --&amp;gt; [0.190012, 0.123555, .... ]&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;将文本转为向量的目的，是把语义相近的词分配到同一片向量空间。所以，一对近义词转成向量后，它们的向量之间的距离通常比其他词更近。比如，足球和篮球在向量空间中的距离更近一些，而足球和篮筐之间的距离更远。Embedding 的本质是压缩。从编码角度讲，自然语言存在冗余信息。Embedding 相当于对自然语言进行重编码，用最少的 token 表达最多的语义。&lt;/p&gt;&#xA;&lt;p&gt;Embedding 在多语言场景下也有优势。经过充分训练的 Embedding 模型，会将多语言内容在语义层面上对齐。也就是说，一个向量可以在多语言环境中保持同一语义。这种特性让大模型得以兼容并包。即使加入多语言材料，也不会因为字面上的词不同，而产生“理解”上的混乱。&lt;/p&gt;&#xA;&lt;h3 id=&#34;2向量检索的原理&#34;&gt;2）向量检索的原理&lt;/h3&gt;&#xA;&lt;p&gt;由于 Embedding 模型具有将相似语义的词训练成距离相近的向量的特性，我们可以把「用户问题」与「知识库内容」都转成 Embedding 向量。然后计算向量之间的距离。向量之间的距离越小，则语料之间的相似度越高。借助这个原理，最后返回知识库中与问题向量距离最小的 Top-K 份语料即可。&lt;/p&gt;</description>
			</item>
			<item>
				<title>Langflow 实现本地知识库</title>
				<link>https://www.luochang.ink/posts/langflow_rag_app/</link>
				<pubDate>Sat, 15 Mar 2025 00:00:00 +0000</pubDate>
				<guid>https://www.luochang.ink/posts/langflow_rag_app/</guid>
				<description>&lt;blockquote&gt;&#xA;&lt;p&gt;本项目将用 &lt;a href=&#34;https://github.com/langflow-ai/langflow&#34; target=&#34;_blank&#34;&gt;langflow&lt;/a&gt; 实现一个本地知识库。&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Langflow 是大模型可视化组件编排工具。它可以为大模型赋能，比如可以为大模型应用增加对话记忆、文档检索等等的功能。它基本上站到了 LangChain 类似的生态位。开发大模型应用的需求通常比较 flexible，在功能和性能都满足的条件下，Langflow 可以快速实现原型开发和模块复用，是目前的效率之选。&lt;/p&gt;&#xA;&lt;p&gt;GitHub 项目地址：&lt;a href=&#34;https://github.com/luochang212/langflow-rag-app&#34; target=&#34;_blank&#34;&gt;langflow-rag-app&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;本文的内容包括：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;介绍 RAG 的相关概念&lt;/li&gt;&#xA;&lt;li&gt;使用 Langflow 实现简单的知识库&lt;/li&gt;&#xA;&lt;li&gt;使用 Langflow 实现带对话记忆功能的知识库&lt;/li&gt;&#xA;&lt;li&gt;使用 Langflow 实现代码检查 (code review) 功能&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;✨ 环境部署相关的脚本，我放在这里了 &lt;a href=&#34;https://github.com/luochang212/langflow-rag-app/tree/main/deploy&#34; target=&#34;_blank&#34;&gt;deploy&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;一rag-的概念介绍&#34;&gt;一、RAG 的概念介绍&lt;/h2&gt;&#xA;&lt;p&gt;这一节，我们先介绍 RAG 的相关概念，&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;知识库&lt;/strong&gt; 就像大语言模型的“小抄”。在回答你之前，大模型先瞅一眼小抄，看有没有和你的问题相关的内容。如果有，就会从知识库中取回相应的文本片段，再结合大模型自身的能力生成最终回答。&lt;/p&gt;&#xA;&lt;p&gt;知识库使用了一种叫 &lt;strong&gt;RAG（检索增强生成）&lt;/strong&gt; 的技术。通过 RAG，大模型可以检索我们给它的文档。比如我们给它数学、法律、金融相关的文档，它可以事先进行“消化”、“吸收”。当我们对它提问时，它就能够像真正的专家一样，结合这些领域知识回答问题。&lt;/p&gt;&#xA;&lt;p&gt;目录：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;提示词模板&lt;/li&gt;&#xA;&lt;li&gt;RAG 技术&#xA;&lt;ul&gt;&#xA;&lt;li&gt;文本向量化&lt;/li&gt;&#xA;&lt;li&gt;向量数据库&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;br&gt;&#xA;&lt;center&gt;&#xA;&lt;button class=&#34;demo-btn&#34; onclick=&#34;window_on(&#39;https://nbviewer.org/github/luochang212/langflow-rag-app/blob/main/1.road_map.ipynb&#39;)&#34;&gt;查看笔记&lt;/button&gt;&#xA;&lt;/center&gt;&#xA;&lt;br&gt;&#xA;&lt;h2 id=&#34;二简单的-rag-应用&#34;&gt;二、简单的 RAG 应用&lt;/h2&gt;&#xA;&lt;p&gt;本节我们完成一个简单的 RAG 应用。我们将一个文档向量化后，存入向量数据库中，然后用 deepseek-r1:1.5b 模型，整合 RAG 取回的内容后输出回答。&lt;/p&gt;&#xA;&lt;p&gt;最终的 langflow 工作流如下：&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://www.luochang.ink/img/simple_rag_app.jpg&#34; alt=&#34;image&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;目录：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;环境准备&#xA;&lt;ul&gt;&#xA;&lt;li&gt;安装 Ollama&lt;/li&gt;&#xA;&lt;li&gt;安装 langflow&lt;/li&gt;&#xA;&lt;li&gt;安装 chroma&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;langflow 搭建工作流&#xA;&lt;ul&gt;&#xA;&lt;li&gt;创建一个新的 Flow&lt;/li&gt;&#xA;&lt;li&gt;初始界面&lt;/li&gt;&#xA;&lt;li&gt;本地改造计划&lt;/li&gt;&#xA;&lt;li&gt;启动 Ollama 服务&lt;/li&gt;&#xA;&lt;li&gt;添加 Ollama Embeddings 组件&lt;/li&gt;&#xA;&lt;li&gt;添加 Chroma DB 组件&lt;/li&gt;&#xA;&lt;li&gt;添加 Ollama 组件&lt;/li&gt;&#xA;&lt;li&gt;传入文档&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;br&gt;&#xA;&lt;center&gt;&#xA;&lt;button class=&#34;demo-btn&#34; onclick=&#34;window_on(&#39;https://nbviewer.org/github/luochang212/langflow-rag-app/blob/main/2.simple_rag_app.ipynb&#39;)&#34;&gt;查看笔记&lt;/button&gt;&#xA;&lt;/center&gt;&#xA;&lt;br&gt;&#xA;&lt;h2 id=&#34;三带对话记忆功能的-rag&#34;&gt;三、带对话记忆功能的 RAG&lt;/h2&gt;&#xA;&lt;p&gt;通过添加 Messsage History 组件，就可以为 RAG 添加对历史对话的记忆。&lt;/p&gt;</description>
			</item>
	</channel>
</rss>
