全新大模型框架Haystack,搭建RAG pipeline
大家好,在AI应用开发的赛道上,目前Haystack以其开源框架的优势,成为LLM技术领域的一匹黑马,对现有竞争者构成挑战。本文将介绍Haystack的亮点优势,并分析它为何能在众多LLM框架中脱颖而出,通过RAG应用实例来展示Haystack的实际应用能力。
1.Haystack简介
Haystack是一个强大的工具包,帮助开发者用少量代码创建AI应用,尤其擅长处理大量文本或文档;能够简化开发实用LLM应用的过程。简单来说,Haystack就像一套多功能的积木,可以灵活组合,可以搭建出各式各样的AI系统。
使用Haystack,能够实现多种应用场景,例如:
-
基于大量文档回答问题的聊天机器人
-
能够从众多文档中查找和提取特定信息的系统
-
能够理解和处理文本、图像和其他类型数据的应用
在Python 3.10环境下,可以通过以下命令安装Haystack:
pip install haystack-ai
2.Haystack工作原理
Haystack的运作依赖于两个核心概念:
-
组件:可以视为独立的工具,每个工具都承担着特定的任务。比如,某个组件可能专门用来检索相关文档,而另一个则负责生成文本回答。
-
管道:决定了组件之间的连接方式。通过管道,我们定义了组件的工作顺序以及它们之间信息的传递路径。
利用这些组件的不同组合,开发者能够构建出处理复杂任务的AI系统。
3.Haystack核心优势
-
灵活性:可以与许多不同的AI模型(如OpenAI、HuggingFace等)和数据存储系统(如ChromaDB、Pinecone,甚至是Neo4j)无缝协作。
-
易用性:即使不精通AI的复杂技术细节,开发者也能轻松上手Haystack。
-
可定制性:开发者可以根据特定需求,创建或调整组件。Haystack采用Pydantic结构,定制过程更加简便。
-
应用多样性:支持构建不同类型的AI系统,从问答到信息提取。
4.构建RAG管道
安装好Haystack之后,接下来只需安装trafilatura和lxml,这两个工具用于提取HTML文档:
pip install trafilatura lxml_html_clean
这里将构建两个管道:一个负责文档的清洗与处理,另一个则用于实现RAG功能。
导入相关包:
import urllib.request
from haystack import Pipeline
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.retrievers import InMemoryEmbeddingRetriever
from haystack.components.converters import HTMLToDocument
from haystack.components.preprocessors import DocumentCleaner, DocumentSplitter
from haystack.components.embedders import OpenAIDocumentEmbedder, OpenAITextEmbedder
from haystack.components.writers import DocumentWriter
from haystack.components.builders import PromptBuilder
from haystack.components.generators import OpenAIGeneratorfrom dotenv import load_dotenv
load_dotenv()
将OpenAI密钥放在.env文件中:
OPENAI_API_KEY = 'YOUR KEY'
提取我们的文本,将其存储在文件夹中。
urllib.request.urlretrieve("https://www.oreilly.com/openbook/freedom/ch01.html", "free_as_in_freedom.html")
我们从连接两个管道的组件着手,这个组件负责将处理后的文档存储在内存中:
document_store = InMemoryDocumentStore()
接下来是管道的第一个组件和输入部分。利用之前创建的HTML文件:
text_file_converter = HTMLToDocument()
这个转换器可以接受路径、字符串或字节流作为输入,并返回一个文档列表。这些文档需要经过清洗,以提高可读性。这便是管道的下一步:
cleaner = DocumentCleaner()
cleaner
组件的任务是提升文本文档的可读性,可以通过它删除空行、多余空格或重复的子字符串等。
随后,根据RAG模型的要求,需要将文档切割成块。这对于处理超出语言模型最大文本长度限制的长文本非常有用,同时也能加快问答的处理速度。在我们的案例中,将文档按句子分割,每块包含5个句子:
splitter = DocumentSplitter(split_by="sentence", split_length=5)
文档切割完成后,准备将其嵌入。这里使用OpenAI提供的OpenAIDocumentEmbedder
,它负责计算文档列表的嵌入向量,并将这些向量存储在每个文档的嵌入字段中:
embedder = OpenAIDocumentEmbedder()
最后通过riter
组件,它是第一个管道的输出部分,负责将文档列表写入最初定义的文档存储中,以便在下一个管道中使用:
writer = DocumentWriter(document_store)
如果想添加其他类型的文档,如Excel或PDF,需创建一个新的管道或调整现有管道,并将其存储在InMemoryDocumentStore
组件中。在管道中逐个添加组件:
indexing_pipeline = Pipeline()indexing_pipeline.add_component("converter", text_file_converter)
indexing_pipeline.add_component("cleaner", cleaner)
indexing_pipeline.add_component("splitter", splitter)
indexing_pipeline.add_component("embedder", embedder)
indexing_pipeline.add_component("writer", writer)
将这些组件连接起来:
indexing_pipeline.connect("converter.documents", "cleaner.documents")
indexing_pipeline.connect("cleaner.documents", "splitter.documents")
indexing_pipeline.connect("splitter.documents", "embedder.documents")
indexing_pipeline.connect("embedder.documents", "writer.documents")
运行管道:
indexing_pipeline.run(data={"sources": ["free_as_in_freedom.html"]})
输出结果:
Calculating embeddings: 100%|██████████| 2/2 [00:01<00:00, 1.10it/s]
{'embedder': {'meta': {'model': 'text-embedding-ada-002', 'usage': {'prompt_tokens': 5191, 'total_tokens': 5191}}}, 'writer': {'documents_written': 39}}
整个过程非常直接,在启动文档处理流程之前,需要指定HTML文件作为待处理的输入数据。
通过执行以下代码,可以查看第一个管道的结构:
indexing_pipeline.show()
现在已经集齐了构建RAG部分所需的所有组件,它们将助力系统最终能够响应我们的各种查询。
5.RAG管道
首先,要确定用于文本嵌入的模型。Haystack支持多种嵌入选项,包括OpenAI和HuggingFace,同时也在不断集成更多。为了简化操作,选择使用OpenAI的嵌入器:
text_embedder = OpenAITextEmbedder()
接下来,利用之前处理好并存储在document_store中的文档。可以根据业务需求,选择不同的检索策略,如topk、scalescore或filter等:
retriever = InMemoryEmbeddingRetriever(document_store)
这个组件负责输出经过处理、准备好进行嵌入的文档列表。现在完成RAG管道的最后两个部分,构建提示和选择语言模型(LLM)。
定义一个基本的提示模板:
template = """Given these documents, answer the question.
Documents:
{% for doc in documents %}
{{ doc.content }}
{% endfor %}
Question: {{query}}
Answer:"""
prompt_builder = PromptBuilder(template=template)
对于LLM,同样选择使用OpenAI模型:
llm = OpenAIGenerator()
将这些组件串联起来,正如之前所做的:
rag_pipeline = Pipeline()rag_pipeline.add_component("text_embedder", text_embedder)
rag_pipeline.add_component("retriever", retriever)
rag_pipeline.add_component("prompt_builder", prompt_builder)
rag_pipeline.add_component("llm", llm)
连接各个组件:
rag_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
rag_pipeline.connect("retriever.documents", "prompt_builder.documents")
rag_pipeline.connect("prompt_builder", "llm")
输出的组件和连接概览如下:
Components
- text_embedder: OpenAITextEmbedder
- retriever: InMemoryEmbeddingRetriever
- prompt_builder: PromptBuilder
- llm: OpenAIGenerator
Connections
- text_embedder.embedding -> retriever.query_embedding (List[float])
- retriever.documents -> prompt_builder.documents (List[Document])
- prompt_builder.prompt -> llm.prompt (str)
最后,查看管道的完整结构:
rag_pipeline.show()
RAG管道构建完成,它将能够根据提供的文档回答各种问题。
6.评估RAG管道
以Richard M. Stallman为例,他是麻省理工学院人工智能实验室的一位软件程序员,曾经历过一次设备故障的苦难。
query = " What is the profession of Richard M. Stallman and where does he works ?"
result = rag_pipeline.run(data={"prompt_builder": {"query":query}, "text_embedder": {"text": query}})
print(result["llm"]["replies"][0])
得到的答案是:
Richard M. Stallman is a software programmer and he works at the Massachusetts Institute of Technology's Artificial Intelligence Laboratory.
另一次,当他到达实验室时,发现打印机托盘里只有四页纸,而这四页还属于其他用户。更糟糕的是,这意味着Stallman的打印任务和另一位用户的打印任务的一部分,仍然卡在实验室计算机网络的电子管道中。
query = "Why did Stallman get frustrated when he tried to retrieve his print job from the new Xerox printer ?"
输出结果:
Stallman got frustrated when he tried to retrieve his print job from the new Xerox printer because only four pages in the printer's tray belonged to another user, meaning that Stallman's print job and the unfinished portion of somebody else's print job were still trapped somewhere within the electrical plumbing of the lab's computer network.
两次查询都完美回答,此外还可以查看请求中使用的令牌数量,以跟踪使用情况:
result['llm']['meta'][0]['usage']
#{'completion_tokens': 65, 'prompt_tokens': 1476, 'total_tokens': 1541}
综上所述,Haystack是开发者手中的得力助手,专门用来打造处理海量文本或文档的LLM人工智能应用。它配备了丰富的组件,这些组件能够像乐高积木一样,通过不同的组合方式,拼装出各种AI解决方案。尽管掌握Haystack需要一些编程技能,但它的核心目标是让AI应用的开发变得更加亲民,让广泛的开发者都能轻松驾驭。
相关文章:
全新大模型框架Haystack,搭建RAG pipeline
大家好,在AI应用开发的赛道上,目前Haystack以其开源框架的优势,成为LLM技术领域的一匹黑马,对现有竞争者构成挑战。本文将介绍Haystack的亮点优势,并分析它为何能在众多LLM框架中脱颖而出,通过RAG应用实例来…...
儿童孤独症专家分享:了解治疗与支持的专业帮助
在儿童的成长旅程中,每一步都充满了探索与发现。然而,对于患有孤独症的儿童来说,这段旅程往往伴随着更多的挑战与困难。孤独症,这个看似遥远的词汇,却深刻地影响着无数家庭的生活。作为儿童孤独症领域的专家࿰…...

初始JavaEE篇——多线程(7):定时器、CAS
找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏:JavaEE 目录 定时器的使用 定时器的原理 模拟实现定时器 CAS 介绍 CAS的应用场景 解析 AtomicInteger 类 实现自旋锁 CAS的缺陷…...

高精度计算(乘)
引言 此篇是专栏信息学杂谈第八篇高精度计算(乘),展示了关于C如何实现高精度乘法的代码 正文: 乘法进位 c[i j - 1] a[i] * b[j] x; //x为之前进位 x c[i j - 1] / 10; c[i j - 1] % 10;完整代码: #include …...
在vue中 如何实现跨域
跨域问题是Web开发中常见的挑战,那么如何解决跨域呢,我们一起来看看吧! 跨域是什么? 跨域(Cross-Origin)是指网络请求从一个域名(origin)发起,而请求的目标资源位于另一…...

计算机考研,选择西安交通大学还是哈工大?
C哥专业提供——计软考研院校选择分析专业课备考指南规划 经过全面分析,2025年考研西安交通大学和哈尔滨工业大学计算机专业的报考难度对比如下: 西安交通大学计算机专业 > 哈尔滨工业大学计算机专业 对于想要报考985高校计算机专业但核心目标是优…...

微积分复习笔记 Calculus Volume 1 - 4.4 The Mean Value Theorem
4.4 The Mean Value Theorem - Calculus Volume 1 | OpenStax...

Cpp多态机制的深入理解(20)
文章目录 前言一、多态的概念二、多态的定义与实现两个必要条件虚函数虚函数的重写重写的三个例外override 和 final重载、重写(覆盖)、重定义(隐藏) 三、抽象类概念接口继承和实现继承 四、多态的原理虚表和虚表指针虚函数调用过程动态绑定与静态绑定 五、那...那单继承甚至多…...

(六)Python结构数据类型
一、集合类型(Sets) Sets(集合)是一个无序不重复的元素集。主要功能是自动清除重复的元素。创建集合时使用大括号{}包含其中元素。 Food{西瓜,南瓜,冬瓜,北瓜} print(Food) 输出结果: 增加重复元素,则会…...

C++进阶-->多态(Polymorphism)
1. 多态的概念 多态,顾名思义多种形态;多态分为编译时多态(静态多态)和运行时多态(动态多态),静态多态就是就是我们前面讲的函数重载和函数模板,可以通过传不同类型,然后…...

python实战项目51:selenium结合requests获取某众点评评论
python实战项目51:selenium结合requests获取某众点评评论 一、selenium获取cookies二、利用requests发送请求三、注意事项四、完整代码一、selenium获取cookies 首先,初始化selenium的webdriver,然后使用webdriver打开某众点评主页,之后手动扫码登录,利用selenium的get_c…...
面试准备第一版ssm spring-springmvc
请写出spring中常用的依赖注入方法: 1、setter 2、构造方法注入 3、字段注入 Setter 注入: 通过公共的 setter 方法进行依赖注入。优点:可选依赖,能更清晰地看到依赖关系。缺点:依赖在构造时不可用,可能导…...

Ubuntu学习笔记 - Day1
文章目录 学习目标:学习内容:学习笔记:Linux简介基于Linux内核的系统 Ubuntu简介GNU简介 远程连接Ubuntu查看Ubuntu的IP地址Mac连接Ubuntu此时可能显示报错,连接被拒绝解决办法连接成功连接退出 学习目标: 一周掌握 Li…...
挑战Java面试题复习第4天,坚持就是胜利
挑战第 4 天 Excption与Error包结构OOM 知识点SOF 知识点线程程序进程知识点有些字段不想序列化,怎么办?说说 IO 流Java IO与 NIO的区别 Excption与Error包结构 运行时异常(RuntimeException): 包括RuntimeException…...

Android 虚拟化框架(AVF)指南
Android 虚拟化框架(AVF)指南 一、项目介绍二、项目特色三、如何使用AVF四、总结 随着移动设备的普及和应用场景的多样化,安全性和隐私保护成为了移动操作系统的重要课题。Android作为全球最广泛使用的移动操作系统之一,一直在不断…...

day-77 超级饮料的最大强化能量
思路 动态规划:因为每一步要么选A,要么选B,所以问题可以转换为求最后一步从A选或从B选中的较大值 解题过程 定义而二维数组dp,dp[i][0]表示最后一步从A取能获得的最大能量,dp[i][1]表示最后一步从B取能获得的最大能量状态转换方程…...

有道小P 1.0.8 | 完全免费的AI全科学习助手,家长的好帮手
有道小P是一款由网易有道出品的完全免费的AI全科学习助手,专为中小学生设计。它支持多种输入方式,包括文字、语音和拍照识别,能够覆盖十个科目的所有题型,提供详细的解析和逐步解答,帮助孩子们理解和吸收知识。此外&am…...

vue项目中如何在路由变化时增加一个进度条
在 Vue.js 项目中,使用路由(如 Vue Router)时,为了提升用户体验,你可能会想要在路由变化时显示一个进度条。这可以通过多种方式实现,其中一种流行的做法是使用第三方库,如 vue-loading-bar 或 n…...

如何解决mingw64安装后配置完环境变量仍然执行不了gcc命令以及Vscode中的环境路径配置中找不到gcc
配置环境变量教程很多,就不多说,说下耗费一小时解决的问题:mingw64安装后配置完环境变量仍然执行不了gcc命令 配置 了N次了,都还是在终端找不到指令,然后,将路径放到第一个,然后再看下…...

3-petalinux2018.3 摸索记录 - 命令驱动 _ 交叉编译链
一、命令行控制GPIO 对于ps端设备,在板卡的linux系统中,切换到/sys/class/gpio路径下可以看到目前挂载的gpio设备。 export: 导入用户空间 gpiochip: 系统中gpio寄存器信息 unexport: 移除用户空间 以MIO40和MIO42…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...

华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...

面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...