去年,我写过关于先进的检索增强生成技术(RAG)是如何开始进入企业以及多代理软件工程(MASE)的出现。这两项生成AI在软件开发中的支柱技术自那时以来已经演变,相互交织,预示着企业AI应用领域的重新定义。
智能代理的真正内涵首先,让我们探索一下构成一个AI代理是什么样的?一些开发者将代理描述为能够思考与行动、行动和记忆的自主实体。比如说,一个ReACT代理,比如一个能够推理和行动的代理。那么,ReACT代理具体是什么呢?我认为它们由三个核心要素构成。
1. 智能: 代理访问大型语言模型(LLM)。
2. 知识: 它在特定领域或主题上的结构化和非结构化数据集。
3. 接收器和效应器: 使代理能够感知环境并执行任务的工具和API接口。
以下是一个典型的代理的简单图示,该代理使用Anthropic LLM作为智能,一个exa-search和一个连接到SingleStore的检索器作为工具,通过检索器工具获取知识。
Flowise 中构建的一个由智能、工具和知识构成的代理程序.
企业中的RAG的发展:企业中的RAG的演变
在生成式AI的世界里,去年似乎已是很久以前,当时开发者开始探索将自定义数据输入大型语言模型以增强上下文理解。在我称之为“搜索和检索”之前,这个词变得广为人知,也就是现在所说的“增强检索生成技术”(RAG)。不过,RAG 不仅流行起来,还迅速席卷了整个软件开发界。
然而,这种简单的方法,常被称为“朴素的RAG”,难以满足大型企业的复杂需求。这些组织通常拥有大量的结构化和非结构化数据,在构建企业级AI应用的过程中遇到了三大难关,这些挑战包括数据的准确度、相关度和延迟。
原来,最主要的原因为大多数企业去年并未看到可投入生产的应用显著增长。
但现在事情发展得很快,现在我们终于看到了一些原则结合的苗头,这让我们看到了企业级软件开发步入了一个全新的时代的前景。
首先,让我们审视一下在企业环境中使RAG应用程序准备好投入生产所需的关键需求:
1. 准确性: 在企业环境中,对错误或错误信息零容忍。特别是在金融和医疗等关键行业,错误的余地根本不存在。
2. 相关性: 随着规模的扩大,资源成本变得更高,因此信息检索必须精准,仅查询必要的数据。这也直接影响到下一个要点。
3. 延迟: RAG 管道必须像思考一样迅速运行,在一秒钟内完成任务,以保持无缝的用户体验,假设主模型的推理仍然需要大约一秒的时间在网络上响应。
精准与速度的魔法
我们如何做到这一点精准性和速度的炼金术般的结合呢?我们来看看每一类以及一些最佳实践吧。
1. 准确性: 这里有几个方面需要注意——微调的嵌入模型和匹配的LLM、有效的评测、对结构化数据的功能调用以及通过基于人类反馈的强化学习(RLHF)实现的实时监控和反馈循环。
2. 相关性: 大多数公司都有数据湖、数据仓库或数据湖仓。所有这些数据对于相关性和与实时数据的混合来说都非常重要,因为如果响应仅包含某个时间点的数据,不仅会使响应变得无关,还会变得危险地不准确。采用实时数据几乎已成为AI应用的基本要求。
3. 延迟: 架构必须优化以确保亚秒级的响应时间。如果响应时间更长,整体体验将变得较差,进而影响产品的接受度。
现在为了构建这个堆栈,每一层都有几种选择,我列出了我在与一些公司交流时发现最常用的那些。
嵌入式创建 — Nvidia 推理微服务(NIMs)在众多其他竞争解决方案中脱颖而出。你可以调用 Nvidia API 或租用/购买自己的 H100 并部署模型。这可能不是每个公司的最佳选择,但如果你需要快速,Nvidia 在这个领域显然是领导者。
Nemo真正有用的是你能够将其部署成一个服务器,这个服务器有一个端点,可以从代理调用,作为工具来使用。
你可以在这里查看Nemo的一些示例和文档。
语义缓存技术 — 你可以选择多种数据存储和框架,但根据我的经验,我总是推荐使用一个能够快速高效处理所有数据使用场景的平台来涵盖所有数据需求。我个人推荐SingleStore,不过为了透明起见,我需要说明我的观点可能有偏见,因为我曾在SingleStore工作。
检索 — 继续上述主题中的讨论,检索包括结构化和非结构化数据,这包括语义搜索和关键词搜索,涵盖像JSON、SQL和键值这样的数据。在这里,你可以使用SingleStore在一个单一查询中完成这一切操作,并在PB级别的数据中实现亚秒级的响应时间。
安全与防护 — 在这里,Nvidia 的 Nemo 安全护栏无疑是一个不错的选择。从去年开始,这个开源库已经取得了长足的进步,现在可以进行输入和输出验证、保护 PII 等操作,并且具有很高的灵活性和适应性。
评价 — 我去年提到过,依旧推荐这个开源库 — RAGAs。这个开源库与我们选择用来整合这一切的框架非常兼容。
巨石与模块正如你可以想象的,去年每一层或步骤都在流水线中独立发展开来,开发人员开始将这些系统按顺序构建成流水线,但这种方法存在很多限制:僵化、延迟、准确性下降和相关性降低。这种单体架构让人想起老旧的 C 或 C++ 应用程序,虽然它们性能不俗,但也可以说既笨重又缺乏灵活性。
迎接多代理检索增强系统(MARS)时代的到来。
现在想象如果我们使用我们选择的工具来执行上述步骤和任务,并构建一系列专门的代理(Agents),每个都是其领域的专家,配有专门的工具。这样,这些代理可以被协调以并行运行,从而获得更好的性能和更高的可扩展性,就像微服务那样。
这种方法还带来几个额外的优势:
- 可维护性:专门的代理可以应对不同的任务,允许独立更新和工具替换。
- 并行性:代理可以同时运行,利用到不同的GPU或计算资源。
- 优化资源:工作负载可以根据任务分布在GPU和/或基于CPU的通用计算资源上,以提高效率。
- 效率和准确性:通过在不同代理中隔离特定任务,有助于调试和基于RLHF的迭代评估过程。
现在我们已经确定了不同的任务和所选的库,我们需要考虑两件事,然后才能将这一切整合起来。首先,我们来选择一个框架来搭建工作流程。
在这里,你可以使用像Autogen或CrewAI这样的代理框架,但与其使用一个监督代理和一个每次结果都不确定且不可预测的合作框架,我更会选择Langchain的LangGraph,原因有二——易于使用,且能与NIMs和Nemo Guardrails等工具集成。此外,我喜欢可以根据企业需求构建“图”的这一点,而这些需求可能因公司不同而大相径庭。
其次,让我们看看与其他代理一起进行的一些额外增强,以使我们的架构更加高效和高性能的架构。
嵌入创建:我们可以添加一个预处理代理,在生成嵌入之前进行数据清洗。
语义缓存:SingleStore非常理想,但我们也可以添加一个缓存管理代理来处理缓存的失效和更新。Langchain在其自己的API中也提供了此项功能。
检索:一旦掌握了基础部分,我们还可以添加一个查询理解代理,在数据检索之前添加更多的上下文信息。
安全和隐私保护:Nemo Guardrail在此方面至关重要,但添加一个单独的PII检测和屏蔽代理也是非常有价值的,例如Protecto。
评估:目前,我们暂时使用RAGAs,尽管我们也可以使用其他代理来利用其他框架并在结果上进行比较。
由于该架构的模块化特性,我们现在也可以构建额外的智能代理,可以根据最终需求随意添加、修改或移除这些智能代理。
查询规划代理: 制定回答查询的最佳方案。
上下文增强代理: 用额外的上下文信息增强检索到的内容。
响应生成代理: 根据增强的信息生成最终回复。
反馈集成代理: 处理用户反馈来优化系统。
日志和监控代理: 管理全面的日志记录和实时监控工作。
数据版本控制代理: 监控数据、嵌入和模型工件的版本,以确保可重复性。
为了协调这个多代理RAG系统,正如上面所说的,我选择了LangGraph。它在设计多代理系统方面表现出色,具有灵活的图结构、稳定的状态管理、与LangChain的集成能力、可视化工具的支持以及可扩展的特点,使其成为企业级应用的理想工具。
代码实现部分步骤 1 — 创建一个代理程序
首先,让我们来看一下使用LangGraph实现的一个简单的代理。
# 增强代理初始化
enrichment_agent = 初始化代理(
[热销产品工具],
chat_model,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, # 无需反应描述的零样本代理类型
verbose=True # 详细输出
)
准备工具
注意我们是怎么把工具交给代理的。这里定义好,当代理需要运行查询时会调用。
top_selling_products_tool = Tool(
name="最热销的产品",
func=get_top_selling_products,
description="获取最热销的产品。你可以设定数量限制,默认为5"
)
这个工具用一个叫get_top_selling_products的函数来获取结构化的数据。
def 获取热销产品(limit=5):
sql查询 = f"""
SELECT product_name, SUM(quantity_sold) as total_sold
FROM sales
GROUP BY product_name
ORDER BY total_sold DESC
LIMIT {limit}
返回 db.run(sql查询)
步骤 3 — 使用图形、节点和边来构建一个工作流程
我们创建一个图,该图包含一个工作流及其节点和边。接着,我们将节点和边添加到工作流中并运行整个工作流。
这里是一个通过提供一个有状态图来创建工作流的例子。AgentState 负责维护整个工作流的状态。
流程图工作流定义为状态图,状态图由AgentState定义。
workflow = StateGraph(AgentState)
最后,我们把这些东西放在一起。
# 添加SQL代理节点和丰富数据代理节点
graph.add_node("sql_agent", sql_agent)
graph.add_node("enrichment_agent", "丰富数据代理")
# 定义基于图的处理流程
@graph.run # 在图上运行定义的工作流程
def workflow(query: str):
sql_result = graph.nodes.sql_agent(query)
enriched_result = graph.nodes.enrichment_agent(sql_result)
return enriched_result
要查看一个完整的代理RAG示例,请参阅这里。
结论部分显然这里只是浅尝辄止,正如所述,我们可以选择不同的技术和方案来构建定制的多代理检索增强系统(MAR)。希望这能为你打下一个良好的基础,如果你希望了解构建企业级AI应用程序所需内容以及整体框架和走向不仅模块化而且可扩展和可控的道路(如我们所熟知的微服务风格的架构)。
最新更新 — 看看我下一篇关于这个系列的文章 — 关于AI应用的七个因素(https://medium.com/p/4528d02d0e83)
✌️ 表示和平 (biǎoshì hépíng)
喜欢这些内容吗?感谢您一直看到这里。我叫Madhukar,我在技术(特别是AI)和创意的交汇点工作。我喜欢开发应用,也爱写关于企业AI、PLG(Product-Led Growth)和营销技术的文章。
欢迎通过LinkedIn联系我,如果你有兴趣合作的话。
免费订阅, 以便在有新故事时收到通知.