探索Active Agent:用Rails方式构建AI功能
在AI技术渗透到每个角落的快节奏世界中,框架和生态系统必须快速适应不断演变的业务需求。每个应用都需要智能功能。在使用某些框架构建的项目中添加AI驱动功能的便捷性,直接决定了该框架能否成为首选工具。假设"某些框架"是"Ruby on Rails",让我们探索这个生态系统的AI就绪程度!
Ruby和Rails的AI生态系统
Ruby和Rails的AI生态系统在AI革命爆发后迅速起飞。从非官方的LLM提供商SDK(如ruby-openai)发展到专门的库,如Raix和RubyLLM。每个库都提供了将大语言模型集成到Ruby应用程序的不同方法,但对我来说,它们都没有提供Rails所缺失的AI抽象层。
我更喜欢遵循Rails约定和设计原则的抽象,能带来熟悉的用户体验。Raix和RubyLLM都专注于为与AI聊天提供通用接口(它们做得很好),但没有超越这个层面(在分层架构意义上,它们主要覆盖基础设施层)。
Active Agent的承诺
另一方面,Active Agent承诺填补Rails抽象堆栈中的空白,并以Rails的方式带来LLM驱动的功能。
当我从朋友Justin那里听说Active Agent时,这正是吸引我的地方。巧合的是,那时我开始考虑《Ruby on Rails应用程序分层设计》第二版的想法,而Active Agent背后的概念听起来正是我为相应新章节所设想的。因此,我决定成为早期采用者,并在Evil Martians推广Active Agent。
Active Agent是否兑现了作为Rails原生AI库的承诺?让我们通过实际示例尝试回答这个问题,并探索Rails中AI的未来可能。
Active Agent简介
Active Agent gem为Rails带来了新的抽象:代理(毫不意外!)。代理旨在封装AI支持的逻辑,并通过使用熟悉的Rails模式将其与框架的其余部分粘合在一起:动作驱动对象(如控制器、通道和邮件程序)、回调(当然!)以及由Action View支持的提示渲染。虽然控制器负责将HTTP请求转换为响应,邮件程序负责编写和发送电子邮件,但代理的主要目的是触发各种AI生成。
让我们通过尝试实现AI的"hello world"——“给我讲个故事"代理来看看Active Agent的实际应用。不过在我们的案例中,将是"给我讲个笑话”。
以下是JokerAgent类的代码:
|
|
对于Rails开发人员来说,这段代码看起来非常熟悉,几乎不需要解释它的作用。接下来,我们可以这样使用它:
|
|
如您所见,有两种模式可用:您可以立即获取生成结果(同步)或将其移动到后台作业(尽管在这种情况下,您必须使用回调来处理结果)。添加使用提示对象作为LLM请求表示,您将看到它如何与Action Mailer非常相似,只是将"deliver_“替换为"generate_"。
实际应用案例
案例1:类似Twitter的按需翻译
我首次测试Active Agent的机会是在它宣布后不久。我正在开发一个内部Martian团队建设项目,并参与典型的帖子-评论-回复对话层次结构。
我们的团队是多语言的,为了让这个项目"温暖而舒适”,我想让任何人都能用他们的母语表达自己的想法并消费他人的想法。因此,我们需要一个翻译功能,我决定采用按需翻译的方式。
以下是翻译代理代码:
|
|
这个例子引发了一个有趣的架构问题:代理是否应该封装整个操作,包括数据库更新,还是只生成结构化输出供其他抽象处理?换句话说,这个#update_record方法是否是架构异味?它是否遵循诸如关注点分离之类的常见良好设计原则?
案例2:Redprints CFP的AI审稿人
我们的第二个示例来自使用AI驱动的提案审稿人扩展我们的Redprints CFP应用程序。该代理评估会议提案,提供分数,并提供建设性反馈,以帮助组织者做出明智决策。
我们实验的ReviewAgent是针对SF Ruby会议的需求量身定制的。我们采用了三个标准来获取每个提案的初始分数:新颖性、相关性和质量(提案本身)。因此,我们需要教导我们的代理如何评估每个标准。
工具集成以查找演讲新颖性
评估标准之一是新颖性:我们希望对新演讲和主题给予更高评分。LLM是否能够知道哪些演讲和主题已经被过度使用?也许。然而,“也许"不是我们可以接受的非确定性水平。因此,我们决定为我们的代理提供搜索Ruby演讲数据库的能力,并根据新颖性评分决定正在审查的提案之一。
首先,我们准备了来自最近几年选定会议的Ruby和Rails演讲的搜索索引。我们获取了RubyEvents"数据库”(YAML文件)并将其转换为Trieve数据集。
然后,我们为ReviewAgent定义了#search_talks工具:
|
|
工具只是一个方法,类似于其他操作。工具参数通过#params Hash访问。您可以使用模板来渲染结果。
测试策略
可维护代码的关键属性之一是可测试性。Active Agent没有提供任何现成的测试工具。当然,您可以使用Webmock或VCR来存根对LLM API的HTTP请求,但这对我来说似乎不太合适。
幸运的是,Active Agent以类似于Active Storage适配化存储服务或Action Mailer适配化传递机制的方式适配化生成提供者。唯一缺失的部分(目前)是适用于测试环境的生成提供者。不用担心,我们可以自己添加!
这是我们用于测试的fake_llm提供者版本:
|
|
未来挑战:Rails AI还需要什么
我们使用Active Agent的经验表明,虽然它为AI交互提供了类似Rails的约定,但AI应用程序领域需要更复杂的抽象。更准确地说,鉴于现代AI不断发展的性质,我们需要一个灵活且可扩展的框架,能够更快地适应变化。
以下是在为Rails应用程序构建AI驱动功能时可能需要额外工作的一些领域:
使用跟踪和AI积分
每个AI应用程序都需要使用监控和限制。用户应该有AI积分,租户应该有预算控制。AI引擎必须提供钩子来:a:跟踪使用情况,b:在没有积分可用时防止使用AI。
动态凭证和私有LLM
用户应该能够使用自己的API密钥或私有模型部署。
动态提示
硬编码的提示可能适用于较小的应用程序或基本用例。但随着使用量的增加,AI驱动的逻辑变得更加复杂,需要更多的优化。
防护和评估
您听说过提示注入吗?您确定您的提示生成的是您期望的内容,而不是一些幻觉吗?
安全始终是Rails的首要任务。AI框架必须鼓励用户构建安全的AI功能。必须验证用户输入,提示必须包括防护栏,输出也必须进行评估。
代理工作流
尽管我不会接触代理工作流(即任务编排由AI控制的工作流,因此是非确定性的),但对于某些功能来说,它可能是一个不错的选择。代理工作流可以建模为入口点编排器代理,在需要时将工作委托给其他代理。
内存和上下文持久化
对于对话式AI功能,请考虑RubyLLM。它开箱即用地提供消息持久化(由Active Record支持),非常适合此类用例。
代理通常需要记住先前的交互或在整个对话中维护上下文。内存可以是静态的(完全包含在上下文中)或动态的(可通过工具由LLM请求)、短期或长期、压缩或无损失。这些都值得拥有一个可集成到其他库中的专用库。
前进的道路
开放问题的数量是巨大的,大多数Rails AI库——包括Active Agent——仍然太年轻,无法回答所有问题。然而,我们应该期望这些库展示对日常需求的理解,并以可扩展的方式设计自己,以便其他人可以通过插件解决特定问题。
Active Agent显示出作为Rails式AI功能基础的前景。然而,真正的考验将是它是否能够演变为支持生产AI应用程序所需的复杂模式。该框架的成功最终将取决于其提供扩展点的能力,用于使用跟踪、高级检测、复杂工作流以及当AI从原型转向生产时出现的无数其他需求。