来自 Rob Knight 的技术评论
2023 年无疑是大型语言模型(LLMs,Large Language Models)之年。
您使用的所有软件都是为了将特定类型的数据转换为其他特定类型的数据而设计的。
按下一个键,某个数字代码就会通过 BIOS、操作系统和应用程序代码向上报告,在这个过程中引发反应。
比如在屏幕上显示一个字符,或者选择一个菜单项,或者跳过一段音乐。
“屏幕上的字符”听起来很简单,但桌面应用程序中字符的表示却复杂得惊人:
- 字符可能存在于表示文本文档或数据库字段的较大数据结构中
- 屏幕上可见的字符可能位于特定的用户界面元素(如文本框)内
- UI 元素可能有特定的设置,比如字体大小和颜色
- 将这些设置转换为屏幕上的图形需要使用操作系统图形工具包
- 图形工具包需要通过低级图形库与显卡对话
- 低级图形库需要和显卡驱动
- 显卡驱动程序告诉显卡要设置哪些像素到哪些颜色
在这里简化并跳过了多个层次和子系统,它已经很复杂了。
要做到这一点,软件工程师需要保持一定程度的严谨性。
代码必须使用精确的数据结构,否则可能会引入错误。
应用程序、操作系统和驱动程序代码的每一层都必须非常精确地相互对话,以免整个系统崩溃。
因此,系统的大多数部分都是非常有选择性的,他们将谈论什么,他们将说什么。
网络应用程序也是如此,在线服务隐藏在狭窄的 API 之后,只允许某些其他 API 以某种方式与系统交互。
在软件工程学中,其中一个名称就是封装
即一个(子)系统应该是一个独立的单元,只要您按照它所需要的特定方式与它进行通信,它就可以保持完全可靠。
实际上,这很难。
每个模块都有自己的小世界模型,其中某些数据结构具有在其他地方可能没有的特定含义。
软件工程师有义务采用哲学家的思维方式,
在这种思维方式中,事物的意义是它们被定义为意义的东西,而不是它们在通常情况下的意义。
由于在即使是琐碎的应用程序中也有许多交互的软件片段,因此需要注意许多不同的概念模型。
有时候,我们会感到困惑。
在 RFC760中,定义了互联网协议,计算机与计算机通信的基础文件
一般来说,发送行为应该是保守的,接收行为应该是自由的。也就是说,它应该小心地发送格式良好的数据报,但是应该接受它可以解释的任何数据报。
这个叫 Postel's law ,来自 Jon Postel,对发送的内容保持谨慎,对接收的内容保持自由
这意味着软件工程师应该尝试对他们的系统进行编码,以接受来自他们必须与之通信的系统的某种程度的错误,
同时努力避免引入他们自己的错误。
在某些方面,这是一个很好的愿望,但它是有代价的。
如果你的系统在接受什么方面过于自由,那么它就根本没有有意义的标准;
如果其他系统开始依赖于接受畸形或混乱的数据,那么接收系统必须永远接受这些数据,
否则就会破坏依赖它的系统。
这使得维护工作变得非常复杂,
因为现在系统对于它的行为有了一个正式的标准,并且在接收到“错误的”数据时会显示一组非正式的行为。
在实践中,除了琐碎的案例之外,对你所接受的东西保持开放的态度是不可行的。
因此,我们的软件需要以非常具体和抽象的方式进行交流。
软件应用程序的“价值链”从一些数据(来自用户或网络)开始,
并通过一系列需要精确对齐才能工作的抽象转换继续进行。
所需的工程工作量很大,
因此大多数应用程序与其他应用程序通信的能力有限,即使它们都使用类似类型的数据也是如此。
这就是为什么大多数涉及大量计算机相互通信的方案都失败了。
对于计算机来说,要在语义和协议上达成一致,并容忍错误而不产生使错误本身成为协议一部分的副作用,
确实非常困难。
但是 GPT-3 的出现
当 GPT-3 存在时,关注结构化数据就像解决昨天的问题一样。Think sloppy.
GPT-3 意味着我们不必太担心如何构造数据,因为 GPT-3确实擅长将一种数据转换为另一种数据。
假设 Alice 有一些数据,而 Bob 有一个用于处理数据的 API,但 Alice 的数据与 Bob 的 API 不匹配。
解决这个问题的旧方法是像哲学家一样思考,
梳理出 Alice 数据的语义和 Bob API 的范式模型,然后在两者之间构建一个转换。
现在,我们可以让 GPT-3来帮我们。
Consider the following message:
-------
Dear Jane,
I am thinking about you when I am swinging through the jungle.
Greetings,
Tarzan
--------
Put this message in the following JSON structure
{
"sender": "..",
"message": "..",
"list_of_words": [
"..",
".."
]
"addressed": "..",
"amount_of_words": ..
}
SQL tables (and columns):
* Customers(customer_id, signup_date)
* Streaming(customer_id, video_id, watch_date, watch_minutes)
A well-written SQL query that lists customers who signed up during March 2020 and watched more than 50 hours of video in their first 30 days:
- [ChatGPT 生成与 API 交互的代码](https://kracekumar.com/post/chatgpt-gh-profile-lookup/)
Can you write a ruby program to check a a list of profile names exists in github?
这些是两个系统之间交互的构建模块,如果提示正确,LLM 可以在几秒钟内根据需要生成它们。
这是一种完全不同的解决问题的方式。
LLM 不是哲学家。
他们并不真正关心语义或抽象数据模型。
他们知道如何做一些事情,你可以要求他们去做。
LLM 是骗子。
如果你想得到一些从 A 到 B 的数据,骗子会比哲学家更快完成,而且大多数时候质量没有损失。
软件集成项目将变得更加容易。
可以由 LLM 生成转换层,它是让我们将两个系统粘合在一起的粘合代码。
单个组件可以打破 Postel 定律,在它们所接受的内容上变得更加保守,对标准更加严格,
因为处理必要数据转换的认知负荷可以外包给 LLM,而不是程序员。
我们可以把应用程序之间的通信看作是一种交易,而特定交易的能力则是一个匹配问题。
匹配理论描述了“随着时间的推移形成互利关系”,通常涉及人与人之间的经济关系,
但这一原则也适用于计算机系统之间的关系。
匹配不仅关系到雇员的技能和雇主的薪水,还关系到他们是否能找到对方,地理、语言、社交网络等等的影响。
如果有一份工作空缺,而且有人愿意并且有能力做这份工作,但是这个人仍然失业,空缺没有填补,
那么这就归因于就业市场的“摩擦”ーー肯定有什么东西阻碍了这个人接受这份工作。
尽管我们尽了最大的努力,计算机之间的交流还是有很多摩擦。
同一台计算机的不同部分之间的通信,甚至同一个应用程序内部的通信,经常会有摩擦!
我们可能在这里有一些数据,在那里有一个 API,只需要一点努力,我们就可以让这两个互相交流。
**但是哲学家并不急于求成,所以我们目前的应用程序无法做到这一点。**
**在与市场的类比中,LLM 是将供给来源与需求来源相匹配的企业家:**
一些系统需要进行某种计算,而另一些系统只要输入正确的数据,就能够进行这种计算。
创业型 LLM 转换数据,并编写代码来调用可以进行计算的系统的 API。
API 市场目前已经存在,但是由于与新 API 交互的边际成本很高,因此利用率很低。
即使我们想要的是合理的,数据格式、 API 模式和网络协议的精细细节也会妨碍我们。
有了正确的框架,LLM 可以帮助我们实现过去几十年我们一直想象的协作软件应用程序网络的目标。
**推荐**
- [**LLMs are hustlers**](https://robknight.org.uk/notes/llms-are-hustlers/)
