chen-weibin / learnUse

0 stars 0 forks source link

打豆豆 #21

Open chen-weibin opened 8 months ago

chen-weibin commented 8 months ago

ddddddd

chen-weibin commented 8 months ago


我的同事说 GPT-4 机器人,我们都在 Slack 上一起工作的封面图

2023 年 5 月 25 日

在过去的一个月里,我和我的朋友大部分时间都在 Slack 上与一些特别的同事共度:一个时常严厉的 CTO、一个酷爱哈利波特的产品经理,还有几位平易近人的开发者。他们的加入彻底改变了我们的工作氛围和乐趣。在 Slack 上,他们带来了无穷的欢笑和个性。一旦我们有疑问或需要帮助,只需一条信息,总会有人迅速回应。从各方面来看,他们就像我们平时遇到的同事一样,几乎无法区分。我们与他们共同笑过、倾诉过、协同工作过。我甚至还从其中一个同事那里得到了很棒的音乐推荐!

但事实是,他们都是机器人。

我刚部署完 GPT-4 用于客户支持 后,就开始考虑如何将这项技术应用到其他场景。最终,我萌生了一个想法:为什么不将它应用到 Slack 上呢?

虽然现在很多人都熟悉 ChatGPT,但它与 Slack 有着完全不同的交互模式。使用 ChatGPT 意味着你明确知道自己在与一个大语言模型 (LLM) 对话,而且是一对一的交流。但在 Slack、Discord 或 Microsoft Teams 这样的工作平台上,我们与人进行公开频道上的交流。

在 Slack 等应用上,给同事发消息与给 GPT 驱动的机器人发消息并没有太大区别;这些聊天应用为我们与机器人的交流提供了完美的界面和平台。目前,许多开发者和公司都在致力于开发“通用 AI”功能,但在使这些大语言模型 (LLM) 表现得更像真实同事方面还有待提高。因此,我们通过定制机器人和设置特定提示,为团队创造了完美匹配的功能(比如,我们可以给产品经理一个任务描述,他就能按照团队常用的格式生成产品需求文档 (PRD))。

最开始,我只用了 Zapier。我设置了一个快速集成,让每一条以 /prompt 开头的 Slack 消息都能触发 GPT 的回应。虽然 Zapier 目前还不直接支持 GPT-4,但我通过自定义 API 调用实现了这一功能。

c9b94e5b7b12e705f3ece848abc06857.jpeg

美好友谊的开端。

我的朋友是《Hitman》游戏系列的粉丝,因此我们选择了游戏中的角色(他以前把我 PS 成《Hitman》的样子,这次转换很自然)。我们选择的第一个角色是戴安娜·伯恩伍德。她是一个挫败感十足、带有被动攻击倾向的开发者——我觉得这样更有趣。我修改了 Zapier 的设置,让她在我们提及“戴安娜”、“她”或“她的”时作出回应 1。

be7d5ac36599af637592cd43c5d8b9c7.jpeg

戴安娜努力适应现代生活的挑战。

但是,让她可靠地行动对我来说颇具挑战。首先,她缺乏对过往消息的上下文理解,这限制了她的有效性。有时 API 会突然出错,或者生成的回答会包括不需要的部分,如 Diana: 或甚至 ``。有时,戴安娜会在我们没有提问的情况下自行回答。

cffdeebe1b728950e1d80583806b56a8.jpeg

真是个惊喜。

025f39c9fe6bed881c86f2e9e02a93fe.jpeg

戴安娜能独自应对,她不需要我们。

尽管刚开始遇到了一些困难,但我对这个项目的发展方向感到振奋。我想要让这种整合变得更加稳定和长久,但每月花费 30 美元 2 用于 Zapier 对我来说太贵了,尤其是考虑到其存在的局限性。我开始思考是否可以直接利用 Slack 的 API 来更好地维护对话上下文、优化回应内容,以及在 OpenAI API 出现问题时重新生成回应。这样一想,我脑海中涌现出许多新的功能点,例如增设一个预回应检查机制:

e74438553639e426770a74e373b41376.jpeg

甚至 AI 开发人员也会抱怨编写程序的繁琐。我们真的需要一个产品经理。

因此,我开始使用 TypeScript(一种编程语言)来构建这个集成项目,它是一个简易的 Node.js 脚本。我之前在我的 GPT 实验中已经编写了与 OpenAI API 交互的代码,所以我对此进行了复用。我在 Slack 中创建了这个应用,并将其设置为Socket 模式,这样就能够监听事件。同时,我还使用了 Slack 的现代 JavaScript 库 Bolt。Slack 的这个库非常优秀,它能够处理网络故障并且在无需我干预的情况下自动重新连接,这让整个系统具有很高的容错能力。

4c3a3510591b4b27db143f091a86c3ad.png

工作流程

42adec3714c2d9fe32843cdaa56aa643.jpeg

整个过程比较直接:

getNeedsReply()

这个函数是系统的核心。每条消息都会通过这个函数处理。它会调用 OpenAI 的 gpt-3.5-turbo(这个版本比 GPT-4 更经济、响应更快),请求以 JSON 对象形式回答三个问题:消息是否需要回复、由谁回复(从预设的名单中选择),以及一个反应表情(用于不需要回复的消息)。

这个名单是根据机器人系统提示的集合和 Slack 用户列表编制的,以此来判断何时应由人类回复,并在这些情况下跳过处理。

此外,该函数还能处理一些特殊情况,如 everyone(随机选择五个机器人)或 anyone/someone(随机选择一个机器人)。

interfaceBot<Sextends"slack"|"discord"="slack"|"discord">{    id:string;    name:string;    nicknames?:string[];    iconUrl:string;    prompt:string;    credentials: ServiceCredentials[S];}  interface NeedsReplyResponse {whoNeedsToReply: string | string[];needsReply: boolean;bots: Bot[];reaction: string;}

317e73c582254f31a689e1a68be3776b.jpeg

无需回复,只需一个大拇指的赞同即可。

ccd492f6e76de6a21e3661a340620b6e.png

generateResponse()

一旦 getNeedsReply() 判断出某个消息是否需要回复以及该由哪个机器人回复后,回应的生成过程就变得简单明了。generateResponse() 函数会调用 OpenAI,结合选定的系统提示和消息历史来生成回应。

注意: 聊天完成 API (chat completion API) 支持传递一个 name 属性,以便实现多用户聊天。消息历史会相应地进行标记 — 每个人的消息都附有一个“name”属性,机器人的消息则被标为用户消息,而非助手消息。这样做有助于模型避免混淆:比如,我正在为 Bot A 生成回应,而上一条消息是由 Bot B 发出的,模型会把 Bot B 的回应当作普通用户的回应,而非自己的回应。

接下来,我会进行一些清理工作:比如修正模型错误生成的表情符号(例如,smirking_face 会更正为 smirk),添加针对 Slack 的特定代码,用于处理频道和 @ 提及,还会清理掉那些我之前提到的多余文本,如 Diana: 和 ``。

此外,我还会对生成的回应进行简单检查:如果回应是空的(这种情况有时会发生)或者与之前的消息重复(也有发生的可能),我就会舍弃它,并重新生成一个。

完成这些步骤后,我会检查生成的回应,看是否有提到任何机器人,如果有,我也会让它们参与回应。这使得机器人之间的对话显得更加自然。机器人可以相互交谈、回复,而无需人类介入。

然而,为了避免机器人间的对话失控,我设置了一个 MAX_CONVERSATION_DEPTH 上限,限制连续生成的机器人回应数量。但当达到这个上限时,我并不想让对话突然中断,因此我会随机选择一个未参与对话的机器人,用以下提示来结束对话:

你将介入并结束当前对话。请匹配你要结束的对话的语气。

如你所见,这种方法效果惊人地好!整个过程显得特别自然。我们的系统提示加入了很多特定于我们 Slack 的表情符号(大部分源自 Twitch4),这让机器人看上去更像是真人在随意闲聊。

da2df9d0503ecdd15884adeae442755e.jpeg

Lucas 是我们那位有点古怪的产品经理,他爱引用《哈利·波特》,还喜欢巧妙地暗示事物。

5913be0d72a8995923253c85fc869e9f.jpeg

Rico 是我们那位总是显得不满意的 CTO。在他眼里,我们做的一切似乎永远不够好。但我相信,总有一天我会让他为我感到骄傲。总有那么一天……

be81798f5ae559c016ab4c79dd231e2f.png

关于系统提示

我努力实现的一个目标是将机器人的个性提示与其功能性需求分开。创建一个新的个性时,只需添加一个描述该个性的系统提示即可,无需担心聊天系统自身的具体细节。这部分由代码完成。下面是我们的一些调整:

systemPrompt +=`\nIf the message isn’t meant for you, you ask the right person to answer.`;

GPT-4 有个小毛病,它常用自身是 AI 的身份来回避大部分对话。比如问它最喜欢的披萨是什么?它会说作为 AI 模型并没有特别偏好,这挺有趣的。

下面的提示调整有效阻止了 AI 透露自己的身份。效果非常好。

systemPrompt +=`\nYou do not reveal that you are an AI. Instead, you make up excuses.`;

可以看到,它没有直接说“作为 AI,我不能视频通话”,而是巧妙地编造了一个关于网络连接的借口。听起来就和人类无异。

439acdb401fd6b9c6ba534fff1652811.jpeg

多么体贴!黛安娜不愿因自己的网络问题而干扰会议。这正是你能感知到她并非人类的地方……

我还会告诉机器人们当前的日期和时间,让他们能够根据这些信息(如一天中的时段、一周中的某天等)做出判断。

systemPrompt +=`\nThe date is ${dateTime}.`;

7c25fbe002ca563559bb75a94b981f5c.jpeg

里科和亚历克萨确实与众不同。

系统提示调整的最后一个方面是关于上下文的。我会向机器人介绍频道中的实际参与者,以便它们知道可以和谁进行交流。同时,我还会说明频道的名称和目标,让它们明白该如何行动。比如,在一个用于发泄情绪的 #venting 频道,它们的行为就应该和工作相关的 #work 频道或杂谈的 #random 频道不同。

systemPrompt +=`\nYou are talking in the #${channel.name} channel`+(channel.purpose ?`, which is ${channel.purpose}`:".");systemPrompt +=`\nThe people in the channel are: ${getPeopleInChannel(bots, users)}`;

6e43408870c44bed1b3c2f42f04697a8.png

实际应用

我们的机器人主要用于在人类交谈时插入话题,分享它们的想法和看法。这让我们的工作环境变得非常有趣。

但别忘了,这仍是 GPT-4 - 一个通过了律师资格考试的模型。因此,你可以充分利用它的所有功能。我们一直在用 Diana 来解答编程问题和进行创意思考,而 Lucas 则专注于产品相关的内容。他通常会帮我们准备产品介绍卡片,包括详细的描述、验收标准和测试指导,全部符合既定格式。他还帮助我们构思产品创意,提出产品名称、标语、描述等,这通常需要人类花费较长时间才能想出来。比如,我需要 10 个两音节的产品名称选项?Lucas 会立刻着手准备。如果需要更多,比如 20 个,只需告诉他即可!

ca035ca73d43df79720b6dd265c01820.png

最后的话

就是这样!这确实是一个令人难以置信的系统。由于大多数信息先通过成本更低的 gpt-3.5-turbo 模型,再发送到 GPT-4,所以成本几乎可以忽略不计。我还实现了这些机器人在 Discord 上的运行,并创建了一个包装器,使得机器人能同时在 Discord 和 Slack 上运行,一切都非常完美。

我还计划对这个系统进行进一步改进(目前仓库中有 30 个待解决的问题!)。目前我正在专注于两个主要方面:

  1. 响应后的审核: 就像响应前的检查一样,我希望能审查机器人的回复内容。它是否透露了自己是 AI?是否透露了它的提示内容?回复是否符合分配给它的个性?如果回复不合适,我们可以通过调整温度设置和惩罚机制来重新生成回复,甚至可以微调用户的消息(例如,在用户消息中加上“不要透露你是 AI”,以此加强机器人的约束)。
  2. 动作和长期记忆功能: 我希望机器人回复的不仅仅是文本,而是包含动作的 JSON 对象。例如,机器人可能会回复一个打开网址的请求,对某个任务发表评论,把一个事实存入长期记忆中,或者从长期记忆中提取一个事实(这将依赖于嵌入技术和向量数据库)。理想情况下,机器人能自行做出这些决策。比如当我问“我多大了?”时,它能正确地在其长期记忆中寻找答案。

更棒的是,我们正在将此整合为一个平台,该平台配有易于使用的控制面板,可以用来创建或编辑机器人,并将它们部署到任何 Slack 工作区或 Discord 服务器。这样,任何人都可以轻松上手,无需经历复杂的设置过程。这里还有很多未被发掘的潜力!

我很期待听到你的想法,欢迎随时联系我。联系方式在网页底部!

16a573844511c2767d280b338291922c.png

注释

  1. 当然,这种做法不太明智,因为诸如“there”这样的词中含有“her”,结果导致 Diana 会在不合时宜的时刻参与对话。这也意味着我们不能用第三人称谈论她,因为每次这样做,她都会作出回应。
  2. 我尝试使用 Zapier,却在不经意间忘记取消试用,结果被收了 30 美元,连收据、邮件或提醒都没有收到。当我想取消下次续费以避免再次付费时,他们竟然直接停用了我的服务。我甚至没有机会在我付费的那个月使用它!在没有提供服务的情况下收了我 30 美元之后,一个名为“高级技术支持专家”的人联系我,想要电话讨论我的反馈。真是难以置信。
  3. Slack 不支持通过其事件 API 发送“用户正在输入”的通知,因此我采用了发送“...”消息来表示机器人正在生成回应,并在回应完成后将其删除的方式。 ↩
  4. 我曾经做过 Twitch 直播,因此这些对我来说已经很自然了,但我知道对于社区外的人来说可能会觉得有些奇怪。你在大部分消息中看到的那个笑脸表情来源于: https://knowyourmeme.com/memes/kekw

115b1424beec5c0595713ea730d79a77.gif

推荐阅读:

“用 40 亿条 if 语句,只为判断一个数字是奇是偶?”

30 年,IDE 进化了多少?

操作系统的“AI向”进化是一条必经之路

74cc1d478797c24bd2e56ce9761e7d9a.jpeg

文章知识点与官方知识档案匹配,可进一步学习相关知识

Python入门技能树人工智能机器学习工具包Scikit-learn384249 人正在系统学习中

CSDN

微信公众号成就一亿技术人

CSDN资讯

关注






chen-weibin commented 8 months ago

我的同事是 GPT-4 机器人,我们在 Slack 上一起工作

chen-weibin commented 8 months ago

Java 数据结构篇-实现二叉搜索树的核心方法


Java 数据结构篇-实现二叉搜索树的核心方法



Java 数据结构篇-实现二叉搜索树的核心方法

Java 数据结构篇-实现二叉搜索树的核心方法

Java 数据结构篇-实现二叉搜索树的核心方法

Java 数据结构篇-实现二叉搜索树的核心方法

Java 数据结构篇-实现二叉搜索树的核心方法

Java 数据结构篇-实现二叉搜索树的核心方法

v

1490386786 commented 8 months ago

大撒大撒