Normal view

There are new articles available, click to refresh the page.
Before yesterdayMain stream

记录一次 AIGC Hackathon 参赛经历和收获

By: 李瑞东
29 May 2023 at 08:26
AIGC Hackathon 主题海报,由公司品牌设计师陶老师和 Stable Diffusion 的共同创作

公司在 5 月上旬的时候举办了一场 AIGC Hackathon 比赛,鼓励内部员工基于公司相关业务,利用 AI 技术进行创作,重塑生产力。

这么有意思的活动我当然也要掺一脚,在同事的怂恿和牵线之下,召集到了另一位设计师,以及一位研发大佬。所以加上我总共是 3 个人,2 个设计,1 个研发。但是严格来说应该是 1.5 个设计,1.5 个研发。因为我会参与到前端界面的实现,这也是我想参与这次活动的其中一个主要原因。

先放上我们开发的小工具的最终效果,其实是通过提前录入 SQL 语句规则,然后用自然语言询问 AI,让 AI 帮忙生成一个可用的 SQL 语句:

过程

想法

因为当前我们公司的业务是研发管理平台,所以我想到能通过 AI 帮助我们的主要是提高效率,减少出错,诸如此类的方向。

尤其是我在刚来到公司的时候有一段时间给我学习体验公司产品。中途就看到有个地方生成图表的话,可以选择各种筛选条件,也能用 SQL 来快速筛选,当时我就觉得如果用 SQL 来筛选会比手动一个个条件添加来的快,但我又不会写 SQL 语句,所以就想到一个主题:「输入自然语言,通过 AI 生成一段 SQL 语句」,产品名称就被定为「SQL-Helper」。

最开始我们讨论到有几种实现方式:

  • 产品原生:在公司的产品中搭建一个开发环境,在里面进行对话交互功能的设计和开发。
  • 外部网页:搭建一个网页,在网页里实现对话。
  • 谷歌插件(Popup):在浏览器右上角上添加一个 Popup 入口,点击后打开一个浏览器提供的容器,在上面进行对话交互。
  • 谷歌插件(嵌入网页):在公司的产品当中嵌入一个小卡片,在上面实现对话和配置等,会遮盖部分网页内容。
用树状图展示了三种实现方式的取舍选择方式的示意图。

最终选择了谷歌插件(嵌入网页)的方式,因为这样算是能比较融入到产品当中去,不需要来回切换网页这么麻烦,毕竟是一个对话的产品。而且 Popup 有一个致命问题是,如果鼠标点击到了网页的任何地方,Popup 就会收起,这种体验不适合用在聊天式的产品当中。而直接基于公司产品的开发环境中进行开发,这种做法成本比较大而且难以协作,毕竟团队中只有一个正经的研发。

团队合作

得益于大佬的用爱发电,他花了一个休息日的时间把架子搭起来了,技术栈是:

  • React
  • Ant Design Manifest V3(支持 Chrome 96)
  • Stylus 样式结构支持

最初搭建好的框架。是能够在网页中嵌入一个按钮,点击后打开一个弹窗:

最初搭建好的框架。图片展示了一个浏览器右下角有一个橙色的沙漏图标,点击后会打开一个出现在屏幕中央的弹窗。

这两个地方就是我们作品的主要载体。我们希望点击悬浮窗之后能打开一个聊天小窗口,能在里面填入 SQL 语句相关的 Key 和 Value,然后填入用户的 API Key,并实现与 AI 实时对话。

所以很快,在第一天的时候我们就有了一个大概的原型,中途通过每日下班前的简短碰面来一起决定增加/减少哪些内容。

最开始的原型。在 Figma 中进行的,由方框和简单文案组成的原型图。分为消息模块和配置模块,每个模块的原型图下方列举了一些必做的功能清单。

然后也确定了我们三人小组的分工:

  • 我:前期负责设计界面、实现静态界面。后期参与 Prompt 调试。
  • 另一个设计师:负责界面设计、图标设计、PPT 制作/包装。
  • 研发大佬:负责功能实现,比如表单提交,发送和接收消息,接口调试等。

然后我们就各司其职,我这边按照大佬给的流程,每天把自己做好的部分提交 Pull requests,并标记清楚完成了哪部分,哪部分的功能需要研发大佬来实现等等。

Github 仓库的 Pull requests 截图。展示了 SQL-Helper 仓库中部分 Pull requests 记录,并且用带有圆角的绿色方框高亮由我提交的部分 Pull requests。

整体的时间表如下图(只有五个工作日,时间紧迫。):

时间表截图。记录了三个成员在周一至周五各自的工作,完成的工作会用绿色打勾图标来标记。

一些细节

初试 Ant Design 的感受

平常在设计稿中使用基于 Ant Design 组件的经验有很多,但是自己亲自在代码里使用该组件还是第一次。

一个强烈的感受是,Ant Design 组件库确实很丰富,很多常用的组件都有封装好,主题色更改的功能也很强大。但是想要基于 Ant Design 组件库来做一些客制化的改动,实在是太费劲了(也可能是因为我太菜...)。

比如当时我想实现一个 TextArea 根据容器高度来自动填满高度的话,我的样式代码是如此之多:

在深色主题下 Visual Code 中的代码截图。展示了我使用大量重复的样式来让一个 TextArea 组件自适应高度。

另一个坑是我们的聊天窗口是嵌入到网站当中的,而且原本我们公司的产品也是基于 Ant Design 组件库搭建的,所以会出现很多样式的冲突。

比如我在自己的界面中使用了 Button 组件,而被嵌入的网站中如果也用了 Button 组件,那么样式将会被原本网页覆盖掉。

如果在这种情况下想要自定义样式,需要在 CSS 中通过多种手段来提升样式的优先级。这里是我比较频繁用到的两个提高优先级的方法:

  • 使用选择器提高 Class 的优先级
  • 使用 !important
在深色主题下 Visual Code 中的代码截图。展示了我使用选择器和 !important 的方法来提升所编写的 Class 层级。
CSS 选择器的优先级相关内容可以参考张鑫旭大神的名著《CSS选择器世界》,写得特别详细。

所以后面回想起来,我在改造 Ant Design 组件库花的时间还是太多了。这个组件库可能在做复杂后台的时候好用,但在做这种小应用,发挥创意的地方,我觉得还限制还是太多了。我觉得我们最开始应该选择使用有更高扩展性的组件库,比如前段时间看到的 Radix UI

从文档来看,Radix UI 会组件里面每个 DOM 都提前命名好相关的 ClassName,那么用户在想自定义样式的时候,就方便很多了。

Radix UI 组件库的截图。展示了 Alert Dialog 组件的代码,并且用带有圆角的绿色方框高亮了代码中的四处 className。

对比起 Ant Design,引用一个组件进来后,会生成巨多个没有打标记的 DOM。每个 DOM 的样式巨难选择,想要改组件内某个元素的样式,没有熟练的 CSS 选择器功夫还真搞不定。

但还是得具体试一试才知道 Radix UI 是不是真的好用,或许也会暗藏某些坑。或许我应该拿自己的个人网站来试一试 🤔。

改造弹窗:拖拽和操作

由于这是一个嵌入在网页当中的对话窗口,本着提高一个易用性的初心,我觉得需要对弹窗组件进行魔改,支持以下两种特点:

  • 支持拖拽:允许用户拖拽弹窗标题区域,改变弹窗的位置,以免挡住原本页面中的元素。
  • 移除遮罩:不展示弹窗背后的黑色遮罩,并且弹窗出现的时候,不影响用户操作原本的网页。

仅仅是改造弹窗这块,足足花了我一天。严重影响了我调试 Prompt 的时间,所以感觉很有必要把它记录下来,即便我的做法绝非最佳实践。

拖拽

拖拽这块我是用了一个名为 DragM 的开源库来实现了,因为看到示例里面效果很不错,所以直接用上了。效果确实也很不错,强烈推荐。

过程有点丢人,就不详细描述了。大概是我参照示例代码做到了弹窗能够实现拖拽,但弹窗的关闭按钮却失效了,后面还是得靠研发大佬来修复。

允许操作背景

这个特点的实现简直是噩梦。Ant Design 文档是提供了一个 API 是能够允许我们隐藏掉黑色的遮罩。

Ant Design Modal 组件的 API 截图。用带有圆角的绿色边框高亮 Ant Design Modal的 API。该 API 控制是否展示 Mask,默认是展示的。

但是这只是让我们看不见遮罩,打开弹窗时,原本页面的元素仍然是无法点击的。所以我试了一些方法,比如说将每一个疑似是遮罩的 DOM 设置为 display: none;,然而并不奏效。

最后生效的方法是用 CSS 选择器选中遮罩层,并将其调整为跟弹窗一样大。那么实际上遮罩还是存在的,但已经被修改为和弹窗一样大,并且叠在弹窗的后面,其实谁都感知不到这个透明遮罩的存在。

所以对于弹窗尺寸以外的部分,是没有被遮罩所覆盖的,自然能够正常响应鼠标操作。

这种做法无法适应弹窗高度会动态变化的情况,但我们这次设计的产品中,弹窗的宽高是固定的,所以即便做法比较不成熟,但确实是达到效果了。

结果

比赛最终有点遗憾,距离拿奖仅一步之遥。获得我们组目标奖项的是一个单人成组的高手。 很可惜的是我们就差一点点,因为最后颁奖的时候大佬也提到了我们的作品,说是如果能更好用一些,比如将生成的 SQL 语句自动填进输入框,或者自动应用然后直接生成图表,就有更大的机会获奖了🤦。

确实我们在演示的时候没有将这个这个产品最强大的功能发挥出来。因为本身产品也有些缺陷,限制了我们的演示范围。

最开始我们设想是演示的时候用自然语言多问几个问题,然后 AI 每次回复都很准确,凸显了自然语言生成 SQL 语句的便利性,而且还想演示输入了几个错别字,AI 仍然能够正确地识别我们的意图,回复正确的 SQL 语句。

但实际上我们最终的产品还是有一个明显的 BUG,在连续聊天时,消息队列不正常,AI有时候会回复我问的上上一个问题,而不是紧接着我的提问来进行回答。

这使得我们演示的时候只能问一个问题,简单带过,没有办法将自然语言带来的便捷性完全地展现出来,实属遗憾。

收获

虽然没能获奖,但参与这次公司内部的 AIGC Hackathon 比赛对我来说有三个特别重要的收获。

参赛经验

简单来说就是产品设计和功能开发的边界,需要根据演示需要来进行规划。

之前我在样式实现中花了太多时间(职业病🤦),比如输入框的聚焦效果,聊天气泡出现的动画,发送消息加载中的动画等等,而实际上在演示的时候,这些可能只展示了 1~2 秒,甚至更少。

因为这些内容大概率不会是评委所在意的东西,反而在过程中怎么调试 Prompt,调试过程中遇到什么挑战,怎么解决,怎么选择模型等等,显得团队很沉浸于与 AI 接口进行交互,通过这个项目积累了挺多经验,可能这些才是大佬们有兴趣了解的地方。

我应该早点完成产品界面还原,然后尽快投入到调试 Prompt 当中的。 如果之后再次参与类似的活动,我觉得我的所有工作都会围绕最后一天的演示来进行,其他东西能减就减。

首次参与代码 PR,并且与真正的研发同事合作

这次是我第一次将代码 PR 到其他成员的仓库当中,并且解决代码冲突,编写改动点,同步最新代码等等。这种团队协作的感觉,让作为设计师的我感觉很新鲜和奇妙。

而且各司其职,每个人都做出了超出自己以往经历的内容,然后每天短会同步下今天的进度、明天的工作内容。尤其是路演前一天晚上一起调试 Prompt,然后把最佳表现录屏,录屏中还出现了几次滑稽的意外...这种协作的经历让我感觉很充实,富有激情。

而且我每天都会遗留一两个事项给峰哥来解决,比如:

  • 我做完了一个表单填写框和提交按钮,我就告诉峰哥让他来做表单提交的功能;
  • 我做完了聊天气泡(由AI、用户、系统发出的消息)的三种样式,也是一样让峰哥来做相关的展示逻辑...

真正参与产品代码贡献对我来说是一直想去做的事情,因为我一直觉得如果能由做界面/交互设计的人,来亲手将其创作内容实现出来,是一件很酷的事情,也能够减少很多沟通成本。

参与到 AI 的浪潮之中

我最开始是在去年年底的时候,用 ChatGPT 来帮我解决我重构个人网站时的一些实现问题,中途因为好奇心驱使,也问了很多奇奇怪怪的问题。然后最近也在高频使用 ChatGPT,来作为我学习英语的助手。

而这次比赛不仅给了我一个机会去参与创造一个跟 AI 相关的产品(包括代码也有不少是 ChatGPT 参与的),还给了我推强大的动力去了解 AI 在商业中的场应用景。除了在比赛中看到其他参赛者的创意之外,现在还了解到比如 Atlassian 已经有相关的功能前瞻了。

从 Atlassian 在 5 月 4 日发布的股东信当中,也透露到该公司已经在用 AI 来来为客户提供服务了。

"Now that generative AI has reached consumer-grade maturity with LLMs, we can create magical new experiences for our customers."现在,随着大型语言模型(LLMs)带领生成型人工智能达到了消费级的成熟,我们可以为我们的客户创造魔术般的新体验。

除了 Atlassian,另一个互联网巨头:Shopify 也将 AI 能力应用到其产品当中。比如在商品详情页的编辑界面当中,我们可以输入几个关键字,让 AI 帮忙生成一段商品介绍的文本,还能够调整文本的风格。

Shopify 商品详情页 AI 功能截图。画面是一个卡片叠加在商家管理后台的商品详情页的富文本输入框上,该卡片左侧是一个纵向排列控件的配置面板,第一个是输入框,输入一些关于商品的关键字;第二个是调整文本风格的下拉菜单,第三个是额外的备注。然后右侧是由 AI 生成的文本,用淡紫色背景的文字来区分,并且提供赞和踩的反馈。卡片右下角是一个 Pointer 样式的鼠标指针,选停在保存按钮上方。

Shopify 将同样也是利用 LLM 来实现的生成文本能力,这被官方称为「Shopify Magic」。除了在商品详情页生成商品描述,也能在邮件当中根据活动类型或产品关键字生成邮件标题,或者在主题编辑器中根据要求来生成标题等等。

微软就不必多说了,也已经在 Microsoft 的办公软件上集成了很多 AI 功能。

代码仓库

这里放上我们产品的代码仓库吧,记录这段热血时光:

SQL-Helper · Github

最后,通过这次 AIGC Hackathon 活动,我真正参与到了产品的代码贡献,同时也看到了许多 AI 能力的应用场景。听说公司有产品在研究 AI 能力在业务中的应用,希望之后自己也有机会在商业项目上进行更多相关的实践吧!

近况

太久没发博客了,记录下我最近的状态吧。应该没有人想知道,但若干年后的我可能会想知道。

  1. 近沉迷于学习英文,所以会导致网站、博客的更新会比之前慢一些。
  2. 发现英文还挺有意思的,但在学生时代是看见英文就想睡觉。以前的我应该是比较喜欢数学和历史。
  3. 小目标是今年内能出一篇全英文的博客。全程用英文书写,然后在发布之前先给 ChatGPT 帮忙检查和润色一下。
  4. 个人网站 LRD.IM 正在开发支持切换语言至「英语」的功能。
  5. 有一个前端相关的分享会正在准备进行,是面向部门内产品、本地化运营和设计同事的。
  6. 在手机上开通了 ChatGPT Plus。直观感受是 GPT-4 的回答比 GPT-3.5 靠谱很多很多,应该会持续订阅。
  7. 正在尝试一种新的作息,再多体会一段时间后,可能也会在博客上记录。

Recover MySQL Database root password

By: Onlyone
13 December 2011 at 22:42
Recover MySQL Database root password




By default, MySQL Server will be installed with root superuser without any password. You can connect to MySQL server as root without requiring password or by keying in blank password. However, if you have set the password for root and forget or unable to recall the password, then you will need to reset the root password for MySQL.
Login as root to the Unix-like (Unix, Linux or BSD) machine with the MySQL server.
Stop the MySQL server by using either of the following command
#/etc/init.d/mysql stop
Now you need to Start MySQL server without password
mysqld_safe --skip-grant-tables &
Connect to mysql server using mysql client with the following command
# mysql -u root
Now you should be having mysql prompt
mysql>
Now you need to Setup new MySQL root user password
mysql> use mysql;
mysql> update user set password=PASSWORD(“newrootpassword”) where user=’root’;
mysql> flush privileges;
mysql> quit
Note: Replace newrootpassword with the new root password for MySQL server. Flush Privileges is needed to making the password change effect immediately.
Now you need to Stop MySQL Server using the following command
# /etc/init.d/mysql stop
Test Your New Mysql root password
First you need to start mysql server using the following command
# /etc/init.d/mysql start
# mysql -u root -p
Now it will prompt for root password and enter your new root password
❌
❌