TS之父的新项目Typechat预示着前端的未来

开发 前端 人工智能
大家都知道AIGC(Artificial Intelligence Generated Content,生成式人工智能)会改变行业现状,但不知道改变的方式是「取代工程师」还是「帮助工程师」?最近,TypeChat的发布让前端未来的发展方向变得更清晰 —— 在不远的未来,AIGC将会是工程师得力的助手,而不是取代工程师。

大家好,我卡颂。

最近两年,整个前端圈都比较焦虑,主要有两个原因:

  1. 经济下行造成工作不好找
  2. AIGC对行业未来的冲击

其中第一条大环境如此,没什么可抱怨的。第二条的焦虑则更多是「对未知的恐惧造成的」。

换言之,大家都知道AIGC(Artificial Intelligence Generated Content,生成式人工智能)会改变行业现状,但不知道改变的方式是「取代工程师」还是「帮助工程师」?

最近,TypeChat[1]的发布让前端未来的发展方向变得更清晰 —— 在不远的未来,AIGC将会是工程师得力的助手,而不是取代工程师。

为什么这么说呢?本文会从以下角度阐述:

  • 当前LLM(large language model,大语言模型)的问题
  • TypeChat是什么,他是如何解决上述问题的
  • TypeChat的实现原理
  • TypeChat对前端行业的影响

LLM的问题

LLM应用最广、普及度最高的应用场景是「聊天助手」(比如chatGPT)。

「聊天助手」场景的特点是:用户输入自然语言,模型输出自然语言。

自然语言对话

如果模型仅能输出自然语言,那他的应用场景只能局限在「聊天助手」。毕竟,「自然语言」只能作为LLM的输入,没法作为其他应用的输入。

比如,我希望做一个舆情监控应用,周期性爬取全网关于某明星的言论,再分析言论的情绪是否正向,最终统计全网对该明星的整体评价。应用实现思路是:

  1. 全网爬取言论数据
  2. 分析每一条言论数据,输出「情绪是否正向」的判断
  3. 统计所有言论对应的情绪
  4. 分析结果

其中第二步,我们可以让LLM判断输入的言论情绪是否正向。

当输入「鸡哥辛苦训练了两年半」,LLM判断这段话的情绪是正向后,可能回复我:

  • 这段话的情绪是正向的
  • 结果是积极的
  • 这是一段积极的对话
  • ...或者其他啰嗦的回答

虽然上述结果都表达了「情绪是正向的」,但输出结果也是自然语言描述的,且结果句式并不稳定,没法输出给第三步的程序做统计。

好在,LLM也可以输出结构化数据(比如JSON)或者代码,其中:

  • 如果能输出符合其他应用规范的JSON,其他应用可以直接读取使用
  • 如果能输出符合其他应用的代码调用,可以直接调用其他程序(通过RPC通信)

比如,我们让LLM对上述问题输出JSON格式的结果,可能的输出如下:

// 可能的结果
{"result": "positive"}

// 可能的结果
{"emotion": "positive"}

// 可能的结果
{"sentiment": "good"}

虽然程序可以读取JSON,但输出的字段可能是不稳定的。假设第三步的统计程序统计的是result字段,但我们第二步输出的结果是sentiment(情绪的意思)字段,这就没法使用了。

为了解决「用户输入自然语言,LLM输出稳定的结构化数据或函数调用」的问题,openAI推出了一个新功能 —— function-calling[2](即函数调用)。

当我们调用openAI API时,参数依次传入:

  • 用自然语言描述的需求
  • 对输出结果函数的类型定义

LLM会输出符合类型定义的函数调用。

比如,我们依次输入:

  • 需求:判断「鸡哥辛苦训练了两年半」情绪是否正向
  • 函数定义:
{
  "name": "mark_sentiment",
  "description": "标记输入语句的情绪是否正向",
  "parameters": {
    "type": "object",
    "properties": {
    "prompt": {
      "type": "string"
    },
    "sentiment": {
      "type": "string",
      "enum": ["negative", "neutral", "positive"]
    }
  }
}

LLM的输出结果为:

mark_sentiment({
  prompt: "鸡哥辛苦训练了两年半",
  sentiment: "positive"
})

只需要定义mark_sentiment方法,用于存储「言论对应的情绪」即可。

function-calling功能极大扩展了LLM的应用场景(chatGPT的插件功能就是通过function-calling实现的):

但是,function-calling同样存在缺点,比如:

  • 只受限于openAI的模型,其他模型(比如Llama 2)没有该功能
  • LLM的响应只有一个函数调用,无法在一次响应中调用多个函数
  • 函数的类型声明对开发者不够友好,内部实现比较黑盒,当返回的函数调用不符合预期时,不好纠错

TypeChat的出现解决了上述问题。

TypeChat是什么,有什么用

在聊function-calling缺点时,我们提到「函数的类型声明对开发者不够友好」,那么什么类型系统对前端开发来说是最熟悉、友好的呢?

答案不言而喻 —— TypeScript。

TypeChat[3]是TypeScript之父「Anders Hejlsberg」(同时也是C#之父)发布的新项目,他可以根据:

  1. 自然语言描述的提示词
  2. 对输出产物类别的定义(是「表示数据的JSON」,还是「表示函数执行的JSON」)
  3. 对输出产物的TS类型声明

让LLM输出符合类型声明的JSON数据。

比如,对于上述「判断言论情绪」的例子,可以向TypeChat输入:

  1. 需求:判断「鸡哥辛苦训练了两年半」情绪是否正向
  2. 输出产物是「表示数据的JSON」
  3. 输出产物的TS类型文件如下:
// 下面是对用户输入情绪的类型定义
export interface SentimentResponse {
    // 情绪的可选项
    sentiment: "negative" | "neutral" | "positive";  
}

LLM输出的结果会被严格限制在上述TS类型。

如果要简单的类比,可以认为TypeChat是使用TS定义类型的function-calling。但实际上,TypeChat的能力不止如此。

首先,TypeChat不和任何LLM绑定,只要能同时理解自然语言与编程语言的LLM都可以使用TypeChat。

其次,输出产物是JSON,JSON除了可以表示数据,还能表示多个函数的执行过程,这样LLM的一次输出可以是多个函数的连续执行。

举个例子,下面是我们的输入:

  1. 需求:计算如下算式:「1 + 2的结果乘以3,再除以2」
  2. 输出产物是「表示函数执行的JSON」
  3. 输出产物的TS类型文件如下:
// 下面是对四则运算的类型定义
export type API = {
    // 两个数字相加
    add(x: number, y: number): number;
    // 两个数字相减
    sub(x: number, y: number): number;
    // 两个数字相乘
    mul(x: number, y: number): number;
    // 两个数字相除
    div(x: number, y: number): number;
    // 对一个数字求负数
    neg(x: number): number;
    // id
    id(x: number): number;
    // 未知情况
    unknown(text: string): number;
}

LLM输出结果为「由JSON表示的函数执行过程」:

{
  "@steps": [
    {
      "@func": "mul",
      "@args": [
        {
          "@func": "add",
          "@args": [1, 2]
        },
        3
      ]
    },
    {
      "@func": "div",
      "@args": [
        {
          "@ref": 0
        },
        2
      ]
    }
  ]
}

其中@XXX是TypeChat中的关键词,比如:

  • @step代表执行步骤,每个index对应一个步骤。
  • @func代表这是个函数执行。
  • @args代表函数的传参。
  • @ref代表引用某个步骤的执行结果。

经由TypeChat内部转换后,得到如下代码:

import { API } from "./schema";
function program(api: API) {
  const step1 = api.mul(api.add(1, 2), 3);
  return api.div(step1, 2);
}

也就是说,我们告诉TypeChat下述信息后:

  • 我们希望计算:「1 + 2的结果乘以3,再除以2」
  • 输出结果要表示为「函数执行」
  • 每个执行的函数要符合我们定义的TS类型

TypeChat输出的结果为:

import { API } from "./schema";
function program(api: API) {
  const step1 = api.mul(api.add(1, 2), 3);
  return api.div(step1, 2);
}

并且,这个结果是稳定的(即使多次执行,输出结果的函数名、类型定义都不会变)。

除了上述功能外,TypeChat最大的亮点在于 —— 他能够对输出结果自动纠错。

因为我们有「输出结果的TS类型声明」,所以可以用TS编译器检查输出结果是否符合类型声明,如果不符合,TypeChat可以将「TS报错信息」连同「输出结果」再次输入给LLM,让他纠错后重新输出。

比如,对于上述「检查言论情绪」的例子,如果输出结果为:

{sentiment: "good"}

经由TS编译器检查后会报错:

Type '"good"' is not assignable to type '"negative" | "neutral" | "positive"'.

TypeChat会将上述报错信息连同输出结果再输入给LLM让他纠错。

TypeChat实现原理

TypeChat的实现原理可以用一张图概括:

其中:

  • 红色路径输出结果为「表示数据的JSON」
  • 蓝色路径输出结果为「可执行的代码」

对于红色路径,以上述「检查言论情绪」为例,TypeChat输入给LLM的提示词类似这样:

你是个将用户输入转换为JSON的系统,转换需要遵循下面的TS类型声明:
${输出产物TS类型声明}

下面是用户的输入:
${"鸡哥辛苦训练了两年半"}

下面是用户输入转换为JSON后的结果:

LLM接收以上提示词后输出JSON。

对于蓝色路径,以上述「四则运算」为例,TypeChat输入给LLM的提示词类似这样:

你是个转换系统,将用户输入转换为由JSON表示的程序,转换需要遵循下面的TS类型声明:
${对@step、@ref、@func等如何使用的类型声明}

程序可以执行由下面的TS类型定义的函数:
${输出产物TS类型声明}

下面是用户输入转换为JSON后的结果:

LLM接收以上提示词后输出代表程序执行的JSON,该JSON再经由TypeChat转换后变为「可执行的代码」。

对输出产物的纠错

如果LLM返回的JSON有TS类型错误,那么TypeChat会拼接出下面的提示词,并输入给LLM:

${报错的JSON数据}

上述JSON对象由于下述原因导致他是非法的:
${TS报错信息}

下面是修正后的JSON:

TypeChat对前端行业的影响

不止是前端工程师,当前程序员使用LLM的主要方式还是:

  1. 用自然语言描述一段代码需求
  2. LLM输出代码
  3. 程序员修改输出的代码,为项目所用

而业界预期的LLM终极形态是:产品经理用自然语言描述产品需求,LLM直接写代码。

如果达到这种程度,程序员就完全没有存在价值了,这也是大部分程序员焦虑的原因。

那么,制约「达到终极形态」的因素有哪些呢?有三点:

  1. LLM对「自然语言描述的需求」的理解能力
  2. LLM一次处理的提示词长度(token数量限制)
  3. LLM生成代码的稳定性

对于第一点,当GPT-3.5出现后,好像LLM的理解能力突然上了好几个台阶。所以,大家会焦虑是不是再过几年,LLM的理解能力突然又爆发性提高,能够完全理解自然语言描述的需求。

对于第二点,GPT-3.5有「最多4096token」的限制,但这一限制正在逐步放宽。这意味着在不远的将来,LLM能够输出的代码量会越来越多。

正是预见到以上两个因素的变化趋势,导致程序员产生「假以时日,会被AIGC取代」的焦虑。

但我们发现,要达到终极形态,还要考虑第三个因素 —— LLM生成代码的稳定性。

也就是说,LLM虽然可以帮我们编写函数代码、模块代码,但如果这些函数、模块的代码是不稳定的,他们就没法配合使用,需要工程师手动修改。

如果LLM生成的代码经常需要工程师手动修改,那就限制了「它能够自动生成代码的规模」,那么他只能沦为工程师的编程助手,而不是取代工程师。

而要解决「生成代码的稳定性」问题,不管是通过openAI的function calling,还是TypeChat,都需要工程师能够对产物做出精准的类型定义。

这就形成了一个悖论 —— AIGC要想取代工程师独立完成项目,需要能生成稳定的代码。而为了生成稳定的代码,需要工程师理解业务逻辑后,编写详尽的类型声明。

为了取代工程师,还需要工程师积极参与?那取代个der。

这顶多算是一种编程范式的迁移,类似之前前端用jQuery开发页面,后来迁移到用前端框架开发页面。

未来,前端工程师编写详尽的类型声明,LLM再根据声明生成框架代码。就像现在前端通过框架编写「状态变化逻辑」,框架再去执行具体的DOM操作一样。

总结

有些同学会焦虑 —— 未来是AIGC的天下,我要不要转行搞人工智能?

实际上,通过本文,我们能感受到一种趋势,未来将会分化出三种工程师:

  1. 搞AIGC算法研究的工程师

这类工程师人数很少,都在头部互联网企业或人工智能企业的实验室中。

  1. 负责公司AIGC基建的工程师

这类工程师负责将上一类工程师的产出与公司业务结合,他们的工作职责包括:

  • 评估、部署各种开源模型
  • 会使用各种工具,比如langChain、Pincecone,当然也包括本文介绍的TypeChat
  • 根据公司业务场景,落地AI基建
  1. 业务工程师

比如前端工程师、后端工程师、全栈工程师。他们会在AIGC基建工程师开发的基建上,进行业务开发。

前端这个岗位会持续存在,只是要求会更高(对业务的抽象能力)、从业者会更少。

可以简单的做个比喻,如果你当前小组的构成是:

  • 一个对业务更理解的前端组长
  • 几个负责业务开发的中级前端

那么未来的构成会是:

  • 一个理解业务的高级前端(可能是之前的前端组长),负责对业务进行抽象
  • 编写具体业务逻辑的AIGC基建

参考资料

[1]TypeChat:https://microsoft.github.io/TypeChat/。

[2]function-calling:https://openai.com/blog/function-calling-and-other-api-updates。

[3]TypeChat:https://microsoft.github.io/TypeChat/。

责任编辑:姜华 来源: 魔术师卡颂
相关推荐

2019-07-29 11:25:57

2023-07-24 13:29:09

TypeChatAI开源

2018-12-20 10:50:47

区块链数字货币比特币

2019-10-15 11:33:19

云计算Kubernetes互联网

2016-11-10 10:07:28

新项目前端流程

2023-09-13 11:04:25

机器人人工智能

2020-01-20 10:10:03

互联网架构

2021-06-29 15:29:33

人工智能合成数据

2014-11-03 14:55:48

AndroidGoogleAndy Rubin

2013-11-25 17:49:20

HPC微异构系统

2023-02-20 08:41:08

SignaluseState()

2022-03-09 17:37:55

前端架构微前端

2010-03-16 15:46:23

核心交换机

2020-09-21 10:16:44

智能

2012-11-07 13:31:53

Hadoop大数据

2021-05-26 09:13:35

Linux之父未来科技

2009-12-22 03:05:03

面向对象之父Alan Kaysmalltalk

2014-11-03 10:20:49

2020-07-29 10:32:10

人工智能AI疫情

2013-04-16 08:32:10

云计算公有云混合云
点赞
收藏

51CTO技术栈公众号