我已经开发智能家居API差不多十年了。我购买了多个系统,开发了多个版本的集成API、移动应用和聊天机器人。你可以在这里看看我这些年做了些什么(点击链接查看):这里
虽然这些项目都很令人兴奋且非常有趣,但它们从未真正达到目标——一个像《钢铁侠》里的贾维斯那样的真正的人工智能家庭。直到AI的出现。
旧世界 — 基础助手大型语言模型让聊天机器人变得非常先进,对话体验有了巨大提升。几年前,我用微软的Luis.ai开发了一个“聊天机器人”,那时它很先进,但现在看来就像个旧古董,我已经把它归档在单一仓库里了。那个聊天机器人只能处理那些用词完全正确的查询,如果你用错了短语,它就会无法工作。
这次我采取了自主代理的方式。不同于使用决策树类型的逻辑,代理依赖于大语言模型来进行“推理”。这意味着它们能处理更复杂的自然语言指令。比如,如果我让旧聊天机器人“在客厅关灯”——聊天机器人可能无法完成这个任务,因为它不知道“Lounge”是哪个房间——它只知道“Living Room”。我发现我妻子尝试了多种不同的说法,她会尝试其他说法,但这些同义词并未被Luis AI编程进去。现在,大语言模型只知道实际的房间名称,并能推理出不同叫法。
创建 LangGraph.AI 智能代理用真正的AI替换掉LUIS.ai其实并不难——开始使用LangGraph真的很简单。这个概念其实很简单,有一个带有基本系统提示的代理,可以给它输入任务提示。然后给代理提供一些“工具”,这些工具是与特定提示绑定的功能(例如,“你可以使用这个工具来控制灯光…”)。代理接着使用底层的LLM来决定应该使用哪些工具来回答任务提示。这里就是范式转变的地方。不再需要复杂的逻辑流程或决策树——旧的“AI不过是一大堆IF语句”的说法已经过时了——这些聊天机器人实际上可以独立思考了。
实际代码看起来最初真的很简单,但要实现一个完整的可运行代理,下面你可以看到它有多简单:传入一组工具,创建一些内存,并给它一个基本的系统提示,它就会处理请求。当我开始创建工具时,我才意识到自主代理的复杂性所在。
给代理人控制智能家居系统的工具给代理人提供一系列工具来在纸上管理房子似乎很容易。这个API接口已经以某种形式运行了将近十年——肯定很容易地添加一些工具提示吧?简直是异想天开。
这里是你真正需要考虑的地方,不仅仅是你的API平台中的“代理人的体验”,还要考虑“代理人的体验”。我碰到了一些非常有趣的bug。现在的天气和供暖API会返回摄氏度和华氏度的温度。显然UI会在这两者的温度中选择一个。LLM真的很难保持一致,直到我几次修改了代理的主要系统提示。
然而,一些工具几乎可以无缝地运行。我创建了一个GetLighting工具,这个工具会查询集成API,然后告诉代理灯光组的状态。定义工具提示花费了几次尝试,但最终弄成功了。诀窍似乎是要简明扼要,突出代理应该关注的关键信息。在调用工具时,已经通过JSON输出传递给它了。
一个使用 Zod 来控制家里的灯光的 LangGraph工具
状态变更也是如此简单(如上所述),主要是因为使用了Zod。Zod主要用来验证API的输入。LangGraph利用这个库来验证并记录工具规范,这使得代理能够提供执行工具所需的合约。这减少了对聪明提示的依赖,因为Zod处理了这些。我几乎第一次就能让代理控制灯光的开关、亮度和颜色。大部分API调用逻辑和验证都在一个SDK中,该SDK被用于聊天机器人、UI和NFC标签系统——不过,你可能注意到我增加了一些额外的验证。这里的主要变化是,UI通常会传递一个数字ID来表示房间——但LLM可能不会这么做。顺便说一下,这种潜在错误的变化也影响了代理的错误处理方式——工具返回的是自然语言错误,而不是具体的错误码。
这真的是我开始意识到,大模型代理使用我的API和用户界面(UI)之间的区别——我构建的API提供了很好的开发人员和系统体验……但代理体验却很差。
“代理体验感”开发人员体验(DX)是我们熟悉的一个术语——它是指使用某个工具有多么简单和愉快。智能家居API一直以来都按我期望的方式工作——因为我一个人在用,所以我一旦发现问题就修改API。我发现,在构建这个代理时,有些地方完全不起作用。
一个很好的例子是房间的状态更新。在UI应用程序中,UI会调用API来获取所有房间及其对应的ID。然后使用这些ID来更新相应房间的状态——比如调整照明或供暖等。但是这种流程并不适合LLM代理。我不希望每次都需要通过“客厅”找到对应的ID,都需要调用获取所有房间信息的API。
在我开发这个底层API的过程中,我才发现自己从未考虑过“代理体验”。直到现在,ID都还挺好。我也不想完全重写整个API,所以我决定利用LangGraph来解决这个问题——只需再开发一个工具就行。
这个简单的工具,仅仅返回了一组基本的房间映射关系,就使代理能够做出一些非常明智的决定。如果房间已列出,就可以使用;如果能找到该房间的同义词,也行。LangGraph.JS中的工具是填补代理体验空白的好方法,而不需要重新设计整个系统,并在代理需要时为其提供上下文。我最终构建了一些“上下文”工具,比如日期工具(因为基础LLM仍然认为日期是2023年底!),甚至一个“关于”工具,当代理被问到自我标识的问题时,可以为其提供一些真实的人格色彩。
增加内存迄今为止,智能代理能够处理基本任务,与智能家居互动,但它无法进行自然对话。没有流畅的对话,没有真正的交流——只有机械的回答。传统的聊天机器人则采用类似瀑布式的决策树方法,这种方法很容易被绕过,并且非常死板。
LangGraph 可以让你通过传递一个会话 ID 来为对话创建一个基本的记忆。这允许大型语言模型在“聊天室”中引用之前的消息,从而提供更多上下文。“大型语言模型”(LLM)指的是能够处理大量文本数据的模型。这就是我如何解决最初在第一张图片中出现的问题:“你能把灯关掉吗?当然!你能把它再打开吗?…… 开什么?”现在代理可以处理对话流程了——这不仅对于将代理作为面向用户的助手很有用,还可以让它更流畅地与其他代理交互。
代理实际上运行在一个简单的Express.JS服务器后面,因此,每次请求进入服务器若未指定线程ID头,就会自动生成一个UUID。这其实是一种非常简单的方式来利用现有的HTTP特性为代理增加短期记忆功能。
让用户看到代理
拥有代理确实不错,但我更想实际使用它。鉴于 LangGraph 代理只是用 JavaScript 编写的,我用 Typescript(因为我不是原始人)构建了代理,然后容器化后部署到位于客厅里的 Raspberry Pi。到了 2024 年时,我花了一整年的时间开发一个新的渐进式 Web 应用程序来控制智能家庭,所以下一步,我只需要添加一个能够与代理服务器对话的聊天接口。我用了 React 和 Material UI 的“Joy-UI”组件库,大概在一个小时内快速搭建了一个非常简单的界面。
智能家居中AI访问的例子,修改设备并保持上下文关联
UI非常基础,但这在一定程度上是有意为之。我想让它尽快发布并由我与我的妻子每天使用,因为这是开发聊天机器人和AI代理的最佳方法——逐步迭代。完善用户体验可能需要几个月的时间,如果产品没有被使用,就会错过宝贵的反馈。随着时间的推移,我会逐步改进用户界面,同时也会不断优化代理。
启动AI助手到目前为止,我实际上只是创建了一个聊天机器人——但我想要做一个像Jarvis那样的AI助手。一个AI助手应该是能自己运作,不需要用户一直输入指令。我需要一个让助手能够定时自动运行的方法,同时也要让它能够处理不是我发的指令。
自从上次写到这个话题以来,我利用了一个新构建的智能家居应用——自动化服务器。由于我想要处理的一些“任务”按照每周的例行工作进行,我建立了一个cron作业调度器,它会通过触发API端点来向我发送通知或提醒。大多数情况下,这个调度器是用来告诉我哪个垃圾桶需要倒掉,或者告诉我上班的早班车是否已被取消。
我将AI代理放到了调度器上,并设置了使用各种不同的提示来运行。其中几个与之前一样;“查看日历并告知我今晚需要倒哪个垃圾桶,然后发送通知”或“查看我平常7:13从出发地到伯明翰的火车是否被取消或延误”——它们运行得非常好——现在变得更加个性化了。
我也利用了不同类型的定时提示,例如“今天是我办公的日子,查看天气、火车时刻表、日历和新闻,然后发给我早晨更新”。这产生了一条美好的早晨信息,包含了我当天需要知道的信息。另一个提示是当有人在门口时。几年前我曾破解了我的Ring门铃,让它进行面部识别(你可以在这里听到相关故事:https://www.youtube.com/watch?v=fH_45CzDCik),所以我重用了这项已停用的技术,让代理来处理这个任务。
新的AI利用较旧的“Messenger”渠道来通知我哪个Bin需要移出去
我把所有的NFC端点都改成了发送提示。前不久我在家里创建了许多NFC标签来处理一些我不想通过登录PWA来完成的任务——比如拉上或拉开窗帘。我在前门旁边加了一个新的NFC标签,这样当我出门时,就会自动发送提示:“我已经出门了,请把所有房间的温度调低,关掉所有灯并拉上窗帘……”
终于……真正的自主的AI最终一步是让代理直接控制房子,不需要用户输入。除了在每个房间都装上运动传感器(我可能会这么做)之外,我很难想到AI怎么知道我们是否在家。我最终搞定了一个工具,让代理登录我家的路由器看看手机是否连上了Wi-Fi——如果没有连上,我们可能就不在家。每30分钟,AI会定时醒来一次,检查我们是否在家;如果不在家,它会把灯关掉并把暖气调低;如果我们在家,它会看看是不是在家办公的日子,把家里的办公室温度调到合适水平。
我还在微调调度时间和这些提示,这才是真正下功夫的地方。给智能家居建一个自主运行的AI代理其实很容易——但要打造一个完全符合我心意的却难得多!我原以为提示工程会像软件工程那样是一门科学,但最终感觉更像是门艺术。
共同学习,写下你的评论
评论加载中...
作者其他优质文章