05|使用LLM应用和提取不可言说知识

你好,我是徐昊,今天我们来继续学习 AI 时代的软件工程。

上节课,我们通过将 LLM 看作一个迁移学习平台,理解了在提示词中上下文和任务的不同作用,并利用这个特性,构造了基于 LLM 的知识提取与应用的流程:通过聚焦在上下文,使用不同的问题反馈以提取知识,再将提取的知识与具体的任务结合,完成知识的应用过程。

这样的流程对于显式知识,或是隐式知识都有极高的提取和传递效率。但是对于知识过程中的核心——不可言说知识要怎么处理呢?这就是我们今天要讨论的问题。

在前面的课程中,我们已经知道,不可言说知识的应用会产生清晰(Clear)和庞杂(Complicated)认知模式,而不可言说知识的学习会产生复杂(Complex)认知模式。不同的认知行为模式具有不同的认知行为,因而与 LLM 交互的模式也就不尽相同。不同的交互模式,是我们处理不可言说知识应用和学习的关键。

与 LLM 交互的模式

由于 LLM 的回答具有不确定性,我们与 LLM 的默认交互模式是复杂认知模式,它的表现是:

  • 探测(Probe): 我们向 LLM 提出问题或者任务,LLM 帮助我们执行这个任务,并产生了初始结果;

  • 感知(Sense): 我们依照 LLM 返回的结果,思考哪些地方是我们不满意的,或者需要进一步了解的。然后我们提出新的问题,或者是重新调整初始问题;

  • 响应(Respond): 通过不同的问题调整,最终拿到满意的结果。

那是不是说 LLM 只能在复杂模式下发挥作用呢?当然不是。这完全取决于我们给予 LLM 的任务是什么,以及要拿到的结果是什么。比如,我们可以给予 LLM 一个非常明确的任务:

在数据库中存在
-表departments,字段为[DepartmentId, DepartmentName], 
-表students,字段为[DepartmentId, StudentId, StudentName]
请为"查找所有计算机学院的学生"生成MySQL的查询语句

这个时候如果我希望 LLM 改写这个 SQL 的一些细节,比如不要带表名之类的,我们会再次向 LLM 提问或修改描述。此时,我们并不是真的处在复杂模式,我们对于要做的修改有清晰的认识,所以我们处在清晰的认知模式中。而交互上表现为复杂模式,只是为了应对 LLM 的不确定性。

因而,当我们讨论 LLM 的交互模式时,需要区分哪些是应对 LLM 不确定性的,哪些是我们认知行为的体现。

清晰模式下的 LLM 交互模式

处在清晰模式时,认知行为表现为:感知(sense)- 归类(categorize)- 响应(Respond)。感知就是对于问题的定义,也就是对于知识的提取。你可以使用已经提取好的知识,或者通过上节课学过的流程,先进行知识提取。

归类是对于任务的选择,也就是根据任务选择不同的提示词模版。假设我们要进行的任务有生成 API 接口、生成功能测试、生成功能代码、编写文档。那么,我们需要根据不同的任务选择不同的提示词模板。

由于 ChatGPT 本身是不支持模板的。下面的例子,我们以 LangChain 的提示词模板为例,其他框架也都大同小异。比如,生成 API 的模板就是:


需求背景
=======
{requirements}
API要求
=====
API返回的结果是json格式;
当查找的SKU不存在时,返回404;
按关键搜索功能使用POST而不是GET;
任务
===
按照API要求为需求设计RESTful API接口。使用RAML描述。

我们只需要将提取到的知识填入模版中,就可以交由 LLM 负责最后响应的动作了。然后,我们可以根据 LLM 给出的结果,给予 LLM 反馈,最终改进结果。

由于处在清晰模式时,对于要处理的问题和解决方案都有明确的认知,我们与 LLM 交互模式就是通过指导性提示词(Instruction Prompting)充分详细地描述要处理任务的上下文和对于任务的要求,让 LLM 负责生成最后的结果。

除了直接套用模板执行任务之外,我们也可以通过链(Chains)建立复杂的任务。

比如上面的例子里,我们要实现 RESTful API,通常会先设计 API,然后根据设计好的 API 完成测试和功能的开发。那么我们可以通过将前面生成 API 的模板和下面编写功能的模板串联为一个链,去完成代码的生成:

需求背景
=======
{requirements}
API
===
{API}
要求
===
使用Java实现
任务
===
按照要求,根据需求实现API中提及的RESTful API

同样,虽然 ChatGPT 本身不支持链,但我们通过 LangChain 的 LCEL 很容易就能完成对两个模板的串联,在其他类似的框架里也有相应的支持。

庞杂模式下的 LLM 交互模式

处在庞杂模式时,认知行为表现为:感知(sense)- 分析(analysis)- 响应(Respond)。与清晰模式的差别在于对于解决方案的寻找,是直接分类还是通过分析筛选。

而在与 LLM 交互时,与清晰模式相比就有很大的差别。在清晰模式时,我们已经明确知道要让 LLM 进行的响应是什么了,关注点在于如何挑选合适的任务,以及如何补充或反馈与任务相关的细节,得到更好的结果。

处在庞杂模式下的时候,我们并不知道具体的任务有哪些,分别是什么。这时候我们可以使用知识生成(Generated Knowledge)让 LLM 帮助我们分析要处理的问题。

所谓知识生成,是指先抛开最终的诉求,让 LLM 先生成一些关于最终诉求的知识。这些知识可能以事实信息、规则或是示例的形式出现。这些生成的知识随后会在 LLM 执行任务时作为补充输入提供给 LLM。比如,我们想让 LLM 去编写代码,那么就可以先让 LLM 根据要解决的问题,生成一个求解思路,然后再要求 LLM 按照这个思路完成编码。这样的过程就是知识生成。

而处在庞杂模式下,最有用的知识生成就是生成任务列表。因为任务列表本来就是分析的结果,是思路的体现。对于任务列表达成一致,就是思路的对齐。而一旦我们明确了需要 LLM 进行的任务,那么就进入了清晰模式。

任务列表的生成可以通过思维链(Chain of Thought,CoT)的方式来实现。CoT 是一种鼓励 LLM 解释其推理过程的方法。具体做法是向模型陈述推理过程。然后,要求 LLM 也要遵循类似的推理过程。

比如,我们可以使用下面这个提示词模板,在提示词中明确给出了任务划分的依据和要求:

需求背景
=======
{requirements}
API
===
{API}
要求
===
1. 使用JAX-RS框架实现API接口
2. 对于数据库的访问通过repository接口
3. 针对每一个领域对象,构造representation model表示其返回的json数据
4. 在API接口中,通过repository访问数据库,并将数据转化为对应的representation model
5. 划分任务时,按照repository,representation model和API的顺序梳理任务
任务
===
现在我们要按照要求,根据需求实现API中提及的RESTful API。
请先生成任务列表。

对于返回的结果,你可以着重看一下 LLM 这次返回的时候,生成的样式和里面的任务,以及和前面的符合度是怎样的。

由于处在庞杂模式时,对于要处理的问题有明确的认知,但是解决方案依赖于我们分析的结果。我们与 LLM 交互模式是借助通过思维链(或类似的技术)指导知识生成,明确 LLM 将要进行的工作。当我们与 LLM 就将要进行的任务达成一致,就可以按照这个共识,让 LLM 负责生成最后的结果。

复杂模式下的 LLM 交互模式

与庞杂模式不同,在处在复杂模式时,我们对于要解决的问题甚至没有完整的思路。因而,响应并不是这个模式下主要要考虑的问题,获取思路才是重点。

在前面庞杂的例子里,如果我们没有思路,就无法通过 CoT 指导 LLM 生成知识。那么也可以通过默认交互模式,围绕解决的思路与 LLM 交互。比如将前面例子中的 CoT 部分去掉:

需求背景
=======
{requirements}
API
===
{API}
要求
===
任务
===
现在我们要按照要求,根据需求实现API中提及的RESTful API。
请先生成任务列表。

这时候 LLM 的返回结果也变得很有意思:

对比这个结果和庞杂模式下的结果,就会发现复杂模式下还需要进一步的迭代与反馈,才能达到可用的状态。这很形象地表现了未被充分学习和已经被充分学习的不可言说知识在 LLM 上的差别,也就是说能够转化为 CoT(或类似技术)的,就是已经被充分学习了的不可言说知识。因而,不可言说知识的提取就是提取 CoT 的过程。

在上面的例子里,我们会发现,影响任务拆分效果的不可言说知识,是关于架构的知识。因而,我们可以在与 LLM 反馈学习的过程中,补充架构相关的知识,以提高任务列表的质量。

除了通过反馈学习提取不可言说知识之外,发现并学习已经被提取出来的不可言说知识,也是复杂模式下一种重要的行为模式。目前比较流行的方式是使用检索增强生成(Retrieval Augmented Generated, RAG)。

RAG 架构

在 RAG 架构下,我们提出的问题并不会被直接处理,而是根据提问的问题,首先从知识库中检索相关的片段,再将对应片段综合,生成最终的 prompt,提供给 LLM 进行回答。它包含根据问题检索、依据结果增强以及增强之后生成三个部分,因此而得名。

在检索的基础上,我们可以通过提问进行互动学习,这是不可言说知识传递的重要模式。比如,要求 LLM 根据已经存在的不可言说知识,解释拆分的原因:

....
任务
===
现在我们要按照要求,根据需求实现API中提及的RESTful API。
请先生成任务列表,并解释为什么这么拆分。

小结

今天我们介绍了在不同的认知行为模式下,与 LLM 不同的交互模式。

在不可言说知识应用的过程中,我们可以通过提示词模版建模任务和流程,来应用显式知识和充分学习的不可言说知识;通过已经提取完成的思维链,指导知识生成、产生任务列表,以消费不可言说知识。

对于不可言说知识的提取,我们可以使用知识提取流程,围绕思维链进行反馈提取。

另外,我们还可以在 LLM 辅助下,学习不可言说知识。

思考题

对于提取的知识,怎么样的传递是最有效率的?

欢迎在留言区分享你的想法,我会让编辑置顶一些优质回答供大家学习讨论。