Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ node_modules
.idea
.DS_Store
.prettierignore
pnpm-lock.yaml
pnpm-lock.yaml
*.mdx
*.md
70 changes: 35 additions & 35 deletions blog/2025-04/_partials/calculus.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ A_{11} & \cdots & A_{1n} \\ \vdots & \ddots & \vdots \\ A_{m1} & \cdots & A_{mn}
\end{bmatrix}$"}:

<Collapse label="$$
\nabla_x (A x) = A^T
$$">
\nabla_x (A x) = A^T
$$">

$$
\begin{split}
Expand Down Expand Up @@ -139,20 +139,20 @@ A_{11} & \cdots & A_{1m} \\ \vdots & \ddots & \vdots \\ A_{n1} & \cdots & A_{nm}
\nabla_x (x^T A) = A
$$">

$$
\begin{split}
&\ \nabla_x (x^T A) = \nabla_x (x_1 A_1 + x_2 A_2 + \cdots + x_n A_n) \\
=&\ \nabla_x (x_1 [A_{11} \cdots A_{1m}] + x_2 [A_{21} \cdots A_{2m}] + \cdots + x_n [A_{n1} \cdots A_{nm}]) \\
=&\ \nabla_x (x_1 A_1 + x_2 A_2 + \cdots + x_n A_n) \\
=&\ \nabla_x (x_1 A_1) + \nabla_x (x_2 A_2) + \cdots + \nabla_x (x_n A_n) \\
=&\ \begin{bmatrix} \
\frac{\partial}{\partial x_1} (x_1 A_1) , \frac{\partial}{\partial x_2} (x_2 A_2) , \cdots , \frac{\partial}{\partial x_n} (x_n A_n)
\end{bmatrix} \\
=&\ \begin{bmatrix}
A_1 , A_2 , \cdots , A_n
\end{bmatrix} = A
\end{split}
$$
$$
\begin{split}
&\ \nabla_x (x^T A) = \nabla_x (x_1 A_1 + x_2 A_2 + \cdots + x_n A_n) \\
=&\ \nabla_x (x_1 [A_{11} \cdots A_{1m}] + x_2 [A_{21} \cdots A_{2m}] + \cdots + x_n [A_{n1} \cdots A_{nm}]) \\
=&\ \nabla_x (x_1 A_1 + x_2 A_2 + \cdots + x_n A_n) \\
=&\ \nabla_x (x_1 A_1) + \nabla_x (x_2 A_2) + \cdots + \nabla_x (x_n A_n) \\
=&\ \begin{bmatrix} \
\frac{\partial}{\partial x_1} (x_1 A_1) , \frac{\partial}{\partial x_2} (x_2 A_2) , \cdots , \frac{\partial}{\partial x_n} (x_n A_n)
\end{bmatrix} \\
=&\ \begin{bmatrix}
A_1 , A_2 , \cdots , A_n
\end{bmatrix} = A
\end{split}
$$

</Collapse>

Expand All @@ -167,17 +167,17 @@ A_{11} & \cdots & A_{1n} \\ \vdots & \ddots & \vdots \\ A_{n1} & \cdots & A_{nn}
\nabla_x x^T A x = (A + A^T) x
$$">

$$
\begin{split}
&\ \nabla_x x^T A x = \nabla_x \sum_{i=1}^n \sum_{j=1}^n x_i A_{ij} x_j \\
=&\ \frac{\partial}{\partial x_k} \sum_{i=1}^n \sum_{j=1}^n x_i A_{ij} x_j + \frac{\partial}{\partial x_k} \sum_{i=1}^n \sum_{j=1}^n x_j A_{ji} x_i \\
=&\ \sum_{i=1}^n \sum_{j=1}^n A_{ij} x_j + \sum_{i=1}^n \sum_{j=1}^n A_{ji} x_i \\
=&\ \sum_{j=1}^n A_{kj} x_j + \sum_{i=1}^n A_{ik} x_i \text{($i, j = k$ 时,$A_{kj} x_j, A_{ik} x_i$ 分别存在一项 $A_{kk} x_k$)} \\
=&\ \sum_{i=1}^n (\sum_{j=1}^n A_{ij} x_j) \cdot e_i + \sum_{j=1}^n (\sum_{i=1}^n A_{ji} x_i) \cdot e_j \\
=&\ \sum_{i=1}^n (\mathbf{A} \mathbf{x})_i \cdot e_i + \sum_{j=1}^n (\mathbf{A^T} \mathbf{x})_j \cdot e_j \\ \
=&\ (A + A^T) x
\end{split}
$$
$$
\begin{split}
&\ \nabla_x x^T A x = \nabla_x \sum_{i=1}^n \sum_{j=1}^n x_i A_{ij} x_j \\
=&\ \frac{\partial}{\partial x_k} \sum_{i=1}^n \sum_{j=1}^n x_i A_{ij} x_j + \frac{\partial}{\partial x_k} \sum_{i=1}^n \sum_{j=1}^n x_j A_{ji} x_i \\
=&\ \sum_{i=1}^n \sum_{j=1}^n A_{ij} x_j + \sum_{i=1}^n \sum_{j=1}^n A_{ji} x_i \\
=&\ \sum_{j=1}^n A_{kj} x_j + \sum_{i=1}^n A_{ik} x_i \text{($i, j = k$ 时,$A_{kj} x_j, A_{ik} x_i$ 分别存在一项 $A_{kk} x_k$)} \\
=&\ \sum_{i=1}^n (\sum_{j=1}^n A_{ij} x_j) \cdot e_i + \sum_{j=1}^n (\sum_{i=1}^n A_{ji} x_i) \cdot e_j \\
=&\ \sum_{i=1}^n (\mathbf{A} \mathbf{x})_i \cdot e_i + \sum_{j=1}^n (\mathbf{A^T} \mathbf{x})_j \cdot e_j \\ \
=&\ (A + A^T) x
\end{split}
$$

</Collapse>

Expand All @@ -199,14 +199,14 @@ A_{11} & \cdots & A_{1n} \\ \vdots & \ddots & \vdots \\ A_{n1} & \cdots & A_{nn}
\nabla_x \|x\|_2^2 = \nabla_x (x^T x) = 2x
$$">

$$
\begin{split}
&\ \nabla_x \|x\|_2 = \nabla_x (\sqrt{x^T x}) ^ 2 \\
=&\ \nabla_x (x^T x) = \nabla_x (x_1^2 + x_2^2 + \cdots + x_n^2) \\
=&\ 2x
\end{split}
$$
$$
\begin{split}
&\ \nabla_x \|x\|_2 = \nabla_x (\sqrt{x^T x}) ^ 2 \\
=&\ \nabla_x (x^T x) = \nabla_x (x_1^2 + x_2^2 + \cdots + x_n^2) \\
=&\ 2x
\end{split}
$$

</Collapse>

:::nerd
Expand Down
127 changes: 127 additions & 0 deletions blog/2025-08/prompt-engineering.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
---
slug: prompt-engineering
title: 提示词工程导览
authors: ["heliannuuthus"]
tags: ["AI"]
draft: true
---

最近在做关于智能体系统的 AI 知识学习、智能体知识库构建和提示词工程。
受 AI 平台 Prompt 产品交流影响和启发,也却身体会到了自己写的 Agent Prompt 会让 LLM 像个 dinner,所以打算系统性的学习一下 Prompt Engineering。
本章节受 [Prompt Engineering Guide](https://www.promptingguide.ai/) 启发,并结合自己的理解进行整理。

<!--truncate-->

## 提示词要素

常规的提示词通常包含以下要素:

1. 指令(instruction):想要模型执行的指令,简洁和直接,通常用一或几句话来概括。
2. 上下文(context):一些外部知识或前置知识的上下文信息,引导 LM 更好的响应用户请求。
3. 输入数据(input):用户输入的问题和内容。
4. 输出数据(output):大模型输出的答案,当前大部分 LM 都具备结构化输出的能力。

### 指令

> 并不存在任何特定 tokens(词元或关键字)能为 LM 的回答带来很积极的作用

1. 结构化的格式和详细的描述能使 LM 对问题和背景理解得更为透彻
2. 指令应该更明确,意图更清晰直接,保证信息传达的有效
3. 集中 LM 注意力,要告诉 LM 做什么而不是告诉它**不做什么**

### 上下文

> LM 回答的准确性和上下文强相关,幻觉是 LM 的既存问题,好的上下文能极大程度上缓解它

1. 上下文可以是 QA 对,也能是一篇文章、一个背景故事、一个技术方案等
2. 上下文不是必须的,LM 是对“世界”存在有限的感知能力,所以我们也需要严令禁止 LM 瞎说

## 提示词技术

> AI 从早几年前就已经开始发酵,到 OpenAI 问世算是彻底爆发,开启 AI 元年。其间 Prompt 技术的演化历史也十分的精彩

本质是引导 LM 正确且准确的完成任务,算是“教会” LM 一种学习方法来更好地应对接下来的问题

### 零样本提示词

> 零样本提示词(Zero Shot Prompt)指 LM 在几乎没有任何的上下文(context)环境中对用户输出(input)进行分析学习,最后给出答案

1. 通常用于执行情感分析或者输入较为明确的单一意图识别任务
2. LM 的 Large 来源于庞大的训练数据,所以它有超强的零样本能力

### 少样本提示词

> 少样本提示词(Few Shot Prompt)指填充少量的 QA 对作为样本填充在 LM Prompt 的上下文以引导 LM 进行类似问题或行为分析

1. LM 通常会按照引入的少量 samples 的简单思维结构来回答用户的问题,加上幻觉,其实能很清晰的感知到,它们并不能识别一些 samples 之外的原则性的错误
2. 在处理复杂的,甚至涉及一些推理步骤的问题时,少样本提示词作用在 LM 上的结果会愈发地显得诡异

### 链式思考(思维链)

> 思维链(Chain of Thought)通过向 Prompt 加入中间推理过程强制 LM 进行思考,本质是一种 Feedback,达到修正自身 CoT 的目的

1. 结合少量样本提示,可提升被单一的少量样本提示限制的推理能力
2. 结合零样本提示,使用 LM 自身对物理世界构建的 CoT 进行问题推理,也是一种很棒的方式
3. Auto-CoT 是一种人工消除 LM 在推理过程中产生的错误的手段,主要分为两步:
1. 问题分类:面临的问题是可分类的且是有限的
2. 抽样表达:针对每一类问题,都能找到其中具有代表性的一个,并且为 LM 演示 CoT 构建过程,可使用简单的规则对 LM 进行启发,达到动态构建 CoT 的目的(例如,输入的长度和推理的步骤正相关)

### 自我一致性

> 自我一致性(Self-Consistency)比 CoT 会更具有说服力一些,CoT 更像是在有限且繁复的信息里根据词元相关性建立起的贪心算法,稳定性并不高。而自我一致性从不同角度出发进行多路径总结通过计算得到更权威的正确答案

1. 自我一致性依赖问题推理出正确答案的多条 CoT 输出内容强相关
2. 本质通过大模型多轮对推理结果进行评分采样,再推理、再评分和采样最终将结果进行相似度评估,将加权结果最高的作为正确答案

### 生成知识提示词

> 生成知识提示词(Generated Knowledge Prompt)指出 LM 可以在检索现有知识库之后、预测之前,对已有知识或单纯的围绕着问题并结合少样本提示进行知识提示词的自生成,达到提升常识性推理性能的目的

1. 通过少量样本提示 LM 生成与问题相关的知识陈述
1. 提示设计包含任务说明,少量手写的问题以及知识示例
2. 生成参数使用核采样,每条问题生成 20 条知识(不同的 LM 可能不同),并对期进行置信度评分
2. 影响性能和结果的因素分为三点:
1. 知识质量事实正确性较高,并且对推理有较积极的作用
2. 知识数量在 20 条时开始饱和,过多会因噪声下降
3. 知识整合:“选择最佳知识策略” 比 MoE(专家混合)和 PoE(专家乘积)效果更好
3. **选择最佳知识策略**
1. 生成知识陈述:根据特定任务的少量样本提示词生成与问题相关的知识陈述。
2. 构建知识增强问题:将生成的每个知识陈述与原始问题进行拼接,形成多个知识增强的问题
3. 计算答案选择聚合分数:使用推理模型计算每个答案在不同知识增强问题下的支持度分数,最终聚合分数由使答案获得最高支持度的知识陈述对应的分数决定
4. 将聚合分数最高的答案为预测结果

### 链式提示词

> 链式提示词(prompt chaining)本质是将一个重要的提示词技术拆分成多个子任务,将上一个子任务的输出作为下一个子任务的 Prompt 提供给 LLM(Feedback),以提升 LLM 性能并保证其输出是稳定且透明的

1. 通常中间子任务的输出是结构化的,并且前后两个子任务有一定的关联性,譬如精简语句、总结摘要和信息提取等
2. 链式提示词对 LLM 的上下文长度有一定的要求,往往最后一个子任务的 Prompt 会结合前面所有子任务的输出
3. 通过这种链式输出,可以很方便的定位到 LLM 在整个流程中犯的错

### 思维树

> 思维树(Tree of Thought)维护着多条连贯的思维链,本质是缓解 LM 受限于 Token-Level 和从左到右决策在生成内容时带来的消极影响。

- LM 生成内容时,是从左到右的一个一个 token 去生成的,并且下一个 token 是基于上一个 token 预测的。将 LM 本身的前瞻性和计算流程全部压缩到了这一个 token。当 token 出现误判可能会导致雪崩。

- 思维树的构建过程可以通过 Prompt 实现,也能通过 RL(Reinforcement Learning)实现
- 通过 RL 实现的思维树,在新环境上更具有鲁棒性
- 通过 Prompt 实现的思维树,在推理过程中更具有可解释性

```markmap
## 思维分解
- 确定问题范围
- 定义筛选条件
- 进行验证答案
## 思维生成


## 思维评估

1. 思维评估:每个节点都会衍生*多个*更接近答案的思维,需要对这些思维进行评估打分

## 思维选择

1. 思维选择:最终会得到多个思维,需要对这些思维进行选择,得到最终答案

```
28 changes: 25 additions & 3 deletions docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
} from "heliannuuthus-remark-collapse-heading";
import remarkCommentTooltip from "heliannuuthus-remark-comment-tooltip";
import remarkExternalLink from "heliannuuthus-remark-external-link";
import remarkMarkmap from "heliannuuthus-remark-markmap";
import remarkTerminology from "heliannuuthus-remark-terminology";
import path from "path";
import { themes as prismThemes } from "prism-react-renderer";
Expand Down Expand Up @@ -38,7 +39,8 @@ const remarkPlugins = [
remarkCodeImport,
remarkBreaks,
remarkMath,
remarkCollapseHeading
remarkCollapseHeading,
remarkMarkmap
];

const rehypePlugins = [rehypeKatex];
Expand Down Expand Up @@ -89,7 +91,18 @@ const config: Config = {

onBrokenLinks: "throw",
onBrokenMarkdownLinks: "warn",

stylesheets: [
{
href: "https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css",
type: "text/css",
crossOrigin: "anonymous"
},
{
href: "https://cdn.jsdelivr.net/npm/@callmebill/lxgw-wenkai-web@latest/style.css",
type: "text/css",
crossorigin: "anonymous"
}
],
// Even if you don't use internationalization, you can use this field to set
// useful metadata like html lang. For example, if your site is Chinese, you
// may want to replace "en" with "zh-Hans".
Expand All @@ -101,6 +114,15 @@ const config: Config = {
editUrl:
"https://github.com/heliannuuthus/heliannuuthus.github.io/edit/master"
},
future: {
v4: {
useCssCascadeLayers: true
},
experimental_faster: {
rspackBundler: true,
rspackPersistentCache: true
}
},
markdown: {
mermaid: true,
parseFrontMatter: async (params) => {
Expand Down Expand Up @@ -232,7 +254,7 @@ const config: Config = {
layout: "elk",
look: "handDrawn",
themeVariables: {
fontFamily: "Noto Sans SC"
fontFamily: "Monaspace Randon Var"
},
xyChart: {
titleFontSize: "14px",
Expand Down
28 changes: 20 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "blog",
"version": "0.0.0",
"name": "heliannuuthus-site",
"version": "0.2.0",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
Expand All @@ -25,6 +25,7 @@
"@ant-design/icons": "^5.5.2",
"@ant-design/v5-patch-for-react-19": "^1.0.3",
"@docusaurus/core": "3.8.1",
"@docusaurus/faster": "^3.8.1",
"@docusaurus/plugin-content-blog": "^3.8.1",
"@docusaurus/plugin-content-docs": "^3.8.1",
"@docusaurus/plugin-content-pages": "^3.8.1",
Expand All @@ -35,13 +36,15 @@
"@docusaurus/theme-mermaid": "^3.8.1",
"@docusaurus/theme-search-algolia": "^3.8.1",
"@mdx-js/mdx": "^3.1.0",
"@mdx-js/react": "^3.0.0",
"@mdx-js/react": "^3.1.0",
"animate.css": "^4.1.1",
"animejs": "^3.2.2",
"antd": "^5.24.2",
"antd": "^5.27.1",
"antd-style": "^3.7.1",
"canvas": "^3.1.0",
"canvg": "^4.0.2",
"clsx": "^2.0.0",
"d3": "^7.9.0",
"echarts": "^5.5.1",
"file-saver": "^2.0.5",
"heliannuuthus-docusaurus-authors": "file:./plugins/docusaurus-authors",
Expand All @@ -52,18 +55,23 @@
"heliannuuthus-remark-collapse-heading": "file:./packages/remark-collapse-heading",
"heliannuuthus-remark-comment-tooltip": "file:./packages/remark-comment-tooltip",
"heliannuuthus-remark-external-link": "file:./packages/remark-external-link",
"heliannuuthus-remark-markmap": "file:./packages/remark-markmap",
"heliannuuthus-remark-mermaid": "file:./packages/remark-mermaid",
"heliannuuthus-remark-terminology": "file:./packages/remark-terminology",
"heliannuuthus-terminology-store": "file:./plugins/terminology-store",
"html-to-image": "^1.11.13",
"js-yaml": "^4.1.0",
"jszip": "^3.10.1",
"markmap-common": "^0.18.9",
"markmap-lib": "^0.18.12",
"markmap-view": "^0.18.12",
"package-up": "^5.0.0",
"prism-react-renderer": "^2.3.0",
"pushfeedback": "^0.1.63",
"pushfeedback-react": "^0.1.63",
"react": "^19.0.0",
"react": "^19.1.1",
"react-device-detect": "^2.2.3",
"react-dom": "^19.0.0",
"react-dom": "^19.1.1",
"rehype-katex": "^7.0.1",
"rehype-mermaid": "^3.0.0",
"rehype-sanitize": "^6.0.0",
Expand All @@ -80,9 +88,13 @@
"@docusaurus/module-type-aliases": "3.8.1",
"@docusaurus/tsconfig": "3.8.1",
"@docusaurus/types": "3.8.1",
"@trivago/prettier-plugin-sort-imports": "^5.2.0",
"@types/d3": "^7.4.3",
"@types/file-saver": "^2.0.7",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"prettier": "^3.5.3",
"@trivago/prettier-plugin-sort-imports": "^5.2.0",
"prettier-plugin-organize-imports": "^4.2.0",
"remark-code-import": "^1.2.0",
"typescript": "~5.7.3"
},
Expand All @@ -99,6 +111,6 @@
]
},
"engines": {
"node": ">=18.0"
"node": ">=22.0"
}
}
Loading