Skip to content

Commit

Permalink
add more structures
Browse files Browse the repository at this point in the history
  • Loading branch information
wj-Mcat committed Jul 4, 2024
1 parent bf7fb1d commit 10ea303
Show file tree
Hide file tree
Showing 22 changed files with 416 additions and 2 deletions.
13 changes: 12 additions & 1 deletion docs/00-agent-intro/00-what-is-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,15 @@ Agent 中的记忆也是一样的,如果要完成一个复杂的任务,通

当然,还有 Tree of Thought 可以对每个子问题进行递归拆分,直到问题被完全解决。

TODO(wj-Mcat): doing
相关的方法介绍如下所示:

![agent planning](./imgs/agent-planning-methods.png)

> 图片来源于:[A Survey on Large Language Model based Autonomous
Agents](https://arxiv.org/pdf/2308.11432)

### 任务反思

一旦任务被拆分出来,此时需要判断:拆分之后的任务是否合理,能否解决问题。所以任务拆分是否正确此时至关重要,能进一步提升任务执行的准确度,这个阶段就称之为任务反思。

任务反思可以用LLM来进行反思,此时你可以写一套Prompt。
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions docs/02-prompt-engineering/01-in-context-learning/00-intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
slug: intro
title: Introduction
---

# In-Context Learning

## 什么是 In-Context Learning

简单来说,就是提供具备一定信息量的上下文,让模型能够精准的学习关键知识,遵循相关指令。。

确切来说,就是编写具备一定引导性的Instruction、提供高质量的Examples、提供足够的外部知识提升大模型在目标任务上的能力。而这一切过程都没有模型的参数更新,仅仅是通过调整Prompt的内容即可完成。

:::tip 其实 Prompt Engineering 一点都不 Low

可能对于一直做LLM Finetune的算法工程师而言,Prompt Engineering 没啥关键技术,非常的Low,可是这就好比如模型训练过程中的 gradient descent 背后的技术就是:链式求导,哪些学数学的小伙伴肯定也是觉得很low,不过不得不承认,链式求导之后进行参数更新对于模型训练而言,至关重要。

:::

In-Context Learning 算是大模型目前最基础的能力之一了,其中Instruction Tuning分支就严重依赖于此能力。如果大家感兴趣的话,我可以写一篇文章来详细介绍此能力。
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
slug: few-shot-prompting
title: Few-Shot Prompting
---


### Few-Shot Prompting

是不是看起来非常熟悉呢?以前有一个 Few-Shot Learning的NLP 方向,本质上也是给少量的几个case,然后训练模型基于此来学习领域内的知识。

而Agent时代的 Few-Shot 就是prompt 当中添加少量的case 来提升大模型在目标领域的理解能力。

比如当你想用大模型开发一个计算机的功能,并以中文回复,此时也可以在其中添加部分few-shot examples,示例如下所示:

```text
2+2: 四
4+5: 九
8+0:
```

当然,这个是最简单的examples 的例子,当功能变得更加复杂,此时 Examples 也需要写的更加复杂,那此时对Examples 的编写也有一定的要求:

* Example 的质量至关重要

认真编写覆盖你业务场景下的 examples 能够有效提升Prompt的效果,可是也不要加太多,如果超过了20个,效果就会降低。

* Example 的顺序也是有讲究的

在一些具体任务上,不同的 Example 顺序能够产生 -50% - 90%+ 的效果。

关于这点的话,还是比较玄学,不过有一定的前置条件:examples 的数量比较多时此问题才会特别明显。目前没有啥解决方案,必须得你不断的测试调整才能够在目标领域上缓解此问题。

* Example 的类别尽量均匀

如果你是做一个二分类的任务,有10个example 是关于0类别,有2个example是关于1类别,此时大模型的效果就肯定更偏向于1类别,由此可见,Few-Shot Examples 的类别分布要尽量均匀,此时才能够让模型有更高质量的输出。

此时如果一两个example已经能够解决70%的任务,想要继续提升效果,此时就需要针对于那些hard-case 编写高质量的example,进而提升效果瓶颈。

* Example 的格式

Example 的格式也会影响模型的效果,其中最常见的格式为:

```prompt
Q: {question}
A: {answer}
```

当然,针对于不同的任务应该有不同的输入输出格式,而大模型很擅长根据Instruction 和 Examples 输出指定格式的内容。

你也可以尝试多种不同的输入输出格式来测试效果,这也是Prompt Engineering中的重要一个环节。

* Example 的分布

如果你的Few-Shot Examples 能够更贴近测试中的Case,此时生成的效果也会更好。

此外,你也可以增加 Examples 的分布情况,尽量覆盖不同的边界情况,此时生成的效果也会更好。

总之,你给的 Examples 与真实场景更贴近,覆盖的范围更广,生成的效果就会更好。
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
slug: dynamic-prompting
title: Dynamic Prompting
---

### 动态选择 Few-Shot Examples

如果你针对于目标场景下有很多的Examples(假设有100个case),此时是否一股脑儿将其全部塞入到 Prompt 当中吗?

非也非也,上文也讲过:
* 如果一个Examples 的数量超过20个,反而会降低模型生成的效果。
* 如果 Examples 的分布与真实输入场景越接近,此时模型生成的效果会越好。

于是,Examples 的选择如果动态起来,此时效果会越好。那如何选择Examples 也有相关的方法:

#### K-Nearest Neighbor(KNN)

方法很简单,可以针对于 所有的Examples 建索引,然后根据query 来召回出最相近的一批Examples,然后塞入到 Prompt 当中,即可提升模型的效果。

可是此方法有一个缺点:Examples 都是相似的,分布太集中,可能会影响模型的泛化性。

#### Self-Generated In-Context Learning

在Zero-Shot场景中,此方法能够有一定的提升效果,可是也存在一定的风险:一旦动态生成的 Examples 不符合目标领域效果,此时会将模型的生成内容给带偏,大大降低目标领域上的效果。

在实际开发过程中,如果能编写一些 Examples 就尽量写,而且也不是很复杂,也能够更稳定的控制好模型的输出效果,此方法不太建议大家使用。

#### 更复杂的Prompt 方法

比如说:LENS、UDR以及Active Example Selection 等方法利用了 embedding、retrieval以及强化学习等相关技术来筛选Examples,这样能够让Examples有更好的效果。

:::warning

这些复杂的方法我后续会详细展开给大家讲解介绍。

:::
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
slug: zero-shot-prompting
title: Zero-Shot Prompting
---

## Zero-Shot Prompt

相比于Few-Shot,此类别中是没有提供任何Examples,此时模型没有任何先验知识可以参考,那如何提升模型效果呢?

> 个人感觉 Zero-Shot的方法可以使用在Few-Shot 上面,进而让Few-Shot的效果上升一个档次。
### Role Prompting

编写角色说明,此时能够让模型能够站在某个角色的立场上有更符合目标偏好的输出。比如:

```prompt
你是一个可爱旅游导员,擅长使用俏皮可爱的话语来给大家介绍不同的景点,在面对旅客的刁难,你总是会用撒娇的方式来向用户表达歉意,然后给出一定具有建设性的建议给旅客。
```

以上的角色描述其实是在整体层面来规范输出风格,基本上属于 Prompt Engineering中的基操了。

### Emotion Prompting

如果模型的输出不太稳定时,此时可以加入一下强调描述词,进而增加输出内容的稳定性。

比如你想让模型输出 JSON 格式的内容,可随机性就是很大,此时可通过以下描述词来提升效果:

```prompt
求求你了,一定要输出JSON格式的内容!!!
重要的事情说三遍:你一定要输出JSON 格式的内容!你一定要输出JSON 格式的内容!你一定要输出JSON 格式的内容!
```

类似于以上的prompt可以增加输出的稳定性。

听起来很扯,可是大模型时代的编程就是如此。

### System2 Attention

不知道大家读过《思考快与慢》这本书没,可以大致了解下:人通常有两种思考方式,一种是快思考,可以认为是人的本能反应,另外一种是慢思考,就是经过缜密的思考之后的结果。

而这个对于大模型解决复杂问题有非常明显的提升效果。

此方法就是通过:在生成之前先慢思考,仔细分析用户的问题并重新调整 Prompt 之后再让模型来输出,这样可以生成有针对性的思考内容,进而提升整体效果。

:::tip 思考快与慢

有一点需要注意,重新prompt 可以认为是一个 Rewrite Agent,然后最后的生成也可以认为是一个Agent,所以用到了Agent Workflow的相关方法。

:::

### Rephrase and Response(RaR)

这个方法没有修改整体的Prompt,而是修改用户的Question。

在生成之前,对用户的Question进行重写,然后将其拆分成多个相关的问题,让模型来生成,此方法能够有效提升用户Question 的质量,进而让模型有更好的输出。

### Re-Reading(RE2)

在Instruction 中可以写上:在生成正式回答之前请再认真阅读用户的问题,据作者说可以有效提升在复杂问题上的效果。

### Self-Ask

对于一个复杂问题,模型通常无法直接回答,此时可让模型决定:是否要对齐问题进行拆解成多个子问题,然后依次回答对应子问题,等最终都回答完毕后,再回答最终问题。

其实这个方法也算是任务拆解,只不过问题呗拆解之后,还是自己来解决此问题,没有使用外部工具,甚至独立的LLM 来解决。
17 changes: 17 additions & 0 deletions docs/02-prompt-engineering/02-chain-of-thought/00-intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
slug: intro
---

## Chain-of-Thought 相关技术

CoT 相关技术我相信大家都早已听说过,本质上还是让模型多思考一点,经过缜密的思考之后得到的答案也会更加准确,这个与上面介绍的System2原理类似,也是借鉴人类的思考方式。

:::tip 人类其实是大模型的训练数据

大模型从人类的文字中学习,此时也潜在的学习了人类的思考方式,是不是有点后背发凉

:::

好了,不闲聊了,开始正式介绍 CoT 的相关技术吧。

首先就是来介绍一下原始的论文,作者仅仅在Prompt 当中添加了“let's think step by step”就可以提升在不同任务上的效果,可以看出让模型多思考一会儿(让子弹飞一会儿)是非常有效的trick,而后续无数的研究者都证实了此方法有效。
50 changes: 50 additions & 0 deletions docs/02-prompt-engineering/02-chain-of-thought/01-zero-shot-cot.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
---

## Zero-Shot CoT

像原始论文中仅仅加入了:“let's think step by step”就是属于Zero-Shot 方法,可是除了这句话,还有其它的sentence可以让模型有更好的思考方式。

:::tip 人是如何思考?大模型是如何思考?

写到这里,突然感觉其实CoT就是在让模型如何思考。上升到更上层的维度,思考方式对于人而言至关重要,大决定了一个人的命运,小到如何有效解决一个问题。

所以大模型的思考方式也是一个非常有趣的话题,当然这个除了你告诉他如何思考之外,也取决于背后LLM的思考能力,是否有训练过多种思考方式(与训练数据集相关)。

:::

这里也有一起其它的方法能够让模型有不同的思考:

```prompt
你需要一步一步的思考并解决此问题,最终保证你真的解决了此问题。
首先,你需要从不同层面且具备一定逻辑性的思考这个问题。
```

Zero-Shot CoT 的方法应用也是非常广泛,同时非常吸引人,因为:构造Examples 也需要一定的成本(虽然我并不觉得 Examples 的构造有多复杂)。

### Step-Back Prompting

此方法主要是让模型在开始Reasoning之前先生成几个更上层的问题和概念,然后回答它,此时能够让模型获得更全面的整体信息,进而提升回答的效果。

### Thread-of-Thought Prompting

这个方法相对比其它方法,也是换汤不换药:让LLM从不同角度来思考(给予模型不同的思考方式),进而提升模型的效果。

关键Prompt 如下所示:

```prompt
Walk me through this context in manageable parts step by step, summarizing and analyzing as we go.
```

### Tabular Chain-of-Thought

这个更TM有意思,让模型以Markdown的方式来输出,进而提升模型的结构化推理能力。

大家可自行编写适应与你们自己任务的Prompt,目标就是让思考过程 markdown 化。

:::tip 老铁你们说,这个想法能发一篇论文吗?

在这里脑暴一下,我如果让思考过程以json 的方式来输出,效果会不会更好呢?是否有资格发一篇论文呢?

:::
21 changes: 21 additions & 0 deletions docs/02-prompt-engineering/02-chain-of-thought/02-few-shot-cot.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
---


## Few-Shot CoT

顾名思义,这个是在Prompt当中添加一些Examples 来提升CoT 的效果,那如何实现呢:在Example当中添加Thought 的数据,这样,模型就可以借鉴一些“思考”,进而进行更稳定的思考。

Example 中的思考可以是人手写的,也可以是模型动态生成的。

所以Few-Shot CoT 的目标就是提高Thought 的准确性。

### Contrastive CoT Prompting

通常我们会添加一些正确的思考内容,可是作者提出,我们同时也需要给出一些错误的思考方式,今日提升思考正确性。

简单来说,我们不仅仅要提供“我们应该这样思考”,还要提供“我们不应该那样思考”,这样LLM的思考效果才会更好。

### 实在是不想写这个篇幅了

其实还有一些其他Few-Shot CoT 的方法,我这边没有写,因为在我看来,这TM全部是都是注水论文,没有任何实用价值,免得脏了您的眼,所以我就没有写,如果你们感兴趣的话,可以亲自去读一读相关系列论文。
8 changes: 8 additions & 0 deletions docs/02-prompt-engineering/03-decomposition/00-intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: Introduction
---

## Decomposition-任务拆解

此类方法的核心思想是:将复杂问题拆解成一个个简单的问题来解决。这个跟CoT的思考非常类似,可是又不太一样:CoT 是在一次生成中完成,可是任务拆解会分为多次模型执行,这样不同任务之间是互不影响的,实践证明这是可以有效提升模型解决复杂问题的能力。

11 changes: 11 additions & 0 deletions docs/02-prompt-engineering/03-decomposition/01-least-to-most.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
---

## Least-to-Most Prompting

此方法分为三个阶段:
1. 将用户的问题拆解为多个子问题,同时并不解决他们。
2. 将上一个阶段中的子问题用分步并行执行的方式来解决。
3. 汇总以上内容,并生成最终答案。

此方法在多种不同的任务当中均有非常明显的效果提升,比如符号推理、数学推理等。
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
---

### Decomposed Prompting

这个方法与 `Least-to-Most Prompting` 方法类似,区别在于:此方法用了外部工具来解决需要计算、需要外部知识的子问题。

这个效果肯定好啊,这个也印证了吴恩达的Agent Workflow的方法论。
17 changes: 17 additions & 0 deletions docs/02-prompt-engineering/03-decomposition/03-plan-and-solve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
title: Plan and Solve
---

### Plan-and-Solve Prompting

这个方法的Prompt为:`首先,让我们来思考用户的问题;然后,制定任务来解决;最后,让我们挨个儿解决这些任务。`

这个相对于Zero-Shot CoT 具备更好的推理能力。

:::note

个人感觉主要的提升有两点:
* 将任务拆分成独立可执行的子任务,有效的屏蔽了不同子任务之间在生成的时候干扰信息。
* 在执行不同子任务的时候,可以利用外部工具来解决具体问题,进而提升整体效果。

:::
10 changes: 10 additions & 0 deletions docs/02-prompt-engineering/03-decomposition/04-tree-of-thought.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
title: Tree of Thought
---

## Tree-of-Thought

和上面的方法相比,此方法可以将某个子问题再次拆解成不同的子问题,进而可以解决非常复杂的问题。

优点是:在针对于特别特别特别复杂的问题时,我相信这个行之有效的。
缺点是:特别特别特别复杂的问题,在实际应用当中不会出现,而且此方法甚至会大大提高模型回复的时延,进而降低使用体验。
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
title: Program of Thought
---

## Program-of-Thoughts

核心思想是:用生成代码来解决用户的问题。

最简单的case 就是:当用户询问:3^12是多少时,此时可以生成一段python来解决此问题。

此方法是代码解释器的基础思想,也是能够用程序解决用户复杂问题的关键方法之一。
15 changes: 15 additions & 0 deletions docs/02-prompt-engineering/04-ensembling/00-intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: Introduction
---

> 准备针对于这个取一个比较好的中文名字,可是想不出来,如果各位老铁有比较好的推荐,请在下面评论区回复,非常期待各位老铁的互动。
此方法的核心思考是:使用多个不同的 prompt(Agent) 来解决同一个问题,最后将答案融合起来,生成最终答案。通常情况下,为了让答案更加准确,可能会有使用投票的方式选择相同答案最多的那一方,可是 Emsembling 方法可以能够减少这种方法带来的部分扰动,进而提升答案的准确性。

:::tip Multi-Agent

Multi-Agent 就是这种范式。

:::

在这个方向有很多优秀的工作,接下来我将一一介绍。
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
title: Demonstration Emsembling
---

## Demonstration Emsembling(DENSE)

通过创建多个不同 Domain 的Few-Shot Examples,然后让多个Agent 分别来推理生成,最后让LLM 来整合最终答案。

个人观点:
* 优点:此类方法简单粗暴。
* 缺点:浪费资源,这个和few-shot 当中要增加examples 的分布范围想违背,属于另辟蹊径的方法,不太可取。
Loading

0 comments on commit 10ea303

Please sign in to comment.