AI应用包括各种由不同组件执行的任务。为了简化AI工程师的工作,开源框架提供了用户友好的抽象,用于如数据加载器、大型语言模型(LLMs)、向量数据库和重排序器等核心组件,并涵盖了外部服务。这些框架正在探索最有效的方式来整合这些组件,重点是让开发者能够以最直观和高效的方式构建统一的AI系统。
在考虑的编排方式中包括链和管道流程,它们都基于有向无环图(DAG)模型。
今年年初(2024年),LlamaIndex 推出了我们的查询管线,这是一个声明式 API,旨在方便各种查询工作流的编排,适用于问题回答、结构化数据提取和自动化流程等应用程序。然而,在尝试通过集成循环来增强其功能,以支持更复杂的查询工作流时,我们遇到了一些挑战。这促使我们重新考虑有向无环图模型在代理环境中的适用性,并在我们的框架内探索替代方案,以适应更复杂的场景。
这导致了对工作流的探索过程。工作流是一种新的代理实现方式。它采用事件驱动架构。
基于图的框架的局限性是什么。基于图或DAG的方法,如LangGraph(以及我们之前的查询管道方案),需要做大量的幕后工作来确定这些。所有这些逻辑处理了大量的特殊情况。这在我们日益复杂的查询管道代码中变得越来越明显。
在有向无环图(DAGs)的背景下,无环特性意味着没有循环,这在日益自主的人工智能应用中可能具有限制性。开发人员需要能够实现自我修正机制来应对组件表现不佳的问题。即使不引入循环,查询管道也面临着许多挑战:
- 调试难题:识别问题变得繁琐。
- 执行过程不透明:组件的执行流程不够透明。
- 编排变得过于复杂:编排器变得过于复杂,需要管理许多边界情况。
- 可读性问题:复杂的管线难以读懂。
当循环被加入到查询管道时,这些问题变得更加突出。遇到了显著的痛点,比如:
- 复杂的逻辑: 核心的编排逻辑,比如 if-else 和 while 循环,杂乱地散布在图的边,使得代码冗长。
- 处理边界情况: 处理可选和默认值变得复杂,因为不清楚上游节点是否会传递这些参数。
- 自然流程的中断: 定义包含循环的图对开发基于代理系统的开发者来说感觉很不自然。需要明确指定“代理”节点的输入和输出边,导致与其他节点之间的通信变得冗长。
为了解决上述问题,LlamaIndex 提出了一种新的设计范式转变,称为 Workflows(工作流),这是一种事件驱动的架构。
什么是工作流程?这是一种通过事件来触发步骤,从而控制应用程序执行流程的方法。应用程序被分解为多个步骤,每个步骤在相应的事件触发时执行。
步骤其实就是Python中的函数。比如,它们可以是简单的单行代码,也可以是多行的复杂代码。
事件实际上是指任何我们可以注意到、观察到或记录下来的变化或情况。
通过结合步骤与事件,我们可以创建任意复杂的工作流程,封装逻辑性,从而使应用程序更容易维护和理解。
总之,工作流(以及事件驱动的编程方式)提供了更强大的解决方案。代码内部更加简单,因为现在完全由用户来决定接下来运行哪些步骤,如何进行调试,这大大减少了这些问题。如我们之前的查询管道等其他方式相比,这种做法大大减少了“黑盒子”问题。
LlamaIndex 工作流相比 LangGraph 有什么优势?
LlamaIndex工作流程提供了一些独特的特性和功能,使其与LangGraph区别开来,
- 数据连接器: 从各种原生来源(如API、PDF和SQL数据库)导入数据的工具。
- 数据索引: 将数据结构化为易于大型语言模型(LLM)消费的高效中间表示形式。
- 引擎: 不同类型的引擎用于通过自然语言访问数据:
- 例如,查询引擎:主要用于回答问题的界面,比如RAG(检索和生成)管道。
- 例如,聊天引擎:用于多轮对话的聊天界面。
4. 代理:由LLM增强的知识型工作者,包括简单的助手函数和API集成。ReActAgent实现定义了一组工具,这些工具可以是Python函数或LlamaIndex查询引擎中的任意一种,以对数据进行自动化推理和处理。
5. 可观察性/评估: 用于应用程序严格实验、评估和监控的集成.
6.LlamaCloud:LlamaCloud提供全方位的数据解析、摄取、索引和检索服务,其中包括领先的文档解析解决方案LlamaParse.
7. 社区与生态系统: 活跃的社区,比如用于自定义数据连接器的LlamaHub和用于快速启动项目的create-llama。
- 集成灵活性:既支持入门级又支持自定义构建。用户可以使用
llama-index
快速入门,或者使用llama-index-core
从LlamaHub添加特定集成,LlamaHub提供了超过300个集成包以上。
9. 高级检索和查询界面: 提供一个高级界面,用于输入大型语言模型 (LLM) 的提示,并检索上下文和增强知识的输出结果.
10. 初学者和高级用户易用性: 初学者可以使用高级API,只需几行代码即可导入并查询数据,而高级用户则可以使用底层API来自定义和扩展模块的功能。
11. 代理组件:能够自动对您的数据进行推理的核心模块,这些核心模块本质上就像代理一样。例如,SubQuestionQueryEngine 可用于多文档分析、查询转换、路由和LLM重新排序.
12. 原生的OpenAIAgent: 包含一个基于OpenAI API实现的OpenAIAgent
,允许快速开发代理功能.
13. 与其他框架的集成: 可以在其他代理框架中作为工具使用,如LangChain和ChatGPT,提供紧密集成并带来额外功能。
这些功能使LlamaIndex成为一个全面的框架,基于大规模语言模型构建增强上下文的生成式AI应用。
设计工作流,我们将使用LlamaIndex工作流在这里实现一个高级的RAG系统。
- 对数据创建索引
- 使用该索引和查询来检索相关文本片段
- 根据原始查询对检索到的文本片段进行重新排序
- 合成最终回复
高级RAG(检索增强生成)工作流程
为实现所使用的技术堆栈 代码实现部分先安装所需的依赖
pip install -qU llama-index # 安装快速更新的 llama-index 包
pip install -qU llama-index-llms-groq # 安装快速更新的 llama-index-llms-groq 包
pip install -qU llama-index-embeddings-huggingface # 安装快速更新的 llama-index-embeddings-huggingface 包
pip install -qU llama-index-utils-workflow # 确保你安装了最新的 llama-index-utils-workflow 包
pip install python-dotenv # 安装 python-dotenv 包
pip install pyvis # 安装 pyvis 包
2. 创建一个.env文件存放API密钥
GROQ_API_KEY = 你的 API 密钥(你的)
3.: 配置 Groq_API_Key.
导入 os
# 从 dotenv 模块导入 load_dotenv 函数
load_dotenv() # 从 .env 文件加载环境变量。
os.getenv("GROQ_API_KEY")
4. 导入所需的依赖
from llama_index.core import VectorStoreIndex
from llama_index.core.schema import NodeWithScore
from llama_index.core.response_synthesizers import CompactAndRefine
from llama_index.core import SimpleDirectoryReader
from llama_index.core import SimpleDirectoryReader, VectorStoreIndex
from llama_index.core.response_synthesizers import CompactAndRefine
from llama_index.core.postprocessor.llm_rerank import LLMRerank
from llama_index.core.workflow import (
Context,
Workflow,
StartEvent,
StopEvent,
step,
Event
)
from llama_index.core.workflow.utils import get_steps_from_class, get_steps_from_instance
from llama_index.llms.groq import Groq
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
5., 设置工作流中的事件。
为了处理这些步骤,我们需要定义一些事件。
- 传递给重排器的获取节点的事件
-
传递给合成器的排序节点的事件
其他步骤会用到内置的
StartEvent
和StopEvent
事件。
class RetrieverEvent(Event):
"""检索的结果"""
nodes: list[NodeWithScore] # NodeWithScore
class RerankEvent(Event):
"""重排检索节点的结果"""
nodes: list[NodeWithScore] # NodeWithScore
6. 设置工作流程
class RAGWorkflow(Workflow):
@step
async def ingest(self, ctx: Context, ev: StartEvent) -> StopEvent | None:
"""文档的入口点,由带有 `dirname` 属性的 StartEvent 触发。"""
dirname = ev.get("dirname")
if not dirname:
return None
documents = SimpleDirectoryReader(dirname).load_data()
index = VectorStoreIndex.from_documents(
documents=documents,
embed_model=HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5"),
)
return StopEvent(result=index)
@step
async def retrieve(
self, ctx: Context, ev: StartEvent
) -> RetrieverEvent | None:
"""RAG 的入口点,由带有 `query` 属性的 StartEvent 触发。"""
query = ev.get("query")
index = ev.get("index")
if not query:
return None
print(f"使用 {query} 查询数据库。")
# 将查询保存到全局上下文中
await ctx.set("query", query)
# 从全局上下文中获取索引信息
if index is None:
print("索引为空,加载一些文档后再进行查询!")
return None
retriever = index.as_retriever(similarity_top_k=2)
nodes = await retriever.aretrieve(query)
print(f"检索到了 {len(nodes)} 个节点。")
return RetrieverEvent(nodes=nodes)
@step
async def rerank(self, ctx: Context, ev: RetrieverEvent) -> RerankEvent:
# 重新排序节点的过程
ranker = LLMRerank(
choice_batch_size=5, top_n=3,
llm=Groq(model="llama-3.1-70b-versatile")
)
print(await ctx.get("query", default=None), flush=True)
new_nodes = ranker.postprocess_nodes(
ev.nodes, query_str=await ctx.get("query", default=None)
)
print(f"重新排序节点为 {len(new_nodes)}")
print(new_nodes)
return RerankEvent(nodes=new_nodes)
@step
async def synthesize(self, ctx: Context, ev: RerankEvent) -> StopEvent:
"""使用重新排序的节点生成流式响应。"""
llm = Groq(model="llama-3.1-70b-versatile")
summarizer = CompactAndRefine(llm=llm, streaming=True, verbose=True)
query = await ctx.get("query", default=None)
response = await summarizer.asynthesize(query, nodes=ev.nodes)
return StopEvent(result=response)
- 检查步骤是否正确执行
# 检查是否有 __step_config 属性,因为这里的重点是检查属性本身,而不是特定的步骤。
workflow = RAGWorkflow()
steps = get_steps_from_class(RAGWorkflow)
if not steps:
steps = get_steps_from_instance(workflow)
print(f"步骤:{steps}")
for step_name, step_func in steps.items():
step_config = getattr(step_func, "__step_config", None)
print(f"配置信息:{step_config}")
if step_config is None:
print(f"步骤 {step_name} 缺少 __step_config 属性")
回复
步骤定义:{'_done': <function 步骤完成 at 0x000001BD6E5F3880>, 'ingest': <function 数据摄入 at 0x000001BD07DEAB60>, 'rerank': <function 重新排序 at 0x000001BD07DEA160>, 'retrieve': <function 检索 at 0x000001BD07DEA5C0>, 'synthesize': <function 合成 at 0x000001BD07DEA0C0>}
配置:接受事件=[<class 'llama_index.core.workflow.events.StopEvent'>] 事件名称='ev' 返回类型=[<class 'NoneType'>] 上下文参数='ctx' 工作线程数=1 请求服务=[]
配置:接受事件=[<class 'llama_index.core.workflow.events.StartEvent'>] 事件名称='ev' 返回类型=[<class 'llama_index.core.workflow.events.StopEvent'>] 上下文参数='ctx' 工作线程数=1 请求服务=[]
配置:接受事件=[<class '__main__.RetrieverEvent'>] 事件名称='ev' 返回类型=[<class '__main__.RerankEvent'>] 上下文参数='ctx' 工作线程数=1 请求服务=[]
配置:接受事件=[<class 'llama_index.core.workflow.events.StartEvent'>] 事件名称='ev' 返回类型=[<class '__main__.RetrieverEvent'>] 上下文参数='ctx' 工作线程数=1 请求服务=[]
配置:接受事件=[<class '__main__.RerankEvent'>] 事件名称='ev' 返回类型=[<class 'llama_index.core.workflow.events.StopEvent'>] 上下文参数='ctx' 工作线程数=1 请求服务=[]
8. 调用工作流并将其可视化
import nest_asyncio
nest_asyncio.apply()
# 可视化
from llama_index.utils.workflow import draw_all_possible_flows, draw_most_recent_execution
# 绘制流程
draw_all_possible_flows(RAGWorkflow, filename="multi_step_workflow.html")
# 画出最近的执行流程
w = RAGWorkflow()
# 加载文档
index = await w.run(dirname="Data")
result = await w.run(query="什么是纤维肌痛?", index=index)
async for chunk in result.async_response_gen():
print(chunk, end="", flush=True)
draw_most_recent_execution(w, filename="rag_flow_recent.html")
回复
查询数据库:纤维肌痛是什么?
检索到2个节点。
纤维肌痛是什么?
将节点重新排序为2
[NodeWithScore(node=TextNode(id_='abde4b4c-b787-4003-acf5-2f5bd05d867c', embedding=None, metadata={'page_label': '137', 'file_name': 'fibromyalgia.pdf', 'file_path': 'c:\\Users\\PLNAYAK\\Documents\\workflow\\Data\\fibromyalgia.pdf', 'file_type': 'application/pdf', 'file_size': 632664, 'creation_date': '2024-09-09', 'last_modified_date': '2024-09-09'}, excluded_embed_metadata_keys=['file_name', 'file_type', 'file_size', 'creation_date', 'last_modified_date', 'last_accessed_date'], excluded_llm_metadata_keys=['file_name', 'file_type', 'file_size', 'creation_date', 'last_modified_date', 'last_accessed_date'], relationships={<NodeRelationship.SOURCE: '1'>: RelatedNodeInfo(node_id='7b100860-f0b3-445b-b5d6-21f021d8c3c0', node_type=<ObjectType.DOCUMENT: '4'>, metadata={'page_label': '137', 'file_name': 'fibromyalgia.pdf', 'file_path': 'c:\\Users\\PLNAYAK\\Documents\\workflow\\Data\\fibromyalgia.pdf', 'file_type': 'application/pdf', 'file_size': 632664, 'creation_date': '2024-09-09', 'last_modified_date': '2024-09-09'}, hash='65d90d8fae093e6a574c784e808701ce0596d595e3e6136f7f0b4a70be8d2b57'), <NodeRelationship.NEXT: '3'>: RelatedNodeInfo(node_id='7edbd742-55e9-4559-9e9f-55d8688c6e62', node_type=<ObjectType.TEXT: '1'>, metadata={}, hash='08366d434882c9ea475468bcff6e0fe183d4192c93617ec3cf3700cf03fd5a65')}, text='2023年2月 ◆ 第107卷,第2期 www.aafp.org/afp 《美国家庭医学杂志》137纤维肌痛的特点是弥漫性肌肉骨骼疼痛、疲劳、睡眠不佳和其他躯体症状。1全球约有10%到15%的成年人患有慢性弥漫性疼痛,其中许多人可能患有纤维肌痛。\n2,3 约2%的美国人患有纤维肌痛,尽管患病率因人群和诊断标准的不同而有所差异。\n3,4 纤维肌痛可以影响儿童和成人,在世界各地和各种文化中都有发现。女性的诊断频率高于男性;一项苏格兰调查发现,女性的诊断频率比男性高两倍到十四倍不等,取决于使用的标准。\n3,4 过去十年诊断标准的变化,包括特定触痛点的消除,导致更多患有慢性疼痛的患者符合纤维肌痛的诊断标准。\n3-5\n病理生理学\n纤维肌痛可能是由中枢疼痛信号处理紊乱引起的,导致高敏和痛觉过敏,这与慢性疼痛状况如肠易激综合症、间质性膀胱炎、慢性盆腔疼痛和慢性下背痛相似。\n6,7 功能性脑成像表明,这种异常处理可能归因于兴奋性和抑制性神经递质之间的不平衡,特别是在岛叶。\n8 建议的病因包括下丘脑-垂体-肾上腺轴和自主神经系统功能障碍、弥漫性炎症、小胶质细胞激活、小纤维神经病以及感染如EB病毒、莱姆病和病毒性肝炎。\n9 双胞胎研究表明,遗传因素也可能是影响因素之一。10纤维肌痛:诊断和管理\nBradford T. Winslow,医学博士,科罗拉多大学医学院,科罗拉多州奥罗拉;瑞典家庭医学住院医师,科罗拉多州恩格尔伍德\nCarmen Vandal,医学博士,和Laurel Dang,医学博士,瑞典家庭医学住院医师,科罗拉多州恩格尔伍德\n CME 本文的临床内容符合AAFP的CME标准。如需CME测验,请参阅第127页。\n作者披露:无相关财务利益。\n患者信息:本文作者撰写的关于该主题的手册可在该文章的在线版本中找到。\n纤维肌痛是一种慢性中枢性疼痛综合症,特点是疼痛刺激处理紊乱。纤维肌痛在女性中诊断频率较高,全球范围内均有发现,影响2%的美国人。纤维肌痛患者表现出弥漫性慢性疼痛、睡眠不佳、疲劳、认知功能障碍和情绪紊乱。可能伴随的功能性躯体综合症、精神障碍和风湿病等共病状况也可能存在。对于有弥漫性慢性疼痛的患者,可通过纤维肌痛快速筛查工具进行筛查。可使用美国风湿病学会标准或Analgesic、Anesthetic和Addiction临床试验转化创新机会和网络-美国疼痛学会疼痛分类标准来诊断纤维肌痛。建立诊断并进行教育可以安抚患者,减少不必要的检测。多学科方法结合非药物疗法和药物来缓解症状最为有效。患者教育、锻炼和认知行为疗法可改善疼痛和功能。度洛西汀、米纳普兰、普瑞巴林和阿米替林可能是治疗纤维肌痛的有效药物。而非甾体抗炎药和阿片类药物对纤维肌痛没有显示出益处,且存在显著局限性。\n(Am Fam Physician\n. 2023; 107(2): 137-144. 版权 © 2023 American Academy of Family Physicians.)\n插图由Jonathan Dimes绘制\n从《美国家庭医学杂志》网站www.aafp.org/afp下载。版权 © 2023 American Academy of Family Physicians。仅供个人非商业使用。所有其他权利保留。如需版权问题或请求授权,请联系copyrights@aafp.org。下载自美国家庭医师网站www.aafp.org/afp。版权 © 2023 American Academy of Family Physicians。', mimetype='text/plain', start_char_idx=0, end_char_idx=4397, text_template='{metadata_str}\n\n{content}', metadata_template='{key}: {value}', metadata_seperator='\n'), score=10.0), NodeWithScore(node=TextNode(id_='0a680a09-1f8d-409e-bbdc-b562b4879f6f', embedding=None, metadata={'page_label': '138', 'file_name': 'fibromyalgia.pdf', 'file_path': 'c:\\Users\\PLNAYAK\\Documents\\workflow\\Data\\fibromyalgia.pdf', 'file_type': 'application/pdf', 'file_size': 632664, 'creation_date': '2024-09-09', 'last_modified_date': '2024-09-09'}, excluded_embed_metadata_keys=['file_name', 'file_type', 'file_size', 'creation_date', 'last_modified_date', 'last_accessed_date'], excluded_llm_metadata_keys=['file_name', 'file_type', 'file_size', 'creation_date', 'last_modified_date', 'last_accessed_date'], relationships={<NodeRelationship.SOURCE: '1'>: RelatedNodeInfo(node_id='f2591e71-4fd5-48ef-8c08-ab465fdabf88', node_type=<ObjectType.DOCUMENT: '4'>, metadata={'page_label': '138', 'file_name': 'fibromyalgia.pdf', 'file_path': 'c:\\Users\\PLNAYAK\\Documents\\workflow\\Data\\fibromyalgia.pdf', 'file_type': 'application/pdf', 'file_size': 632664, 'creation_date': '2024-09-09', 'last_modified_date': '2024-09-09'}, hash='e0f0653ead2af78ad773abacd139db824a7e40216476d9aa63077b83a7370686')}, text='138 《美国家庭医学杂志》www.aafp.org/afp 第107卷,第2期 ◆ 2023年2月\n纤维肌痛\n临床表现\n慢性弥漫性疼痛是大多数纤维肌痛患者的首要症状。患者还可能经历肌肉僵硬和触痛。纤维肌痛患者的体格检查通常发现弥漫性触痛,而没有其他异常发现。如果有关节肿胀、炎症或畸形,应考虑其他或额外的诊断。\n5\n疲劳和睡眠障碍也很常见。5,11 睡眠障碍包括难以入睡、保持睡眠或在睡眠后感觉未得到充分恢复。5,6,12 认知症状如注意力不集中、健忘或思维改变也很常见。患者将这种认知障碍称为“fibrofog”,描述为精神变慢,影响日常活动。\n13\n同时存在其他疼痛性疾病并不排除纤维肌痛的诊断。纤维肌痛快速筛查工具可以用于筛查有弥漫性慢性疼痛的患者,帮助区分纤维肌痛和其他状况(表1)。\n14 该工具可SORT: 关键实践建议\n临床建议 证据评级 评论\n对于患有弥漫性疼痛、疲劳和睡眠障碍至少三个月的患者,应考虑纤维肌痛的诊断。\n5,11 纤维肌痛的诊断可以使用AAPT 2019诊断标准或美国风湿病学会2011/2016标准\n纤维肌痛患者应采用多学科治疗方法,包括教育、锻炼和非药物和药物选项。\n27,28C 共识指南和系统评价\n认知行为疗法可以在短期内改善纤维肌痛患者的疼痛和残疾。\n32,34,35A 系统评价显示改善效果\n阿米替林、环苯扎林、度洛西汀(Cymbalta)、米纳普兰(Savella)和普瑞巴林(Lyrica)在纤维肌痛疼痛治疗上有效。\n43,46-48,50,52,54A 系统评价显示这些药物有效\nAAPT = Analgesic、Anesthetic和Addiction临床试验转化创新机会和网络-美国疼痛学会疼痛分类。\nA = 一致、高质量的患者导向证据;B = 不一致或低质量的患者导向证据;C = 共识、疾病导向证据、常规实践、专家意见或个案系列。有关SORT证据评级系统的更多信息,请访问 https://www.aafp.org/afpsort。\n表1\n纤维肌痛快速筛查工具(FiRST)\n是\n我全身都有疼痛。\n我的疼痛伴随着持续而非常不愉快的持续疲劳。\n我的疼痛感觉像是烧灼、电击或抽筋。\n我的疼痛伴随着其他身体上的异常感觉,如针刺、刺痛或麻木。\n我的疼痛伴随着其他健康问题,如消化问题、泌尿问题、头痛或不安腿综合症。\n我的疼痛对我的生活产生了重大影响,特别是在我的睡眠和我的注意力方面,使我整体感觉迟钝。\n总计*\n*—每个“是”答案得1分。总分5分或以上提示纤维肌痛。\n改编自 Perrot S, Bouhassira D, Fermanian J; CEDR (Cercle d’Étude de la Douleur en Rhumatologie)。纤维肌痛快速筛查工具(FiRST)的开发和验证。Pain。2010;150(2):255。\n下载自ClinicalKey.es Elsevier于2023年3月24日,供National Library of Health and Social Security Boletin-BINASSS (bolet-binas@binasss.sa.cr) 使用。版权 ©2023 Elsevier Inc.保留所有权利。', mimetype='text/plain', start_char_idx=0, end_char_idx=3975, text_template='{metadata_str}\n\n{content}', metadata_template='{key}: {value}', metadata_seperator='\n'), score=8.0)]
纤维肌痛是一种慢性中央性疼痛综合症,特点是疼痛刺激处理紊乱。它表现为弥漫性肌肉骨骼疼痛、疲劳、睡眠不佳和其他躯体症状。
可视化工作流程
工作流程观察- 我们有两个入口点,即接受
StartEvent
的步骤 - 各步骤自己决定何时运行
- 工作流上下文用来保存用户的查询信息
- 节点被传递,最终返回一个流式响应
- 工作流由StartEvent触发。
- StartEvent触发ingest步骤,将文档索引化、切分并加载到向量存储中。
- ingest步骤返回生成的索引,此步骤由StopEvent关闭,从而结束该步骤。
- StartEvent然后触发检索步骤,输入包括查询和索引。
- 检索步骤触发RetrieverEvent,返回与查询匹配的节点。
- RetrieverEvent触发重排序步骤,输入为匹配的节点。
- 重排序步骤按节点与查询的相关性重新排序匹配的节点,并触发RerankEvent。
- RerankEvent然后触发合成步骤,根据重新排序的节点生成最终响应。
当前的流程可视化展示
关于工作流执行的几点看法:</TRANSLATION>
以下是我根据观察的一些详细见解和建议。
1. Python 3.11.0 的兼容性
观察: 流程和可视化在Python 3.11.0中工作正确.
推荐: Python 3.11.0 支持使用 | 运算符进行类型注释,这简化了类型提示。如果可能,建议使用 Python 3.11.0 或更高版本进行开发,以利用这些功能并避免兼容性问题的困扰。
2. Python 3.9.12 兼容性
观察:在Python 3.9.12里,| 操作符无法使用,你得去修改utils.py里的num_of_events
推荐如下:
类型提示: 在Python 3.9版本中,使用typing模块里的Union,而不是用|操作符进行类型注解。
修复验证: 直接在utils.py
中修改num_of_events
是一个临时解决方案,但不是理想的方案。相反,确保每个步骤函数恰好有一个使用Event
类型注解的参数以通过验证检查。
3. 数据可视化在Google Colab
观察:即使设置了 notebook=True 参数,Google Colab 中的可视化功能也无法正常运行.
推荐:
确保正确安装所有必需的库:确保所有必需的库都已安装在Colab里。
!pip install pyvis llama-index-core llama-index-llms-openai llama-index-embeddings-openai llama-index-readers-file llama-index-utils-workflow
# 渲染HTML的检查:使用以下方法在Colab中渲染HTML内容:
from pyvis.network import Network
from IPython.core.display import display, HTML
def draw_all_possible_flows(
workflow: Workflow,
filename: str = "workflow_all_flows.html",
notebook: bool = True, # 将notebook设为True
) -> None:
net = Network(directed=True, height="750px", width="100%")
# 添加停止事件的节点和边
net.add_node(
StopEvent.__name__,
label=StopEvent.__name__,
color="#FFA07A",
shape="ellipse",
)
net.add_node("_done", label="_done", color="#ADD8E6", shape="box")
net.add_edge(StopEvent.__name__, "_done")
# 添加从所有步骤的节点
steps = get_steps_from_class(workflow)
if not steps:
# 如果类中没有定义步骤,则尝试从实例中获取
steps = get_steps_from_instance(workflow)
step_config: Optional[StepConfig] = None
for step_name, step_func in steps.items():
step_config = getattr(step_func, "__step_config", None)
if step_config is None:
continue
net.add_node(
step_name, label=step_name, color="#ADD8E6", shape="box"
) # 步骤节点用浅蓝色
for event_type in step_config.accepted_events:
net.add_node(
event_type.__name__,
label=event_type.__name__,
color="#90EE90" if event_type != StartEvent else "#E27AFF",
shape="ellipse",
) # 事件节点用浅绿色
# 添加所有步骤的边
for step_name, step_func in steps.items():
step_config = getattr(step_func, "__step_config", None)
if step_config is None:
continue
for return_type in step_config.return_types:
if return_type != type(None):
net.add_edge(step_name, return_type.__name__)
for event_type in step_config.accepted_events:
net.add_edge(event_type.__name__, step_name)
if notebook:
net.show(filename, notebook=True)
with open(filename, "r") as file:
display(HTML(file.read()))
else:
net.show(filename)
# 在Google Colab中的示例用法
draw_all_possible_flows(
RAGWorkflow, filename="multi_step_workflow.html", notebook=True
)
总结
- Python 3.11.0:与 | 操作符和工作流可视化兼容良好。
- Python 3.9.12:使用 Union 进行类型注解,并确保正确注解事件参数,以避免修改 utils.py。
- Google Colab:确保所有依赖项已安装,并使用提供的方法来渲染 HTML 内容。
通过遵循这些建议,你就可以在不同的环境和Python版本间达到一致的功能。
最后说一下随着人工智能应用变得越来越复杂和具有代理功能,传统有向无环图(DAGs)的局限性变得越来越突出。无法包含循环限制了开发人员实施自我修正机制的能力,这对于保持稳健和适应性强的人工智能系统至关重要。
向前发展,探索能够适应现代AI应用动态性和迭代性的替代框架体系至关重要。通过优先考虑直观的设计和高效的编排,我们能帮助开发者创建更加强大和适应性强的AI系统,这些系统能够从错误中学习并在日益复杂的环境中蓬勃发展。
在这里,我们利用LlamaIndex Workflow实现了一个案例。我们还需要做更多的实验来充分了解它的潜力,并且让它在实现和理解复杂架构时更加简单易懂。
参考链接: LlamaIndex 工作流 beta 版本:一种创建复杂 AI 应用程序的新方式——LlamaIndex 是一个简单且灵活的数据框架,可以将自定义数据源与大型语言模型 (LLMs) 相连接。www.llamaindex.ai](https://www.llamaindex.ai/blog/introducing-workflows-beta-a-new-way-to-create-complex-ai-applications-with-llamaindex?source=post_page-----bd6047299fa5--------------------------------) 体验全球最快的推断:GroqCloud console.groq.com注:我在此声明,上述实验均为本人所做,实施时参考了网上的相关资料。
共同学习,写下你的评论
评论加载中...
作者其他优质文章