标签: openai

  • 分享自制小工具:Automate GPT – 在 ChatGPT 里批量执行任务

    分享自制小工具:Automate GPT – 在 ChatGPT 里批量执行任务

    其实这个小工具是我很早以前开发的,最近因为有需求,又翻出来修了修,觉得蛮有用的,分享给大家。Automate GPT 是一个浏览器扩展,可以方便我们更好的使用 ChatGPT。

    OpenAI 最近几次发布的新功能还是很强力的,比如近期大热的各种风格化绘图,什么吉卜力啊、卡通3D啊、玩具啊,等等。相信大家都在各种平台上看过,我也试做了一些:

    (更多…)
  • 尝试用 DALL-E 3 制作漫画《姆伊姆伊》

    尝试用 DALL-E 3 制作漫画《姆伊姆伊》

    DALL-E 3 发布有一阵子了,今天跟一个朋友聊到 AI 制作漫画,我突然想起来,还没测试过 DALL-E 3 的漫画制作能力,所以简单试了试。我认为它的表现不错,做绘本类的产品应该问题不大。下面是我的作品。

    Once upon a time, there is a dog, his name is Muimui

    (这是我早年帮孩子写的英文演讲的作文。)

    Once upon a time, there is a dog, his name is Muimui. Muimui is a corgi.

    Muimui is a good dog, everything is fine except that he like barking very much.

    When I cleaning the room, he barks.

    When my mom and dad talk to me loudly, he barks.

    One day, I was eating hot dog bread, I like hot dog bread.

    Suddenly, my mom said to me: “Do you finish your homework?”, when I turn my head to her, I fall the hot dog bread down to the ground!

    (这张图我尝试了很多次,都没法把说话气泡指向妈妈。)

    I was shocked, and my hot dog bread fell to the floor.

    Muimui run fast to the hot dog bread immediately, grabbed the bread and happily ate it.

    This time, he didn’t bark at all!

    简评 DALL-E

    DALL-E 作为 OpenAI 的产品,它最大的优势就是可以很好的理解我们的 Prompt,不需要我们事先学习模型训练时的标记,大大降低了普通用户使用 text2img 功能的难度。Prompt 会试图把我们的 Prompt 扩写得更全面,比如第一幅图,实际生效的 Prompt 是:

    Watercolor painting of Muimui the corgi looking out of a large window in a comfortable home, with curtains gently swaying.

    如果我们要调整图片,可以继续跟 DALL-E 对话,它会自动帮我们整合 Prompt,然后输出新的图片。我们可以要求它基于某个图片进行修改,以便产出我们想要的效果。

    如果你仔细观察,会发现上面几张图片里,有几张里面的角色存在明显的特征,比如坐在沙发上的那个小男孩,戴眼镜穿衬衣,卡其色的裤子都很接近,我不知道它是怎么做到的,不过如果能维持这个稳定性,可能真的可以用来画漫画。

    我并没有尝试对角色稳定性做出约束,比如什么样的发型、什么样的衣服等,不知道会不会对输出的结果产生影响。

    不过 DALL-E 也有劣势:我们不能自己训练小模型(Lora),所以大家的产出可能会千篇一律。另外 DALL-E 有很多“安全性”预设 Prompt,我们不能随意要求它画出一些 NSFW 的作品。

    总结

    不知道读者觉得这个作品如何?欢迎留言讨论。

  • Prompt Engineering 经验分享

    Prompt Engineering 经验分享

    我这大半年来都在围绕 ChatGPT API 做事,积累了一些 Prompt 相关的经验,大部分跟编程有关。即拿到结果后,我们不直接输出,而是使用代码处理这些结果,然后再输出。Functional Calling 对编程当然有用,不过有时候,配合文中的一些方法,可以得到更好用的结果。

    ChatGPT 的基本原理

    ChatGPT 是一个生成式大语言模型,它由海量的数据训练而来。所以当我们输入一些内容作为启动数据之后,它就会计算出来最可能最合理的新内容。比如,输入“白日依山尽”,那么最合理的接续多半是“黄河入海流”。当然,由于 ChatGPT 已经针对“聊天”这个场景做过优化,所以,他可能会多说一些过渡性的内容。

    通常来说,我们发给 ChatGPT 的内容不会这么好预期,所以它会产出的结果也存在很大变数。这对我们来说有好处也有坏处。好处是,多变的结果,会让我们有更多期待,也更有机会拿到想要的结果;坏处是,结果质量可能忽高忽低,格式也飘忽不定,难以在程序里使用。

    Prompt 入门

    要写出好的、有效的 Prompt,第一步应该去认真阅读 OpenAI 官方的 GPT最佳实践(GPT best practices)。这里我简单总结一下:

    请求里包含必要的信息

    比如我家孩子想让 GPT 帮他写作文,如果只说:“帮我写一篇作文”,效果就不好。因为作文有很多可能,不同的阶段、不同的文体、不同的主题,写出来的作文可能完全不同。

    这时候就要耐心跟 GPT 讲清楚:“我是一名小学五年级的学生,请帮我写一篇作文,大约 300 字,记录我们家过中秋节的故事,我们吃了月饼,看了晚会;我们本来想出去旅游,但是爸爸妈妈猜到处都是人,就没有出去。”

    让 GPT 扮演一个角色

    GPT 已把成千上万的角色融于一身。还是上面的例子,我家孩子如果只让 GPT 帮他写作文,能写,但是未必敢交给老师。所以此时就要让 GPT 扮演同样的小学五年级的学生来写作文。

    给 GPT 提供周边信息的时候,要把边界标清楚

    没有格式的文字,无论是人还是机器都无法理解。所以我们可以使用各种 XML 标记,或者三连引号,让 GPT 知道哪些是我们的请求、哪些是我们给它的参考资料。

    提前帮 GPT 分解任务

    GPT 目前的逻辑能力有限,如果我们有更靠谱的解法,直接教给它会更有效率。

    提供例子让 GPT 参考

    这个策略在二次开发领域会大量使用,我觉得比 functional calling 更常用。

    指定输出内容的长度

    我们知道,语言都存在信息密度,想把一件事情说清楚,可能需要很多文字;而过多的文字,也可能存在一些“废话”。所以限制输出长度往往也可以行之有效地改进结果。

    不过实际上,内容长度会跟很多因素有关,往往不能简单一限了之;如果篇幅限制,实在说不清楚,GPT 也可能会忽略我们的某个要求,大量文字一吐为快。

    我的经验

    对编程来说,稳定性非常重要,因为我们的代码无法适配各种各样千奇百怪的输出。这些输出在 ChatGPT 的聊天界面里,面向使用自然语言的普通人,其表达能力没有问题,但是对我们的程序来说,一些微微的差异也可能破坏代码功能。

    总则:把 GPT 当成态度超好但能力一般的实习生

    GPT 拥有海量的知识,但是缺少足够的逻辑思维能力去组织、架构这些知识。于是我们不能指望 GPT 能够很好的利用这些知识帮我们做事情。更多的时候,我们要先想清楚怎么做,拆解出来步骤,再把任务逐一分配给 GPT,让它尽量简单地做执行工作。

    但是 GPT 态度绝对好,绝对耐心,它可以不厌其烦的反复尝试我们交代的工作,毫无怨言。真是一个能力平平的社畜……

    如果你不知道下一步该怎么做,不妨把 ChatGPT 当成一位无法独立处理工作的实习生,尝试带领它工作,而不是期待他能解决你都不知道该怎么解决的问题。

    减少歧义,尤其是隐含的歧义

    有时候,我们的表达会有一些隐含的歧义。比如,我们去吃饭,想点一份不辣的鱼香肉丝或者回锅肉,这里面就包含歧义——按照川菜里的标准定义,鱼香肉丝和回锅肉都有辣。如果是在不常吃辣的地方,厨师可能可以试一试;如果实在巴蜀本地,那多半厨师要谢绝接待了。

    我们向 ChatGPT 提要求的时候也要注意。举个例子,我厂的产品会要求 ChatGPT 帮忙写一封信,这封信需要遵循一定格式,我们才好解析它并重新格式化。但是我们发现,GPT 在写开头(intro)的时候,经常会只写:Dear Meathill,即问候语(greetings),然后漏掉我们希望有的第一段。反复换模型也没有效果。后来我把要求改成

    intro: greetings, then one paragraph of introduction about 50 words,终于解决了问题。

    因为对于 GPT 来说,一句 greeting 也可以是 intro,只要求写 intro,它搞不清我们的目的,输出就远不如后面准确。

    使用 YAML 传递格式化数据

    JSON 格式要求很严格,很容易出错,而且在得到完整结果前,也很难解析。所以我建议大家如果需要格式化数据,不要用 JSON,用 YAML。YAML 格式更简单,不容易出错;而且 YAML 在流式传播的时候,不耽误我们实时解析并且输出,效果更好。

    比如这样:

    Please, as a Christian minister, help me choose a thought-provoking verse from the Bible, tell me why you chose it, and then write a prayer for me. Please write to me in the following YAML formats. No other content.

    “`yaml
    verse: the verse content
    reference: the verse you select for me
    thought: teach me about this verse, about 80 words
    prayer: use it to lead me to prayer, about 80 words
    “`

    控制 Prompt 的长度

    正如前面所说:

    1. ChatGPT 的推理能力并没有传说中那么强;
    2. 自然语言里难免会存在前后矛盾之处

    所以过长的 prompt 很容易导致得到不稳定、不可靠的结果。网上能找到各种洋洋洒洒一大篇的超长 Prompt,实际上以我的经验,这些 Prompt 要么实际效果一般,要么有许多限制条件并不必要。尤其是那些限制 ChatGPT 应该说这个不应该说那个的,多半因为前后矛盾实际上并未生效。

    我建议大家保证遵守上面最佳实践的六点之后,尽量用简短无歧义的语言提出要求,得到的结果会更加可靠。

    (案例待补充)

    Embedding + Searching 中文一般,英文略好

    经我们测试,中文 Embedding 的结果差强人意,检索匹配度很差,感觉跟传统关键词搜索的效果差不多,自然语言与原文表达相似的意思,但是词汇完全不同的时候,经常搜不出结果。

    英文略好一些,不过也好不到哪儿去,事实搜索强于表意搜索,做知识库知识管理的话,问题不大;期待做回复系统的话,我认为并不可行。实际上,我体验那些所谓名人聊天工具时,感觉也是如此。

    比如,类似 trickle.com 这样的知识管理工具,存进去一些统计数据,如股票价格、销量等,然后基于自然语言进行检索:“苹果股价最高时是多少?”一般来说没有问题。但是如果写日记,然后搜索:“我那天特别开心,是怎么了来着?”,就基本没有结果。

    解决方案当然也是有的,在 Embedding 存入数据库时,预设一些搜索场景,然后让 ChatGPT 帮助生成搜索辅助内容,最后一起 Embedding 存入数据库,这样搜索的时候就有更大概率能找到。比如:

    这是我的日记,请分析我日记中所表述的心情、印象、态度,概括为 10~20 个形容词。请只用 TypeScript `string[]` 的格式输出。No more other content.

    “””长假期间天气好热,想出去玩,但想到这么热人又多就懒得走了……”””。

    总结

    ChatGPT 非常强,但要让他发挥全部战力,我们开发者的努力也不可或缺。以上是我这几个月来学习总结得到的经验,希望对大家有用。也期待看到更多开发者从编程角度,分享二次开发的经验。

  • 我的 AI 学习一周/月总结:四月三场 Hackathon

    我的 AI 学习一周/月总结:四月三场 Hackathon

    这篇文章在我草稿箱里躺了一个月,因为种种原因,内容不够充足,就一直没发。周末想了想,还是补一些内容把它发出来。经过连续几个月的高强度信息获取、吸收,我觉得现在已经进展到必须躬行实践的阶段。未来类似这种信息汇编、浅尝辄止的博客会减少,还是回到案例分析、实践分享的老路上吧。

    最近几周,我一直在努力 release 产品,先死磕计费系统、然后跟 Chrome Extension 在各个网站里搏斗,基本上眼睛一睁一闭,一天就过去了;与此同时,之前报名参加 Hackathon 开始进入正赛阶段,最近三周一周一场,时间非常紧张,周更文章根本来不及……

    不过笔记该写还得写,近期也学到一些东西,记一记。

    我不看好 AutoGPT

    近期最火的产品应该是 AutoGPT。顾名思义,AutoGPT 就是在 ChatGPT 的基础上,让 AI 自己决策、自己尝试、自己评估。这样,我们只需要告诉 AI 我们的需求,然后等待,就能拿到自己需要的东西。

    理想状态,尤其是电影里,这样当然是可行的,然后天网就来了……但是我认为,现阶段这种尝试就是纯烧钱,效果跟猴子打字机差不多。我甚至怀疑这个产品是 OpenAI 自己放出来做压力测试的。

    ChatGPT 的确从人类生产的文本知识里获得到了很多经验,以至于可以回答比如“我想做一个XXX,我应该怎么做”这样的问题。我们普通人多半也是这么开始工作的:先找出一些方案,然后尝试这些方案;遇到问题就再想方案,再解决;重复若干次,直至达成主要目的。似乎用 ChatGPt 也能做到这一点。

    但是我们的决策大量依赖经验、和人类与生俱来的直觉(生物进化 37 亿年得到)。很多时候,经验丰富的老手和新人之间的区别,就是判断哪些方向可以尝试、哪些方向应该优先尝试。所以我们可以把 ChatGPT 当成一名新晋毕业生,刚刚学了一堆知识,但是实操经验几乎为零,然后你告诉他:按照你的想法随便搞,预算不限。结果可能好么?

    我看好在 ChatGPT 等 LLM 加持下,胶水层、DSL、专家系统能够达到新高度,但我不看好 AutoGPT 这样的无头苍蝇。

    OpenAI 发布 Embedding 指南

    openai-cookbook/Question_answering_using_embeddings.ipynb at main · openai/openai-cookbook · GitHub

    昨天 OpenAI 发布了 Embedding 指南,其中一个要点:为什么(Embedding)搜索要好于微调(fine-tuning)?

    文中有个比喻:模型权重就像长期记忆,微调模型就像是为了 闭卷 考试而学习,到了考试的时候,记忆还是会混乱,还是会做错题。搜索就像是开卷考试,通过携带信息(现场翻书),答案会更准确,通常得分也更高。

    显然,使用 Embedding 搜索时,发送的内容会更多,能用到的上下文就会更受限,而且价格会更高。所以最终怎么选择,需要我们自己权衡。

    这篇文章还提到了 Embedding 不适用的场合,以及如何 debug+调优,非常值得一看,推荐给大家。

    四月份参加三场 AIGC Hackathon

    四月连续参加三场 Hackathon,连续三周都在各种赶工,累得够呛,也是本系列文章搁置的原因。我在 复盘文章 里比较详细的记录了参赛过程和作品设计开发,感兴趣的同学可以去看看。简单来说,我们努力开发了一款 web app,叫做 拜拜,可以让用户在任何场合都能求神拜佛,并得到一些心灵的慰藉。

    目前我们已经让神佛可以用语音的方式跟信众交流,结合回声效果,实测效果不错,欢迎大家试用、反馈。

    下一步我们会添加用户体系,并先在大陆地区以外上线。大陆地区以内当然也不会放弃,不过要确保我们合法合规,肯定会慢很多。所以,一步一步来吧,顺利的话,我们希望今年能够提交到各种市场、平台上线;不顺利的话,把主要流程做出来跑通,找个公司卖掉也好。

    一些碎碎念

    我这两天再看 Supabase 的文档,发现它们在 Supabase AI 搜索的下面增加了这样一个补充说明:

    Supabase AI is experimental and may produce incorrect answers.

    Always verify the output before executing.

    看起来,利用 ChatGPT 提升文档可用性并非一帆风顺,乱编答案的问题可能会长期困扰我们。期待大家进一步的最佳实践。

    目前更大上下文规模的模型也不断放出,比如前两天公布的 Claude,支持 100K 上下文,大家可以试一试。

    AI 倦怠期

    ChatGPT 去年引爆行业,今年过完春节破圈,接下来整个 234 月,大家都沉迷于各种 AI 新技术无法自拔。终于,过完五一之后,舆论环境终于开始降温,我相信各位读者老爷跟我的感觉应该差不多吧。

    其实也很正常,密集的投入开发之后,目前 AI 技术能干什么、不能干什么、什么能干好、花多少钱能干好之类的边界,虽然不能说非常清晰吧,但是大概在哪里,大家应该都知道了。割韭菜的那些我们不聊,只说付出辛勤劳动就能有所收获的部分,其实也不太多,或者成本不低。

    所以最近新东西不太多,更多的则是降本增效,比如用小模型换取接近的效果,比如用开源产品替代闭源产品等等。我相信,这是技术发展的必然,也是新一波创新前的宁静,后面会更好。


    总结

    地球生物的身体是自然界进化了 37 亿年得到的,我们可以非常高效地使用资源,比如一个馒头,就够我们活蹦乱跳几个小时。但是当需求上升到一定阶段后,效率就要让位给绝对值,比如硬拉世界纪录,也只有区区 500+kg,但是大型机械随便就是几十吨。

    AI 其实复刻了这条道路。它在思想深度广度上,都不如人类;但是凭借现在的算力冗余,大力出奇迹,从另一个角度超越了人类。将来怎么走,不好说,希望我们能像使用机械一样,使用 AI。

    就目前的状况来看,AI 基础设施现在已经非常好了,应用层存在大量机会。我维持之前的判断不变,建议大家有机会多多接触,早日加入。

  • 使用 Vercel、Supabase、Stripe 打造 OpenAI 计费系统:1. 系统篇

    使用 Vercel、Supabase、Stripe 打造 OpenAI 计费系统:1. 系统篇

    过去两周,我基本都在跟这套付费/计费系统死磕,相对来说投入到 AI 学习里的时间不多,以至于 我的 AI 学习周记 系列本周停更。如今终于基本搞定这套系统,基本概念、开发调试都不存在难以逾越的问题,所以打算写几篇博客总结一下,给后来者分享我收获的知识、踩到的坑。也让自己需要的时候可以翻查笔记。

    OpenAI 计费系统现状

    目前我们讨论的 OpenAI 计费,基本是针对 ChatGPT 对应的 gpt-3.5-turbo 和 gpt-4 这两个模型,在 API 调用方面的费用。官方规定,gpt-3.5-turbo 是 $0.002/1000 tokens,gpt-4 根据容量不同,最多要贵 30 倍,所以提供服务时,我们基本还是以 3.5 为主。如果用户愿意多付钱,我们也可以提供 gpt-4(已经拥有权限)。

    不使用 stream: true 的时候,OpenAI 会返回使用的 token 数量,这个时候,数据准确可靠。但是为用户体验考虑,也为云服务考虑,使用 stream: true 模式明显更好。但是在这种模式下,OpenAI 不返回使用的 token 数量。(我猜测这跟 Transformer 模型的工作原理有关。)所以我们就需要手动统计 token 的消耗。

    这个时候得到的结果可能并不准确,但是没办法,我们只能这么做。

    我们开始也不知道 OpenAI 怎么统计 token 数,好在官方提供了计算页面:https://platform.openai.com/tokenizer 和推荐方案(看起来是传说中的 GPT 地牢作者的作品),可以帮我们完成计算。至于详情,将来会具体介绍。

    基于 Edge Function 的计费系统设计

    首先,我们要选择服务器架构。

    传统方案是配置一台云服务器,然后前面架一个 CDN。但由于我们是一个面向全球的服务,这样的架构不甚理想。而且基于 stream: true 的方案需要长时间维持网络连接,单机容量也不够。全球部署的话,成本太高,初创团队不现实。

    所以很自然的,我们准备使用 Edge Function。Edge Function 的优势在于:

    1. 它借助云服务厂商的边缘节点提供服务,节点分布广泛,可以就近服务用户,大大改进响应时间。
    2. Edge Function 在用户请求的时候才工作,平时休眠。这种按需付费成本更低。
    3. 相比于传统的 Serverless Function,Edge Function 一般都会修改运行时,用减少负载的方式提升启动速度,以几乎 0 延迟的方式启动,用户体验很好。

    以上几点我均已在之前的试做项目中在 Vercel 平台上体验过,所以这次没怎么纠结,直接选择 Vercel Edge Function 开发。

    也欢迎大家阅读我前一篇分享文:使用 Vercel Edge Function 访问 OpenAI API 的注意事项

    数据库选择:Supabase

    确定使用 Edge Function 之后,下一步要选择数据库。传统的、基于数据库协议的方式不可行,必须支持 http 请求,必须支持连接池,可选方案不太多。刚好前阵子我为了抽键盘,了解到有一家叫 Supabase 的新 serverless 服务商,可以很好满足我们的需求。

    首先,他们能满足 Vercel Edge Function 的需要,也是官方推荐的厂家之一。

    其次,他们的服务基于 PosgreSQL,具备丰富的插件生态,可以实现各种功能,包括未来给 ChatGPT 提供内容拓展的 pg_vector,可以不用担心将来需求延伸。

    再次,作为一家 serverless 服务商,他们家的免费额度看起来还不错,应该可以满足我们早期验证产品的目标(薅羊毛就是爽)。而且,自带 RLS(行级安全策略)也会给未来的开发带来很多方便,比如我们可以放心的把用户身份有关的读取操作放在客户端,不用单独开发接口,节省很多人力。

    最后,我们决定选用 Supabase,作为数据库服务供应商。

    其实 Supabase 也提供 Edge Function,效果理论上并不比 Vercel 差,但它是基于 Deno 的封装,生态和环境都跟 Node.js 不太一样。考虑到学习成本,以及分散投入有利于多嫖资源,所以我暂时不打算用,还是先集中在他们家的数据库上。

    收费选择:Stripe

    作为超迷你初创团队,主攻海外英文市场,我们的策略自然是一切从简,那么付费方案很自然就选择了 Stripe。Stripe 的功能全,文档强大,很适合我们这种小团队使用:

    1. 接受多种收费方式,各种信用卡不一而足,尽可能满足用户
    2. 提供订阅式购买
    3. 支持优惠码等促销手段
    4. 提供 SaaS 服务,方便管理用户
    5. 可以用 Payment link 创建付费页面,省去几乎所有购买流程的开发成本
    6. 提供 webhook,对接我们的账户体系
    7. 提供大量 API,如果有需要,将来我们可以逐步迁移到自己的平台

    最终选择

    基本上,我们最终形成了这样一套方案:

    1. Vercel Edge Function 提供 OpenAI API 的封装,我们借由它完成用户请求、额度拦截、计费等功能
    2. Supabase 提供存储,我们借由它存储用户的账户状态、付费记录、消费记录等功能
    3. Stripe 提供购买功能,我们用它的 Payment link 让用户完成购买付费

    这些产品都支持 TS/JS 为主的语言,提供基于 npm 的 SDK,开发环境很大众,开发体验不错。未来属于 JS。

    这套架构在初期没什么成本,可以覆盖几乎全球的用户,提供不俗的性能。将来用户量增长,需要扩容的时候,也不需要我们再手动开发扩容功能,只要根据用户量、使用量付费给云服务商就好。如果将来我们要提供 embedding,嵌入用户自己的数据,也可以很容易的在现有框架下实现扩展。

    乐观估计,未来半年到一年内,我们都可以在这个体系下开发。


    小结

    我感觉全世界就我一个人在做计费系统,其他人:

    1. 要么是不知道是弄了很多免费账号还是自己负担费用先抢用户,反正是敞开给用户免费用
    2. 要么是收一大笔钱割韭菜,反正收的钱多,普通用户随便用也用不完

    总之都不在意区分用户,也不在意回本。于是几乎看不到有人讨论如何做自己的付费系统。

    我们认为成熟的商品,还是要在成本、收益、风险上形成稳定、友好的比例,计费系统早晚都得做,不如先做好。

    如果你对 OpenAI 计费系统,对我们这套基于公共云平台的 Edge Function 方案感兴趣或者有问题,欢迎留言讨论。

  • 我的 AI 学习一周总结:ChatGPT 开放插件系统

    我的 AI 学习一周总结:ChatGPT 开放插件系统

    本周主攻产品的注册、付费、计费系统,遇到不少问题,投入到 AI 学习的时间不太多,本来以为攒不够内容,没想到临近周末 OpenAI 又放了个大招,所以赶紧表达下我的观点,把这周总结发了。

    好好学习,天天向上。卷到最后,就是胜利。

    OpenAI 发布 ChatGPT 插件系统

    今天早上醒来,到处是 ChatGPT 插件系统的新闻,官方新闻在这里:

    We’ve implemented initial support for plugins in ChatGPT. Plugins are tools designed specifically for language models with safety as a core principle, and help ChatGPT access up-to-date information, run computations, or use third-party services.

    ChatGPT plugins (openai.com)

    除了一般的能力整合,更吸引我们注意的是,这次 OpenAI 还公开了一些带来更多可能性的功能(通过官方插件,不知道会不会开放给第三方)。

    网络浏览能力 Browsing

    类似 New Bing,这个功能让 ChatGPT 可以从互联网上获取资讯,然后结合强大的文本理解和推理能力,一方面对接用户的自然语言询问,另一方面代替用户从茫茫文海中查找合适的内容。

    这个能力十分让人期待,不过也让我隐隐有些担心:大家都依赖 ChatGPT 快速获得答案之后,互联网信息污染会不会越来越容易,也越来越容易造成破坏了?

    另外一个问题。ChatGPT 能否像搜索引擎那样广开善源,即从大量信息源总结出结果,而不是只有几个少数的信息源,比如 CNN?如果信息来源很多,它能不能正确的总结和分辨?又能不能在合适的时间内给出结果呢?有待观察。

    网络沙箱执行能力 Code interpreter

    GPT 的模型本身就能很好的理解和生成代码,但由于它并不是真的理解语法规范,所以生成的代码能不能执行比较看运气。如今,通过 Code interpreter,它可以在页面沙箱里执行的 python 代码,于是至少有三个方面的改善:

    1. 解决数学问题。以前逢数学题必错,将来不会了。
    2. 直接进行数据分析和可视化
    3. 文件类型转换

    信息提取 Retrieval

    ChatGPT Retrieval 插件可以访问个人和组织专属信息源,根据用户自己的数据生成更精准的回答。这个产品是开源的,可以部署在用户自己的环境里,相当炸裂,这下 LangChain 和 LlamaIndex 岌岌可危,我之前想搞的 Second Me 也可以换个方向了。

    但是,这也印证了开发者的担忧:大厂偷家怎么办?本来核心技术就在大厂,我们辛辛苦苦帮他们把产品方案趟出来,裤衩一声,大厂发布了自己的版本,我们呢?

    我对 ChatGPT 插件系统的想法

    插件系统会把用户留在 ChatGPT,大大威胁 Google 和其它传统入口

    之前 ChatGPT 最大的问题就是数据太旧,很多知识它都不知道,还特别喜欢编造结果,使得我们不能依赖它做决策。如今它可以从互联网上获得资讯,理论上可靠性大大提升;而且它的界面是自然语言,非常友好。未来可能会有越来越多的人依赖 https://chat.openai.com/chat 获取信息、做决策;也会有越来越多的语音助手接入他们的服务。于是用 Google、百度、Bing 获取信息的人就会减少,使用 hao123 这种目录网站的人几乎就是史前动物了。我认为对 Google 他们是大利空。

    可以想像,就像抖音快手分别带火大量新品牌一样,我认为所有厂商都不会放过这个机会,大家一定会涌入 ChatGPT 插件市场,试图用 AI 给自己引入新的用户。未来,CEO(Chat Engine Optimization)可能会和 SEO 一样重要。比如,通过在知乎问答“脸上长痘怎么办”里注入自己的品牌内容,可能比做一堆垃圾内容农场,更有价值。这么一想,利好知乎、Quora。

    插件系统并不会威胁其它 AI 厂商

    我倒不觉得插件系统会对其它 AI 厂商带来什么威胁——或者不如说,不会让威胁更大,因为模型领先太多。相反,ChatGPT 很可能通过自己的发展,给其它厂商打了个样出来,让大家知道怎么做产品。

    比如,多模态重要还是接入互联网重要?我觉得可能是后者,至少对百度而言,过去一周被反复处刑的文生图功能,是不是可以先放放?集中精力优化大模型,然后多做一些应用层的接口,可能更受市场欢迎。

    API 能不能用插件系统,怎么用?

    作为应用开发者,我觉得,插件能带来的功能,我用 App、自己的网站、浏览器扩展,都可以完成。(正如我在 之前的文章 说过的那样)。只要能获得合适的收益,在 iOS、Web、还是 ChatGPT 平台上做产品,对我来说都差不多,都挺好。

    所以我更关心技术天花板在哪里。比如访问网络的能力,我能不能在 API 里使用?怎么用?这关系到我能否拥有自己的产品入口,以及我应该怎么搭建我的基础设施。

    OpenAI 的云够用么?面向公共开放后,收费贵么?

    现在几乎所有 AI 产品都在排队,OpenAI 更是排队大户。我觉得除了产品本身的成熟度之外,他们的云服务承载能力和运营成本也是排队的一个重要原因。

    假设将来产品基本成熟了,单客成本会是多少呢?有多少用户能用上呢?我觉得也是个问题。所有的工具,都会加剧人与人之间的差异,将来善用 AI 工具的人一定比全手工的人高效很多,那么 AI 会不会导致新的不平等呢?

    Stable Diffusion 小进展

    这些问题可能都是国内才会遇到的,即然我是简中写作,那可能还有些作用吧。我们使用的是 AutoDL 的服务器,看起来是建在华为云上。服务器官方提供代理,可以加速 GitHub 访问,但是我们这个区刚好没有,惨兮兮……当真是没有困难创造困难也要上。

    安装扩展

    SD webui 默认仅允许本地环境在线安装扩展,我们部署在服务器上的环境必须添加 --enable-insecure-extension-accessCOMMANDLINE_ARGS 里才可以。配置并重启服务之后就可以了。

    直接 clone https 协议的仓库可能会被墙影响,然而默认情况下,基本上所有扩展都要依赖 git clone https://github.com/xxxx 安装。此时我的解决方案是先生成 ssh-key:

    ssh-keygen -t ed25519 -C "meathill+sd@gmail.com"

    然后把 key 添加到 GitHub。再接着把 ssh 协议的仓库链接复制到“Extension > Install from URL”里安装,即可。

    安装完成后,很多时候仅重载前端界面不行,还是要重启整个服务。

    面部修复

    AutoDL 提供的镜像默认不包含面部修复功能,在第一次使用该功能时,SD webui 会尝试下载对应的包。因为服务器在墙内,下载地址在 GitHub,所以速度很慢,可能会超时或者断线失败。此时可以手动辅助处理,先下载到本地,然后上传到服务器。大约有以下几个文件:

    使用 Vercel Edge Function 调用 OpenAI API 的经验

    我总结了最近几周的开发经验,主要是使用 Vercel Edge Function 提供 API 服务时踩过的坑,汇集成一篇博客,推荐有类似需求、做类似技术选型的同学参考:

    使用 Vercel Edge Function 访问 OpenAI API 的注意事项

    一堆新品

    各大厂商发布了不少围绕 AI 打造的新品和改进的老产品,正如下图所示:

    这里简单列几个,大家有空可以试试。不过大部分都只是有限开放,要先加入 wishlist,等排队。

    • GitHub Copilot X 更好的代码辅助工具,可惜只能用在 VS Code
    • 文心一言 百度的竞品,目前还不能打,不过持续关注吧
    • Office Copilot 整合 GPT 到 Office 里,可能产生质的变化
    • Google Bard Google 的竞品,好像也要差一些
    • Adobe Firefly Adobe 把绘图类 AIGC 整合到自家的产品里,大大降低美术制图的门槛

    市场很热,OpenAI 的掌舵者对节奏的把握也很强,隔三差五就把大家刺激一波。我的观点还是:书上得来终觉浅,绝知此事要躬行。工程上总会有各种各样奇奇怪怪的问题等待我们去解决,有些可以用 AI 加速,有些则需要自己摸索。所以对大家来说,越早动手,工程积累越多,优势越大。

    大家加油吧。有空别忘了去排队。

  • 使用 Vercel Edge Function 访问 OpenAI API 的注意事项

    使用 Vercel Edge Function 访问 OpenAI API 的注意事项

    从某天开始,OpenAI API 无法从国内直接访问。而且,也不是每个人都有自己的云服务器,能够搭建独立服务。那么,还有别的办法能比较容易的访问到 OpenAI 么?当然是有的,比如 Vercel Edge Function,或者 CloudFlare Edge Function。

    这里我准备结合前阵子的开发经验,分享一下使用 Vercel Edge Function 访问 OpenAI API 的注意事项,让新来的开发者能少走弯路。

    推荐阅读

    开始之前,我建议大家先花点时间了解一下 Edge Function,以及如何使用 Vercel Edge Function 开发 OpenAI 应用。因为我后面要分享的主要是踩过的坑,所以先系统性了解会好很多:

    Building a GPT-3 app with Next.js and Vercel Edge Functions

    官方教程,还有 Demo 网站GitHub 项目,非常友好。虽然是英文写的,不过并不难懂,实在不行就用 Edge 浏览器自带的翻译功能吧,建议大家好好学习英文。

    自有域名+CNAME 实现国内访问

    Vercel 给免费版用户也提供子域名+ SSL 证书,很多时候都够用,但可惜,vercel.app 大域名被墙了,连带所有子域名都无法访问。好在 Vercel CDN 在国内也还能用,所以我们只需要一个自己的域名即可。

    申请域名的选择有很多,国内几大云服务商都能注册,国外的域名供应商也可以放心使用。我比较常用的是 namecheap.com。便宜的比如 .xyz 域名首年只要几块钱,随便注册一个就能用。

    注册完域名之后,在 Vercel 后台找到自己的应用,在“Setting > Domains“里添加域名,然后 Vercel 会告诉你怎么配置 DNS。复制解析目标,在域名供应商 DNS 配置页面完成 CNAME 配置,稍等片刻,解析生效后,即可得到一个国内也能正常访问的域名。

    使用 Edge Function

    Vercel Edge Function 与我们日常开发的 node.js 服务器略有区别。它并非完整的 node.js,而是 Edge 基于 V8 专门打造的袖珍运行时,尽可能轻量化,裁剪掉很多系统 API。功能少,但是速度很快,几乎零启动时间。(我之前将它跟 Supabase 记混了,以为它也是基于 deno 的。)

    使用 Edge Function 的好处,简单来说:省运维;详细来说,大概有这么几点:

    1. 性能更好。比随便买个小水管强得多。
    2. 自带弹性伸缩。不管访问量怎么成长,都有 Vercel 集群帮我们自动伸缩。(当然可能需要付钱)
    3. 启动速度比 serverless 快很多,基本没有等待时间。
    4. 免费额度足够初期 MVP 验证。

    坏处当然也有。首先,Edge Function 里跑的是 TS,这就意味着很多兼容 JS 的开源仓库都不能用。其次,Edge Function 很多原生 API 都不支持,所以没有特意兼容的仓库也不能用。举个例子,要完成网络请求,大家最熟悉的 Axios 就不能用,只能用系统原生的 fetch

    解决超时问题

    由于算法原因,OpenAI API 返回数据的总时间可能比较长,而 Edge Function 的等待时间又限制得很严。所以如果等待 OpenAI 返回全部数据再渲染,可能因为等太久,在 Edge Function 这里会超时。

    解决方案就是使用流(stream)式传播。在这种情况下,OpenAI 会逐步返回结果(差不多一个单词一个单词这样蹦),只要在客户端进行组合,就能看到类似实时输入的效果。

    完整的范例代码上面的官方文章有,我就不复制粘贴了,大家注意就好。

    Edge Function 的流不是最初的流

    这里有个坑,虽然我们在 Edge Function 里获取了 OpenAI API 的流,然后转发出来,但实际上我们接收到的流并不是最初的流。最初的流里,每次发送的数据都是完整的 JSON 文件,可以直接解析;但是 Edge Function 里转发给我们的却是前后合并后随机切分的结果。

    于是我们必须重新整理响应体。大概方案如下:

    1. 在每次返回的响应体里找到两个 json 的连接处
    2. 截断,拿到前面的 json,解析,得到自己想要的数据
    3. 继续查找完整的 json,如果没有,则和下一次响应体连接起来处理

    核心代码如下:

    class fetchGpt {
      fetch() {
        // 前面的代码参考官方例子
        // 我从循环读取开始
        while (!done) {
          const { value, done: doneReading } = await reader.read();
          done = doneReading;
          if (!value) {
            break;
          }
    
          // readableStream 读出来的是 Uint8Array,不能直接合并
          if (chunkValue.length > offset) {
            lastValue = concatUint8Array(lastValue, value);
          } else {
            lastValue = value;
            offset = 0;
          }
          chunkValue = decoder.decode(lastValue);
          [finishReason, offset] = this.parseChunk(chunkValue, offset);
        }
      }
      parseChunk(chunk: string, offset = 0): [string, number] {
        let finishReason = '';
        let nextOffset = offset;
        while (nextOffset !== -1) {
          nextOffset = chunk.indexOf(splitter, nextOffset + 1);
          const text = nextOffset !== -1
            ? chunk.substring(offset, nextOffset)
            : chunk.substring(offset);
          try {
            const json = JSON.parse(text);
            const [ choice ] = json.choices;
            const { delta, finish_reason } = choice;
            const chunkContent = delta?.content || '';
            // 这里我把数据交给事件 和 pinia 处理
            this.emit(MessengerEvent.MESSAGE, chunkContent, json.id, json.created);
            this.store.appendTextToLastItem(chunkContent, {
              id: json.id,
              created: json.created,
              system: this.options.system || '',
            });
            finishReason = finish_reason;
            offset = nextOffset !== -1 ? nextOffset : chunk.length;
          } catch (e) {
            //- ignore
          }
        }
        return [finishReason, offset];
      }

    常见 API 使用错误

    大家都知道,OpenAI 按照请求响应的 token 数算钱。所以我就想精打细算,通过在请求参数里减少 max_tokens,尽量少返回些内容。

    事实证明这个做法不成立。首先,OpenAI 对请求的兼容性不高,max_tokens 如果是 NaN 或者带有小数,都会报错。其次,ChatGPT 很啰嗦,内容量少了,它不过瘾,就会反复要求继续(finish_reason: 'length'),尤其在极端条件下,如果我们自动 continue,可能会误入死循环。

    所以我建议,max_tokens 最少 128,尽量 256 以上。


    前几天,有朋友在我的博客下面留言,说 Whisper 他试过,没啥特别的。我的观点不是这样。所谓纸上得来终觉浅,绝知此事要躬行。很多东西,确实不复杂,照着官方教程弄,三下五除二,在本地跑起来,并不难。但是想弄得干净利索,在生产环境里跑顺,遇到什么问题都能快速解决,也不是随随便便就能搞定的。

    希望有类似需求,寻求类似解决方案的同学能少走弯路;也欢迎大家多多分享,有意见建议,欢迎留言讨论。

  • 我的 AI 学习一周总结:ChatGPT API 的改进

    我的 AI 学习一周总结:ChatGPT API 的改进

    本周也在继续学习 AI based 应用研发,继续总结+做笔记。

    ChatGPT API 的改进

    新 API 除支持 ChatGPT 模型以外,还增加了一些功能参数,能让我们提升工具效率,同时降低费用消耗。

    新增 messages 参数,显示定义角色

    ChatGPT API 增加了 messages 参数,支持显示定义角色,可以取代之前的 prompt,更清晰的标记每一个内容的来源,方便 API 生成更有价值的内容输出。OpenAI 称之为“Chat Markup Language(ChatML)”,格式如下:

    type MessageItem = {
      role: 'user' | 'system' | 'assistant';
      content: string;
    };
    type Messages = MessageItem[];

    具体文档参见:Chat completion – OpenAI API

    以前我们必须手动保留全部来往信息,放在 prompt 里。这样有几个问题:

    1. 往来数据量很大,很多时候要浪费钱在传输前面产生的内容上
    2. 除了 ChatGPT 以外,其它工具无法分析数据结构
    3. 我估计,OpenAI 那边的计算效率也不高

    n 参数,支持一次性返回多个结果

    以前虽然名为 choices,但每次只返回一个结果,如果要调整,就要多次发送 prompt,还要带上之前的结果,很浪费。

    现在,如果是文字润色、内容仿写等场景,就可以从多个结果中选择最好的一个,再进行微调,无疑会大大提升效率,也会降低消费。

    突破 token 限制

    使用 OpenAI 自己的 embedding API,将自己的数据(比如聊天记录中的数据)导入,生成更符合自己需要的模型。新的模型被之前的数据重塑过,就会看起来更符合新的要求。

    原文在此:这确实是一个相当好的绕过tokens长度限制解决方案,我尝试将这个方案整理一下

    仓库在此:mckaywrigley/paul-graham-gpt: AI search & chat for all of Paul Graham’s essays. (github.com)

    值得关注的项目

    LlamaIndex(gpt-index)

    Welcome to LlamaIndex (GPT Index)! — LlamaIndex documentation (gpt-index.readthedocs.io)

    正在更名为 LlamaIndex(羊驼),可以将自己的数据和 LLM 结合,得到更适合自己的模型。基本上就是上面 “突破 token 限制” 逻辑的实现。比如,我们可以把一本书通过 LlamaIndex 喂给 ChatGPT, 得到的模型里就有了我们最近喂进去的知识,然后我们可以再用自然语言向 ChatGPT 提问,就会得到包含了新知识的答案。

    感觉一扇新的大门正在打开。几乎所有说明书、客服,甚至一些高阶职位都可以(可能)被这个方案替代。据说实测结果,它对新知识的理解归纳总结能力都很强。

    ChatPDF

    ChatPDF – Chat with any PDF!

    不知道跟上面一个项目是什么关系,感觉实现的功能很像。上传一个 PDF,然后使用自然语言的方式让 ChatGPT 帮你提炼内容。我试了一下,感觉很神奇,虽然我觉得不能替代完整读完一本书的价值,但帮我们快速归纳查找内容应该作用很大。

    然则,我试用之后发现,它还是做不到“不知道就说不知道”,于是,如果我们的问题超出了书本和它原本模型的边界,它就又开始瞎编了。这仍然是很大的问题。因为用户可能默认它包含了书的全部内容,用户自己却不十分确定书的内容,于是很可能把错误的知识归纳当成正确的吸收。

    bilingual_book_maker

    yihong0618/bilingual_book_maker: Make bilingual epub books Using AI translate (github.com)

    基于 ChatGPT/OpenAI 的全书翻译工具,可以把完整的一本书交给它,它会帮你拆开,一节一节的翻译,然后生成一本新的返回给你。

    酷表

    酷表ChatExcel

    上传 excel,然后用自然语言描述你的需求,它会帮你自动调整表结构、编写函数,等。直到你满意,就可以下载表格,继续编辑。

    目前来看有些文件会上传失败,可能还不太稳定,可以持续观望。

    部署 Stable Diffusion 到 AutoDL.com

    经 Easy 推荐,我在 AutoDL.com 购买了一台 3090 服务器,给几个朋友部署 Stable Diffusion 环境。AutoDL 的价格比较便宜,支持按小时租用,还有做好的镜像,使用起来比较方便。大概过程如下:

    1. 抢一台服务器。因为显卡数量有限,价格比较便宜,所以必须过抢。
    2. 服务器就位后,登录 JupyterLab,按照提示运行
    3. 使用“自定义服务”获取对外的 IP 和端口
    4. 因为系统盘容量有限,可以把模型放在数据盘上,然后软链过去使用
    5. 实测 3090 出图速度很快

    复制周姐成功,接下来该学习 Lora 炼丹了。

    Hackathon

    近期跟 AI 有关的 Hackathon 也很多,我报名了好几个,已经有点忙不过来了……

    推荐给大家:

    1. SegmentFault AIGC Hackathon 2023 黑客马拉松
    2. 即刻(App 里搜索“AIHackathon”)
    3. 腾讯 Light(报名已经截止)

    现在各种 AI 的新知识简直太多了,看着各种新闻,一方面精神振奋,另一方面又觉得有点慌,感觉不自觉就会地落在别人后面……

    另外,原则上来说,ChatGPT 是 OpenAI 的作品之一,很多功能可能要借助 OpenAI API 实现。不过实际讲述时,我就懒得区分了,相信读者应该能看明白。

  • 我的 AI 学习一周总结:ChatGPT API 发布

    我的 AI 学习一周总结:ChatGPT API 发布

    即然接下来的时间准备投身 AI 行业应用层开发,那就隔三岔五分享一下近期学到的知识、在做的事情吧。(配图是今天用第一次用 SD 生成的图片,prompt:“a beautiful girl“。)

    ChatGPT API 发布

    今天(2023-03-02,美国时间 03-01) OpenAI 正式发布了 ChatGPT API,即 基于 gpt-3.5-turbo 模型的。它的价格更便宜,$0.002/1k tokens,比之前 text-davince-003 便宜 10 倍。它能提供更好的对话质量,还提供了新的结构化数据接口,相信会给应用开发者带来更多的空间。

    chatgpt 等 npm 包也相应更新,如果没有办法搞定绑卡操作,可以继续用这些社区接口白嫖。

    尝试 Vercel Edge Function

    之前开发 GPT-3 插件的时候,有同学介绍了 Building a GPT-3 app with Next.js and Vercel Edge Functions 一文,于是我尝试把 API 挪到 Vercel Edge Function 上,然后失败。

    今天写本文的时候,又看了眼 TwitterBio 的例子,发现自己并没有做错。排查来排查去,还是自己犯蠢,部署环节出了问题。如今已经可以使用了。回头重构下插件,添加一些功能进去。

    学习社区 ChatGPT API 仓库

    ChatGPT 的开发商 OpenAI 提供两大块服务,API 和 ChatGPT 网页版。API 需要绑卡,有一定门槛;网页版可以免费用,不过存在偶尔连不上、响应慢等情况,据说买 plus 之后会有好转。

    于是社区就开发了网页版转 API 的工具,可以用来搭建自己的 ChatGPT API。但是需要使用反向代理服务器作为中转,开发者也不提供反向代理服务器的源码,存在一些风险,所以我看完就不打算使用了。

    本地搭建 Stable Diffusion 环境

    搭建过程其实很简单,难点主要在下载 pip 包和模型上,受限于墙内的网络环境,原本简单的下载变得异常艰辛。还好在换用国内 pip 源之后,我终于在本地搭建成功 Stable Diffusion Web UI 环境。大体过程如下:

    1. 安装必须的软件环境,比如 cmake、python3.10 等
    2. clone AUTOMATIC1111/stable-diffusion-webui: Stable Diffusion web UI (github.com)
    3. 修改 pip 源
    4. 反复执行 ./webui 直至安装成功
    5. 换模型可以在 Civitai 下载

    Whisper 模型

    Whisper 模型是 OpenAI 释出的开源模型,可以用来做语音识别,据说效果非常好。它不仅可以识别语音内容,还可以根据声纹,区分不同的发言人。所以用途也很广,比如视频会议之后,可以用它生成会议的文字记录。如果再结合 ChatGPT,就可以进行内容总结、会议摘要等工作,想象空间很大。

    因为开源,所以可以自己搭建服务器,据说不需要很强的计算能力,庶民可用。OpenAI 这次也放出了 Whisper API,方便用户使用。

    ChatGPT 新知

    中文语料少的副作用

    使用英文要求 ChatGPT 创作哈姆雷特的故事,它会拒绝,因为它知道哈姆雷特,新故事如果背景差异过大,它就会拒绝。但如果用中文,因为语料不足,哈姆雷特对它来说也只是个人命,它就会很配合。

    名人资料

    GPT-3 会大量混淆中国名人,比如郭德纲、岳云鹏;相对来说,ChatGPT 就好很多。


    现在 AI 工具与 AI 基础设施层出不穷,日新月异应接不暇,学起来既有动力也有压力。下一步希望能把所有工具的环境都搭建起来,先积累感性认识再说。