标签: vercel

  • 聊聊 Serverless 与 Edge Function

    聊聊 Serverless 与 Edge Function

    熟悉我的同学可能记得,前几年我经常推荐 Serverless,而且我的博客里现在还挂着 LeanCloud 的推荐链接。我觉得 Serverless 对前端、全栈开发者来说简直是个福音,很多原本很难的开发工作,有了 Serverless 之后,都能很容易的由前端处理,大大扩展了前端的能力覆盖范围。

    时至今日,我们不仅有 Serverless,还有 Edge Function,后者几乎没有冷启动的问题,更能提供 SSR 功能,好上加好。很多数据存储服务也针对性地提供好用的接口。今天的开发环境对前端来说,简直无与伦比。所以我想聊聊这个话题,希望每个前端都能在 Serverless/Edge Function 得帮助下成长为全栈开发。

    Serverless 是什么?

    我就不去抄准确定义了,按照我的体验来分享:

    1. 不需要维护独立的服务器
    2. 分为两个部分:
      1. 基于行级权限控制的数据库
      2. 可以自动扩容、降容的云函数执行器
    3. 云数据库,配合行级权限,配合合理的数据逻辑,可以在前端完成大部分数据处理的工作
    4. 云函数可以自动扩容、降容,可以休眠、启动,可以完成云数据库无法放在前端的操作
    5. 云函数以函数为一个执行单位,实现更精准的资源控制

    总之,前端有了 Serverless,就可以在没有后端、没有运维的配合下,独立完成完整应用的开发,并且具备相当强的扩展能力,费用也很低。

    其它应用场景

    除此之外,Serverless 还可以用在各种有突发计算高峰的场景里,比如音视频处理。我们可以利用 Serverless 在没人使用时自动休眠(不计费),有人访问时自动启动的特性,有需求的时候才启动,完成计算后自动关机,既节省成本,又提供很高的理论并发。

    Serverless 的问题

    早期的 Serverless 调度系统有些问题。出于学习成本的考虑,早期 Serverless 多数是基于容器技术,虽然可以完整支持大部分编程语言及其 API,但是冷启动一般都需要不少时间,少则十几秒,多则几十秒。

    这么久的启动时间,对于计算密集型领域来说,问题并不严重。因为在这些场景里,几十秒的启动时间占比不高,通常来说用户需要等待的时间远比它久,自然有队列和轮询放在前面。但是对于一般的网站应用,服务普通客户,如果启动一次要几十秒,那就很难接受了。

    比如最近大热的 ChatGPT,有些同行尝试用 Serverless 做转发,就受困于冷启动,经常超时报错。

    一代更比一代强:Edge Function

    我不太确定 Edge Function 是什么时候诞生的,最初我以为 Edge Function 无非就是跑在运算力富裕的边缘节点上,本质上跟 Serverless 没什么区别,直到前些日子开始大规模使用 Vercel,深入了解之后,才明白 Edge Function 的优势。

    简单来说,无论是 Vercel、Supabase、还是 Cloudflare Worker,都抛弃了以前基于 Docker 的做法,或者精简运行时,或者使用 deno 这样更快更小的核心,将冷启动的速度降到毫秒级——基本就是网络传输的延迟级别。

    于是 Edge Function 的可用性就大大提升,可以用在各种速度敏感型的场合,比如现代框架的 SSR、代理服务器、HTML 内容改写,等等。

    目前,我的 Edge Function 主要用在以下几个场景:

    1. Nuxt.js/Next.js 的 SSR
    2. 代理 OpenAI 的 API 访问
    3. 操作 Upstash Redis 存储和修改数据
    4. 响应 Stripe 的付款请求

    Vercel Edge Function 的限制

    我用 Vercel 比较多,这里介绍一下 Vercel Edge Function 的限制。

    首先,Vercel Edge Function 是 node.js 的子集。除了拥有完全一致的语法和基本对象之外,Edge Function 并不能使用全部的系统 API,比如 fs、http/https 等。所以类似 axios 这样知名的 ajax 封装就不能使用;也不能使用 OpenAI 的官方 npm 包。

    Edge Function 只支持 ESM,所以依赖里面的包即使没有用到系统 API,也必须使用 ESM 才能使用。所以我们必须经常性的处理一下公共包。

    虽然支持 TypeScript,但部署的时候,会使用 ESM 编译,所以 import 必须使用相对路径,否则会报错。报错的内容是使用了不支持的格式,非常有误导性。

    其它就是一些系统性要求,比如代码限制、内存限制、请求体限制等,我目前都还没有撞到。大家小心点就是。比较可能遇到的问题是,Edge Function 30s 内必须开始返回内容,这在 OpenAI 开发中很容易遇到问题,开启 stream: true 就好。

    更好的生态环境

    Vercel、CloudFlare 均提供非常完整的网络环境,包括网站、CDN 缓存层等必备服务。

    如果要使用数据库,选项非常丰富,除了 Vercel 自带的各种不解渴的“小样”,我们还可以使用 Upstash Redis,MongoDB,PlantScale MySQL,Supabase PosgreSQL,以及 TiDB Cloud Serverless。

    基本上,应有尽有,几乎所有 Web 开发所需要的存储方案都能找到有免费额度的试用装。开发环境真是盛世空前。

    我们应该怎么做

    现在经济大环境不好,很多同学面临失业、降薪,V2EX 上经常有同学讨论是开网约车好还是送外卖好……这个我也没办法。但是从另一个角度来说,我们的开发环境却是史无前例的好,部署、运维成本非常低,几乎所有必须的服务都有免费试用,每家都提供清晰的文档、易用的 SDK。

    我建议,大家好好利用闲暇时间,利用现在各种生成式模型大爆发,但是市场还没稳定下来的时间节点,多多尝试,即使做不出惊世之作,也能为自己的将来累积足够多的资本,坚持到云开日出那一天。

    广告时间:我的全栈开发课程

    发现忘记打广告了,赶紧补上。

    我目前正在连载一套云原生全栈开发课程,使用 Nuxt3 + Vercel + Serverless 数据库开发。目前发布了三集,本周计划制作第四集(如果有时间就做第五集,嗯嗯),请大家观看,有号的话还请帮我一键三连,多谢。

    B站地址:Nuxt3+Vercel+Serverless 数据库全栈开发

    油管地址:Nuxt3+Vercel+Serverless数据库全栈开发 – YouTube

    总结

    曾经面试金山的时候,有位面试官问我:你这么大年纪,你觉得你比年轻人有什么优势?我答道:因为我年纪足够大,见识过足够多的技术发展,所以我能更快地学会一门技术,也能更准确的判断一门技术是否值得学习。我一直很看好 Serverless,如今有了 Edge Function,serverless 更好用;有了各种服务,serverless 更强大。Serverless 是未来全栈不可或缺的技术。

    希望大家都学会使用。有任何问题、建议、意见,欢迎留言讨论。

  • 【视频】Nuxt3+Vercel+Serverless 全栈开发(1):技术选型介绍,项目基础搭建

    【视频】Nuxt3+Vercel+Serverless 全栈开发(1):技术选型介绍,项目基础搭建

    大家好,时隔小半年,我又来做系列视频了。这次计划结合近期的一些开发经验,分享最近我比较喜欢的全栈+高效+免费+云原生技术方案。

    这套技术方案大约是这样:

    • Nuxt3
      • 提供 Vue 开发环境
      • 提供服务器渲染 SSR 能力
      • 提供 API 环境
    • Vercel
      • 提供部署环境和各项网站能力
      • 提供 Edge Function 和各种存储
      • 提供全球化服务能力
      • 提供 SSL
      • 免费额度足够用很久
    • Upstash
      • 提供 Redis
      • 免费额度足够用很久
      • 付费也不贵
    • TiDB Cloud Serverless
      • 云数据库,MySQL 兼容 API
      • HTTP endpoint
      • 免费额度足够用很久
    • 其它
      • Nuxt- i18n
      • TailwindCSS
      • DaisyUI
      • GitHub
      • pnpm

    使用这套技术方案,可以应对绝大多数网站需求,部署在全球化网络里,使用丰富的免费资源。云原生会带来天生的高可用性、鲁棒性、伸缩性。

    这是第一次分享,详细介绍了这套技术选型,nuxt3 项目的基础搭建,和它自带的路由、服务器 API 系统。

    这次会把每次的分享压缩到 25~30 分钟,降低观看门槛。

    如果你有任何问题、建议,欢迎留言讨论。请 b 站有号的同学帮忙分享完播一键三连,谢谢大家。

    另外,我也在 YouTube 上上传了一份,大家有空的话,麻烦帮忙关注下我的油管频道,感谢感谢。肉山全栈小课堂 – YouTube

  • 使用 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 他试过,没啥特别的。我的观点不是这样。所谓纸上得来终觉浅,绝知此事要躬行。很多东西,确实不复杂,照着官方教程弄,三下五除二,在本地跑起来,并不难。但是想弄得干净利索,在生产环境里跑顺,遇到什么问题都能快速解决,也不是随随便便就能搞定的。

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

  • 【代友招聘】【全职远程】全栈 Next.js Web3 教学网站

    【代友招聘】【全职远程】全栈 Next.js Web3 教学网站

    事情是这样的。前厂去年年底把我们遣散后,我就找了一些工作来做,这是其中之一。我们最初要参加一场 Hackathon,作品是 Web3 教学网站,用游戏闯关的模式,吸引更多人来加入 Web3 开发。Hackathon 之后,老板决定把产品延伸扩展,做成独立产品,继续推广,让更多人可以用。

    按约我本打算继续帮他们做开发,但如今我已经确定要跟 Vincent 一起做 AI 应用层的产品,时间上不够两相兼顾,必须辞去一边。经过协商,我接下来会逐步退出这边的开发,初期兼作一些顾问型的工作,直到他们招到合适人选。

    这里,我要帮他们招招人试试看。情况大概如下:

    • 这是一家主要团队在美国的初创企业
    • 他们的主要目标产品是 Web3 教学网站
    • 他们已有产品、设计、课程团队,需要一个比较有经验的全栈开发负责网站研发工作
    • 近几个月工资会以稳定币形式支付,需要自己负责社保等;几个月后他们会回到国内正式注册公司,到时候可以正式跟国内公司签约
      • 不希望稳定币的话,可以要求人民币结算
    • 老板还是很靠谱的,结账很爽利
    • 主要技术栈是 Next.js+TailwindCSS+DynanmoDB+Vercel
    • 工资我不敢承诺,不过应该在远程岗位里算不错
    • 最好有远程工作经验,能做好自我管理,还能辅助管理研发最好

    有兴趣、有能力的同学,请与我取得联系,我会推荐给他们进行进一步的面试。

  • 我的 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 基础设施层出不穷,日新月异应接不暇,学起来既有动力也有压力。下一步希望能把所有工具的环境都搭建起来,先积累感性认识再说。

  • Turbopack 发布后的各方反应:Vite/Webpack/围观群众

    Turbopack 发布后的各方反应:Vite/Webpack/围观群众

    上周整理了一下 Turbopack 发布后的各方反应,以便让自己和各位同学下一步做决策的时候能有所参考。接着忙碌的一周过去,我发现博客这周还没更,于是赶紧来补一下。

    0. TL;DR

    1. Turbopack 的宣传语更多还是“宣传”,实际效果提升并没有那么巨大。
    2. Turbopack 目前只支持 Next.js + React,且没有建立健全插件机制,所以没有生态可言,如果我们的主要开发环境不一致,可能暂时用不到。
    3. Turbopack 基于 Rust 开发,性能提升主要来自 SWC,所以有时间、有兴趣的话,直接使用 SWC 替换编译工具就好。
    4. 非目标开发者群体建议先不考虑迁移。
    5. Turbopack 对于打包过程有不小的改进,值得持续关注。
    6. 如果你日常使用 React,且想在新技术出现时斩获先机,早点动手也挺好。

    2022-10-26

    首先,10月26日,Vercel 发布了 Turbopack,自命 Webpack 继任者,号称速度比 Wepback 快 700 倍,比 Vite 快 10 倍。

    这些是官推亮点:

    • ~700x faster than Webpack -> 比 Webpack 快 700 倍
    • 10x faster than Vite -> 比 Vite 快 10 倍
    • Native incremental architecture built with Rust -> 基于 Rust,具备原生可增长架构
      ◆ Support for React Server Components -> 支持 React 服务器组件
      ◆ Support for TS, JSX, CSS & more -> 支持 TS、JSX、CSS,以及更多

    尤大观点

    很快,Vite 作者 @youyuxi 就跟进表达反驳:

    “10x faster than Vite” isn’t entirely accurate

    “‘比 Vite 快 10 倍’并不完全准确”,他说。

    然后他进一步介绍了自己的理由:

    1. Vite’s default React HMR is still babel-based, while Next/turbopack use swc/rust-based transform, so the HMR performance difference is a bit of apples to oranges.

    因为 Vite 默认的 HMR 仍然基于 Babel,而Next/Turbopack 使用的是基于 Rust 平台的 SWC,所以这里 HMR 的性能差异是关公战秦琼(这个 thread 后面还有若干理由,我就不一一翻译了):

    Vite can switch to the swc/rust transform if necessary, we currently chose not to do that because adding swc to the deps list is extra weight, and even without it HMR is fast enough.

    Vite 当然可以在必要时切换到 swc/rust,但 Vite 开发团队并不想这样做,因为即使只用 Babel(不那样做),HMR 也足够快。使用 SWC 替换 Babel 只是平添开发负担。

    1. turbopack does address Vite’s request congestion issue on large apps. On Vite side we are also exploring how we can solve this via upcoming browser features like web bundles.
    1. Turbopack 确实解决了 Vite 在大型应用上的请求拥塞问题。我们 Vite 团队这边,也在探索如何解决这个问题,比如,是否可以借助即将推出的浏览器功能(Web Bundles)。

    In the long run we may also consider using turbopack under the hood to replace esbuild/Rollup (where suitable), due to its strong caching capabilities.

    1. 从长远来看,由于 Turbopack 强大的缓存能力,我们也会考虑在底层使用 Turbopack 来替换 esbuild/Rollup。如果合适的话。
    1. I’m glad vercel is investing its resources into a proper native-speed successor to webpack (as it should), and that our work on Vite has pushed this to happen. It’ll be interesting to see how it evolves – my hope is it can be made truly framework agnostic, not Next-first.
    1. 我很高兴 Vercel 愿意投入资源,打造 Webpack 的继任者,并着力提升它们的速度表现(应该如此),我们在 Vite 上的努力也达到了这样的目的。我对它们未来的演变很感兴趣——我希望它不要和框架捆绑在一起,不要 Next-first。

    Sean Larkin 观点

    (Sean Larkin 是 Webpack 的核心团队成员。目前好像在 LinkedIn 工作,好像。)

    Sean Larkin 也表达了自己的观点:

    Few thoughts: 几点想法:

    1. Love the innovation but it looks moderately SWC powers and wish there was some more callout there.
    2. Disappointed how entangled this is with next/turborepo. But Vercel needs to make.
    3. The path of migration from webpack for the avg user will be hard.
    4. I like that the dev server is still bundling modules because ESM slower than raw ESM. I need to peel back more layers to try and get a standalone implementation working.
    5. It’s all in alpha so we need to still look at the broader view but I hope we’re selling less going fwd
    1. 我喜欢创新。但看起来,Turbopack 更多是借力于 SWC,希望对方能表达得清楚一些。
    2. 我对 Turborepo 与 Next 的绑定程度感到失望。但是 Vercel 需要挣到更多的 (天使资金),没办法。
    3. 普通用户想 Webpack 迁移过去,会很艰难。
    4. 我倾向于开发服务器上的模块仍然是打包后的,因为 ESM 比原始 ESM 慢。我需要剥离更多层,才能让独立的实现工作。
    5. 目前它还处于 alpha 阶段,所以我们要看开一点,但我仍然希望,销售手腕少一些,好好干开发。

    2022-10-27 ~ 2022-10-28

    这段时间,@youyuxi 觉得 Turbopack 的数据有问题,因为 Vercel benchmark 的设计有问题,于是他尝试调整测试方式,给出了一些数据。不过后来他删除了这些推文,因为数字不太对。

    2022-10-27

    Vite 核心成员之一,@antfu7 在知乎上表达了自己的观点:

    他认为 Vite 更吸引人的是其插件系统,和构建在上面的生态系统。这样才能将改进快速带给其他领域。Turbopack 方面,静观其变吧。

    https://zhihu.com/question/562349205/answer/2733040669
    如何评价Vercel开源的使用Rust实现的Turbopack? – Anthony Fu的回答 – 知乎

    2022-10-29

    经过几天实验,Vite 作者 @youyuxi 发表了新的推文,新推文介绍了他进一步比较 Turbopack 和 Vite 之间性能之后,得到的新结论。

    I updated the vite vs next/turbo benchmark by using swc to transform React refresh for vite. To avoid confusion, I have deleted the previous two tweets with outdated numbers.

    Latest numbers:

    • root: vite 338.2ms / next 334.6ms
    • leaf: vite 141.8ms / next 84.4ms

    我通过搭配 Vite+SWC,重新评测 React 转换之后,更新 Vite vs Next/Turbopack 的基准测试。为避免混淆,我删除了前两条带有过时数字的推文。

    最新的对比数字:

    • 根:Vite 338.2ms / Next 334.6ms
    • 叶:Vite 141.8ms / Next 84.4ms

    The swc transform helps a lot in the root component case because the file is big, and previously cost 300ms in babel transforms alone. This makes vite almost exactly the same speed with turbopack.

    SWC 转换在根组件时候提供了很大帮助。因为文件很大,以前仅在 Babel 中转换就要花费 300 毫秒。替换之后,Vite 的速度几乎与 Turbopack 完全相同。

    Interestingly, in leaf scenarios turbopack is still 69% faster – this entails that Vite HMR actually caught up with turbopack as the file gets bigger, potentially scaling better in larger apps.

    有趣的是,在叶子场景中,Turbopack 的速度仍然更快,提升约有 69%。——这意味着随着文件变大,Vite HMR 实际上赶上了 Turbopack,在较大的应用程序中可能会有更好的扩展性。

    测试用仓库:https://github.com/yyx990803/vite-vs-next-turbo-hmr

    Because we are now testing the HMR of the same framework with the same set of transforms, the result is more relevant for other frameworks compared to previously posted numbers.

    现在,因为我们使用相同的转换集测试同一框架的 HMR,与之前发布的数字相比,结果的相关度更高。

    Just to add a bit of context – in this benchmark, even before using swc for React transforms, turbo is only 2x compared to vite (compared to marketed 10x). So the difference wasn’t that drastic to begin with.

    顺便讲点相关前提:这套基准测试,甚至在替换使用 SWC 转换 React 之前,与 Vite 相比,Turbo 也会仅 2 倍(他们市场宣称要快 10 倍)。所以其实一直以来,差异都没有那么大。

    2022-10-31 及之后

    本文主体整理于 10 月 31 日,之后 @youyuxi 还在孜孜不倦的跑 benchmark,与各路支持、反对、吃瓜者或讨论或争论。但是他的观点变化不大,所以我也就偷懒不继续翻译了,相信大家看完都能做出自己的判断。

    N 神有一些观点,摘录于此:

    vite 为了提升速度,利用了浏览器的特性,在 dev 阶段不打包而用 esbuild 预编译 esm 小包投送给浏览器, 在 build时候用 rollup 再打包。这样 dev 就会非常快(因为无需打包),但写插件就很分裂,要考虑 dev 和 build 两种情况。并且理论上如果依赖小包过多会肯定会遇到浏览器并发瓶颈减慢速度。

    按 Turbopack 的说法,他 dev 和 build 同样走打包流程,还能比 vite 快,那么铁定是更好的。只是太早期了,现在还没有开放插件生态。而且自命 webpack 继任者没毛病,看 github 上就是 webpack 作者主力搞的。

    但另一方面如果未来 non-bundler 成为主流,前端不再需要打包。turbopack就没用了。vite 抛弃 rollup,build 也走 dev 流程就更美了。

    https://twitter.com/nshen121/status/1587333382362763264

    SWC 作者和 Webpack 作者

    这二位目前都在 Vercel 工作,可能受公司公关限制,都只转发了官推,并没有发表更多意见。


    总结

    Turbopack 可能不如官方所说的那么好。它的确带来了 HMR 的提升,但代价是不健全的插件机制和生态环境,以及难以被前端团队掌握的 Rust 平台。

    未来一段时间,我们还要继续坚持在 Vite 平台上。

  • TiDB Hackathon 2022 参赛小记

    TiDB Hackathon 2022 参赛小记

    今年的 TiDB Hackathon 来的比去年早一些,赶在 1024 前举行。去年我参加 TiDB Hackathon 2021 之后,感觉非常好:组织给力、参赛选手水平高、技术分享氛围好,能学到很多东西。于是今年毫不犹豫,再次报名参加。

    我其实一直想搞个移植类的项目,把某个能用但不够好用的项目移植到 TiDB 上,得奖倒在其次,主要是为了将来自己用或者给别人用。但是我也知道,这类作品的技术含量有限,除非做得很好或者很有特点,否则多半连决赛都很难入围。于是我韬光养晦,卧底在群里,等待抱大腿的机会。

    然而,赛前创意脑爆会,CTO 黄东旭说了一些跟我很接近的想法——当然,也可能是我听错了,我当时一边搬砖一边开着直播,注意力不集中;后来我又听了一遍,没能找到印象中的那几点。

    本来想抱大腿,但是经历上次思否 Hackathon 之后,必须得说,哥们儿飘了,哥们儿觉得自己行了,哥们儿觉得自己也是个角儿了。于是我甩掉了前面已经蹭进去的队伍,拉大旗谋虎皮,邀请赋闲在家的竹子一起,组了自己的队伍,准备携余威再下一城。

    正所谓黄粱美梦,终有一醒。很快教训就来了。

    0. 开场 brief

    由黄东旭(TiDB CTO + CoFounder)演讲。

    TiDB 的诞生

    • 三个后端基建程序员,厌倦了分库分表的枯燥生活,决定造福大家。
    • 一腔热血+盲目自信,开始动手
    • Why TiDB?(自吹的部分省略,哈哈

    TiDB 的未来

    • From OLTP to HTAP
    • From SQL to API
    • From TiDB to TiDB-as-a-Service
    • From Infrastructure to Applications
    • From Code to You

    TiDB 近景展示

    基于云的高速动态 Scale 能力,把 TiDB 从数据库变成 end-point,让用户对底层无感,应该是未来的发展方向。

    1. 密集 coding

    开幕式结束后,各支队伍开始 coding。今年规定比较严,必须在入围决赛后才能写代码,杜绝有人拿一年的大项目 hackathon 上改个字体就参赛的行为。

    我们团队其实有一些前期的调研和摸索,比如我的 NocoDB + TiDB 实例很早就部署了,然后队伍的日常管理也在上面。不过事后来看,我们还是太轻敌了,各方面的。

    1. 行级权限控制(Row Level Security / Row Based ACL)

    首先我要确定 NocoDB 怎么支持行级权限控制,因为 idea 脑爆会上东旭有提到,所以得重视起来(面向 CTO 编程)。结果比较令人失望,NocoDB 并不直接支持类似 LeanCloud 那种 row based ACL。

    用一些比较复杂的方式似乎能够实现。比如:

    1. 生成主表
    2. 为用户创建不同的视图
    3. 用户通过特定表单提交信息

    总之这个方向进展不顺利。

    2. Vercel Template

    我们计划做的第二个东西(也是脑爆会上提到的),是 Vercel Template,即可以让用户在 Vercel 上一键部署实例的东西。

    临近中午,竹子找我说可能做不了,于是我赶紧去看。Vercel 本身主要提供静态内容托管,从 GitHub 拉纯前端仓库然后部署。后端服务只提供 serverless functions,支持文件路由映射。next.js 和 nuxt.js 不知道是主动还是被动,都提供了类似的方案去适配。

    NocoDB 前端是基于 Vue3+nuxt.js 打造的,所以并不难搞。困难的是服务端。我们面临两个选择:

    1. 手动把 API map 到文件路由(比如 /api/user => /api/user.get.js
    2. 直接用入口 js 作为 serverless function

    竹子开始尝试了方案(1),觉得可能超出 hackathon 的时间要求。我也觉得方案(1)不太靠谱,于是开始尝试方案(2)。由于依赖的问题、Vercel 的问题,我们一直折腾到凌晨 00:30,最终推翻了方案(2)……由于 serverless functions 的无状态特性,没有优化过的程序完全没法跑。

    3. SaaS

    最后我们只剩下来原本计划中 Nice to have 的功能:SaaS 平台。这个部分我们本来只想在 PPT 里提一嘴,算是对未来的展望,希望评委老师感兴趣。并没打算做,毕竟 hackathon 里俩人做 SaaS,怎么看也不靠谱,但是现在,这竟然是我们唯一可能的交付物了,真的是……

    当然完整交付是不可能的,我们的目标就是让评委相信我们能做出这样的东西来。

    其实说白了,这垂死挣扎,就是高考前,语文/英语老师说:“你们作文不会写,就把前面阅读理解打乱顺序抄一遍,不要空着!”,那个意思。

    2. 小转机

    没想到真的有转机,虽然不大。

    竹子 mock 了几个 API,仿真了在 Vercel 上使用 Template 部署应用的过程,录成视频,准备在 demo 的时候播。我一看,咦?反正都是模拟 API,我那儿(测试服)有现成的啊。这样一想,我整理出一个似乎还可以的想法:

    1. 部署 nocodb-gui
    2. 使用我的测试服作为 server API
    3. 完成演示

    这样可以演示一些效果,而且很容易带出来我们接下来要做的:基于 NocoDB+TiDB 的 SaaS。哎,昨天真是被 Vercel 部署消耗掉太多体力脑力了,竟然没想到这么直接的解法。

    3. 答辩

    其实事后想想,上面也称不上什么转机,顶多就算是把阅读题抄了一遍,只是稍微打乱了一下顺序。

    答辩时评委问我:你们这个有什么优势呢?有什么是你们做了,但别人难以做到的?扪心自问,其实没有。我甚至没来得及做 Vercel Integration。如果我们事先准备好,让用户能够通过 Vercel Integration 得到独立的 NocoDB Backend API 与 独立的 TiDB 实例,也许算是个完整的产品,但目前这个完成度,也就比交白卷强那么一丢丢。

    哎,打回原形,再次寄望于来年吧。

    4. 赛事组织点评

    TiDB Hackathon 的组织一如既往的给力。首先参赛过程非常舒服,纪念品诚意满满。CTO 的开场 brief 让人动力十足。后勤保障非常给力:包三餐、零食饮料下午茶管够;有些同学从外地来,想在公司打地铺,组委会也尽力帮忙满足。组委会还准备了一些活动,让大家能放松心情,加强交流,可惜我一直在跟 Vercel 搏斗,没空参加。哥们儿好歹也在 Just Dance 有 MegaDancer 的表现。

    哦对,美中不足,空调不够给力,只有风没有制冷。猜测是大厦周末不供冷,不能全怪主办方。

    这次我还动员了一些同学来参赛,不知道他们战果如何,希望比我好。相信他们也会收获颇丰。

    5. 其它收获和感想

    1. NocoDB 输入体验不行,但其它体验挺好,值得长期使用
    2. TiDB 的确挺快,developer tier 足够我现在的用量,准备继续白嫖下去
    3. 学会了 Vercel 生态的知识
      • deploy button
      • template
      • integration
      • deploy API
      • cli
    4. 新概念:HTAP

    总结

    今年的项目方向多半还是对的。降低用户门槛,提升产品可用性,应该是受主办方欢迎的方向。可惜我们选择的执行方式不够得当,可以帮用户薅羊毛,但要能薅到羊毛才行,目前这个方案,其实还有一段路要走。

    考虑到厂里年底要突击,姆伊用药助手 0.2 版本还没开始动工,以及其它一些开发需求,我估计会把这个项目放一放,先用着我的 NocoDB + TiDB 实例。等待时机,再动手折腾折腾。

    感谢 TiDB,举办这么棒的 Hackathon;感谢组委会,尽心尽力尽责,把活动办得这么好;感谢我老婆,给我放假让我在外面肝了两天代码;感谢竹子,跟我一起辛辛苦苦折腾半天,最后铩羽恶而归。生活还要继续,下周继续努力,大家一起加油。