前言
自 ChatGPT 上线以来,传统互联网行业受到了巨大的冲击,而这冲击也不止体现在大厂的模型竞赛、创业赛道和投资方向的集中化、新岗位的涌现和旧岗位的没落等等可见的变化,更体现在每个互联网从业者动荡的内心上。有人觉得 AGI(通用人工智能)马上就要实现了,机器统治人类的时代不远了;有人觉得软件行业快走到头了,人和机器马上可以用自然语言交流,不需要程序员做中间商赚差价了;当然也有人觉得这一切还很遥远,按部就班干好手头的事情就好。
本文不会过多讨论意识形态的问题,也不想贩卖焦虑。作为一个程序员,面对颠覆性的新技术,我们应该去了解它的各种实践场景和理论知识,这个过程本身就很有意思(说实话前端圈这些年来来回回折腾的东西早已令人厌倦了),更别说要预测新技术的走向以及它会带来的影响,本就需要建立在对它的现状和历史的深入理解之上,而不是盲目听信营销号们添油加醋的宣传,跟着各大 KOL 们人云亦云。
从本文开始,我会把自己的学习过程记录下来,中间会夹杂很多个人观点,私货满满,欢迎批判。
使用 LLM(大语言模型)的一些方法
Prompt Engineering
Prompt Engineering(提示工程)最开始应该是训练 LLM 的一种模式(后面讲 Fine-tuning 的时候会提到),但这里特指它在 LLM 使用场景下的应用。它最基础的模式,就是通过自然语言直接和 LLM 进行交流,获得反馈的过程,更进一步地,我们将这个过程『工程化』,就是所谓的提示工程了。这个工程化主要体现在两个层面:
- 通过一些特殊的提示技术(few-shot/CoT 等)提升 LLM 生成内容的准确性
- 一定程度上将提示词视为代码,通过模板、模块等常用于代码工程的方式来生产和维护提示词
第一个层面是目前对 Prompt Engineering 的普遍理解,第二个层面算是我额外加上的个人理解。在提示技术层面,其实有两个重要的原则:
- 清晰具体
- 给模型思考的时间
第一个原则可以衍生出一些技巧和模式,譬如指定角色和任务,提供一些示例(即 few-shot) :
const messages = [
{ role: 'system', content: 'You are a assistant of lowcode platform, you can translate react component to json schema.' },
{ role: 'user', content: input }, // input 是示例组件
{ role: 'assistant', content: output }, // output 是示例 schema
{ role: 'user', content: code } // code 是待转换的组件
]
上面这个结构也是调用 OpenAI Chat Completion 接口的标准格式。但总得来说这个原则更多地还是考验『提问的艺术』,如果你在现实中很擅长提问,那大概率也能很好地应用这一原则跟 LLM 交流。
第二个原则就涉及一些具体的模式了,譬如 CoT(思维链)提出,面对一个复杂问题(譬如复杂数学题),如果你直接提问,模型可能会答错,但你只需要在问题后面加一句『Let’s think step by step』,模型就会把这个问题的推理过程都一步步列出来,从而得出一个正确的答案。你还有很多方法可以让模型『慢』下来,譬如人为地拆解任务,或者让模型自己拆解任务,拆成一个树结构,然后自底向上完成任务,等等。《思考,快与慢》中提出了『系统1』、『系统2』的说法,认为我们使用系统1,直觉性地快速完成大部分日常活动,而面对复杂情况,需要刻意保持专注,慢下来,使用系统2去努力完成任务。类比到大模型也差不多,模型偏向于使用系统1完成任务,哪怕会得出错误的结果(人在凭直觉决策时也经常出错),这时候就需要利用提示技巧,让模型慢下来,使用系统2来完成任务。
以上提到的提示技巧如果大家感兴趣的话,可以去 Prompt Engineering Guide 详细了解。吴恩达也联合 OpenAI 的成员做了几个相关课程,大家可以自行学习。
说完第一层面的理解,再稍微聊下第二层面的 Prompt Engineering——像管理代码一样管理 Prompt。这其中的典型代表应该要算当前最流行的 LLM 框架 LangChain 了(今年 3 月获得 1000 万美元种子轮融资,OpenAI 的官方 Demo 库中有使用 LangChain 的示例,创始人和吴恩达一起出了课程……)。它最基本的作用就是将人与 LLM 的沟通过程模块化了,它提供了很多 Component 来完成特定功能——LLM 连接、Prompt 模版、数据导入、数据存储、内存管理、结果格式化等等,将这些 Component 组合起来完成一个特定任务,就需要用到 Chain。当然它还提供了 Agent 的概念,让 LLM 可以和外界环境交互,调用外部 API 来完成更复杂的任务,下面再展开讲这部分内容。
Function calling
Function calling 是 OpenAI 新开放的接口,功能效果上跟 ChatGPT 的 Plugin、 LangChain 的 Agent 类似,都是提供一些 API(可以是函数、三方接口等) 的名字和描述给 LLM,然后让 LLM 接收自然语言的输入,由 LLM 来选择调用什么 API 解决用户的问题,并且会根据函数的参数类型将用户的输入转换成相应的格式。
这个功能算是锦上添花,之前通过 Prompt Engineering 也能实现(LangChain 就是这么做的)。但这背后的思想其实很厉害,它意味着可以将 LLM 完全整合进我们原有的开发模式中,我们通过代码提供能力,由 LLM 来做决策和编排。个人认为这应该会成为很长一段时间内工业界使用 LLM 的标准姿势,因为 LLM 虽然在通往 AGI 的路上,但在现阶段还是有很多任务不能执行得很好(尤其是公司内部任务),但它能识别自然语言,它也能使用工具(人类相比动物最大的优势?),那我们给它提供这些工具就行了,它就可以帮我们的用户解决实际的问题。
再稍微深入一点来看,LLM 在当下更多地是一种人机交互的新模式。从命令行到 GUI 的变革,孕育了苹果、微软这样的巨头公司,也催生了客户端工程师、Web 前端工程师这样的新岗位。我们前端工程师,有时候自称人机交互工程师,说白了就是画画网页 UI,然后让用户可以通过 UI 获取信息、表达诉求,然后我们调用后端 API 来响应用户的诉求。现在我们可能正处在 GUI -> LLM 的过渡期,公司内部的系统、特定的业务逻辑,不见得能很快被 AI 取代,但前端呢?客户端呢?
『人机交互工程师』这个岗位不会消失,但工作内容可能就不是像现在这样画 UI、调接口了,而是微调一个 LLM,帮它整理一些 API,替它做一些上下文管理以及 Prompt Engineering 的事情。当然常规的网页、APP 也不会消失,只是它们在很多场景中可能会被渐渐弱化,就像当初移动互联网大潮的时候,很多大厂的 PC 网站都不提供完整的功能了,而是引导用户去下载 App。
最后
这篇文章算是个入坑的引子吧,感谢 AIGC,让我对技术又重拾了兴趣,也有了写博客的动力。下一篇应该会聊一些 Fine-tuning 相关的东西,更偏实践一些,欢迎一起探讨。文中提到的链接整理如下: