Day04---提示工程进阶(CoT + 结构化输出):基于通义千问的深度探索
Day04—提示工程进阶(CoT + 结构化输出):基于通义千问的深度探索
摘要:本文深入探讨提示工程的进阶技巧,即思维链(CoT)与结构化输出,并以通义千问模型为例进行详细讲解与实践。通过学习这些技巧,开发者能够引导模型进行更具逻辑性的推理,并获取易于处理的结构化数据,提升模型应用的效率与质量。
一、引言
在使用大语言模型时,如何让模型的回答更具逻辑性、更易于后续处理是关键问题。提示工程的进阶技巧 —— 思维链(CoT)和结构化输出,为我们提供了有效的解决方案。本文将基于通义千问模型,详细介绍如何运用这两种技巧。
二、核心任务
(一)思维链(CoT)
思维链(Chain of Thought, CoT)模拟人类逐步思考的过程,使模型能够分步推理,而不是直接给出答案。这样不仅能让模型的回答更具逻辑性,还能提高回答的可解释性。
例如,对于数学问题 “小明有 5 个苹果,小红的苹果数比小明的 2 倍少 3 个,问小红有几个苹果?”
我们可以构建如下的 CoT 提示:“请按照以下步骤回答这个问题:首先,分析题目中所涉及的数量关系,即小红的苹果数与小明苹果数的联系;然后,列出计算步骤;最后,得出答案。问题是:小明有 5 个苹果,小红的苹果数比小明的 2 倍少 3 个,问小红有几个苹果?”
通义千问基于此提示,可能会给出这样的回答:“首先,分析题目可知,要计算小红的苹果数,需先求出小明苹果数的 2 倍,再减去 3。计算步骤为:小明苹果数的 2 倍是5×2=10个,然后比这个结果少 3 个,即10−3=7个。所以,小红有 7 个苹果。”
(二)结构化输出
结构化输出是指引导模型以特定的结构化格式(如 JSON)返回结果。这种格式在将模型输出集成到其他系统或进行进一步数据处理时极为方便。
比如,我们希望模型返回用户信息,包含姓名、年龄和职业。可设计如下提示:“请以 JSON 格式返回一个用户的信息,包含姓名、年龄和职业。姓名设定为‘张三’,年龄 30 岁,职业是‘工程师’。”
通义千问可能返回的结果为:
{
"姓名": "张三",
"年龄": 30,
"职业": "工程师"
}
三、补充任务
(一)编写 CoT Prompt
-
数学题求解
- 代码实现:
from openai import OpenAI
# CoT Prompt - 数学题
math_cot_prompt = "请按照以下步骤回答这个数学问题:首先,分析题目中所涉及的数量关系;然后,列出计算步骤;最后,得出答案。问题是:一个班级有40名学生,其中男生占$\frac{3}{5}$,问女生有多少人?"
try:
client = OpenAI(
api_key="你的API_KEY",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
completion = client.chat.completions.create(
model="qwen-plus", # 模型列表: https://help.aliyun.com/model-studio/getting-started/models
messages=[
{"role": "user", "content": math_cot_prompt}
]
)
print(completion.choices[0].message.content)
except Exception as e:
print(f"错误信息:{e}")
print("请参考文档:https://help.aliyun.com/model-studio/developer-reference/error-code")
-
解释:上述代码中,我们基于openAi用于调用通义千问的 API 。
math_cot_prompt构建了一个数学题的 CoT 提示,引导模型先分析数量关系,再列出计算步骤,最后得出答案。运行代码后,通义千问会根据提示进行回答。 -
回答结果:
**第一步:分析题目中所涉及的数量关系**
- 班级总人数为 40 人,这是一个整体(单位“1”)。
- 男生占总人数的 $\frac{3}{5}$,即男生人数 = 总人数 × $\frac{3}{5}$。
- 女生人数 = 总人数 − 男生人数;
或等价地,女生占比 = $1 - \frac{3}{5} = \frac{2}{5}$,
所以女生人数 = 总人数 × $\frac{2}{5}$。
这两种思路本质一致,体现的是“部分与整体”的互补关系。
**第二步:列出计算步骤**
方法一(先求男生,再求女生):
① 男生人数 = $40 \times \frac{3}{5} = \frac{40 \times 3}{5} = \frac{120}{5} = 24$(人)
② 女生人数 = 总人数 − 男生人数 = $40 - 24 = 16$(人)
方法二(直接求女生占比):
① 女生占比 = $1 - \frac{3}{5} = \frac{2}{5}$
② 女生人数 = $40 \times \frac{2}{5} = \frac{40 \times 2}{5} = \frac{80}{5} = 16$(人)
两种方法结果一致,验证无误。
**第三步:得出答案**
女生有 **16人**。
-
逻辑推理
- 代码实现:
from openai import OpenAI
# CoT Prompt - 逻辑推理
math_cot_prompt = "请按照以下步骤回答这个逻辑推理问题:首先,分析题目条件之间的逻辑关系;然后,阐述推理过程;最后,得出结论。问题是:有三个人,甲、乙、丙,甲说乙在说谎,乙说丙在说谎,丙说甲和乙都在说谎。请问谁在说真话,谁在说假话?"
try:
client = OpenAI(
api_key="你的API_KEY",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
completion = client.chat.completions.create(
model="qwen-plus", # 模型列表: https://help.aliyun.com/model-studio/getting-started/models
messages=[
{"role": "user", "content": math_cot_prompt}
]
)
print(completion.choices[0].message.content)
except Exception as e:
print(f"错误信息:{e}")
print("请参考文档:https://help.aliyun.com/model-studio/developer-reference/error-code")
-
解释:这里的
logic_cot_prompt构建了逻辑推理题的 CoT 提示,要求模型按步骤分析条件逻辑关系、阐述推理过程并得出结论。同样通过call_qwen函数调用通义千问 API 获取回答。 -
回答结果:
我们按照题目要求,分三步进行逻辑推理:**分析逻辑关系 → 阐述推理过程 → 得出结论**。
一、分析题目条件之间的逻辑关系
设:
- $ A $:甲说真话(即甲的陈述为真)
- $ B $:乙说真话
- $ C $:丙说真话
三人陈述如下(注意:每人说的是关于他人真假的断言,而非自身):
- **甲说:“乙在说谎”** → 即甲声称 $ \neg B $。
若甲说真话($ A $ 为真),则 $ \neg B $ 为真 ⇒ $ B $ 为假;
若甲说假话($ A $ 为假),则其陈述为假 ⇒ “乙在说谎”是假的 ⇒ 乙没说谎 ⇒ $ B $ 为真。
✅ 所以:**$ A \leftrightarrow \neg B $**(甲说真话当且仅当乙说假话)
- **乙说:“丙在说谎”** → 即乙声称 $ \neg C $。
同理可得:**$ B \leftrightarrow \neg C $**
- **丙说:“甲和乙都在说谎”** → 即丙声称 $ \neg A \land \neg B $。
若丙说真话($ C $ 为真),则 $ \neg A \land \neg B $ 为真 ⇒ $ A $ 假且 $ B $ 假;
若丙说假话($ C $ 为假),则其陈述为假 ⇒ $ \neg A \land \neg B $ 为假 ⇒ 即 $ A \lor B $ 为真(甲或乙至少一人说真话)。
✅ 所以:**$ C \leftrightarrow (\neg A \land \neg B) $**
综上,我们得到三个逻辑等价式:
1. $ A \leftrightarrow \neg B $
2. $ B \leftrightarrow \neg C $
3. $ C \leftrightarrow (\neg A \land \neg B) $
这是一个闭合的布尔逻辑系统,可通过代入或穷举验证。
二、阐述推理过程(采用假设检验法,严谨推导)
我们尝试枚举所有可能的 $ (A, B, C) $ 组合(共 $ 2^3 = 8 $ 种),检验哪些满足全部三个等价式。
| A | B | C | 检验① $A \leftrightarrow \neg B$ | 检验② $B \leftrightarrow \neg C$ | 检验③ $C \leftrightarrow (\neg A \land \neg B)$ | 全部成立? |
|---|---|---|-------------------------------|-------------------------------|---------------------------------------------|-----------|
| T | T | T | T ↔ F? ❌(F) | T ↔ F? ❌ | T ↔ (F ∧ F)=F? ❌ | 否 |
| T | T | F | T ↔ F? ❌ | T ↔ T? ✅ | F ↔ (F ∧ F)=F? ✅ | 否(①不成立)|
| T | F | T | T ↔ T? ✅ | F ↔ F? ✅ | T ↔ (F ∧ T)=F? ❌ | 否(③不成立)|
| T | F | F | T ↔ T? ✅ | F ↔ T? ❌ | F ↔ (F ∧ T)=F? ✅ | 否(②不成立)|
| F | T | T | F ↔ F? ✅ | T ↔ F? ❌ | T ↔ (T ∧ F)=F? ❌ | 否 |
| F | T | F | F ↔ F? ✅ | T ↔ T? ✅ | F ↔ (T ∧ F)=F? ✅ | **是!** ✅ |
| F | F | T | F ↔ T? ❌ | F ↔ F? ✅ | T ↔ (T ∧ T)=T? ✅ | 否(①不成立)|
| F | F | F | F ↔ T? ❌ | F ↔ T? ❌ | F ↔ (T ∧ T)=T? ❌ | 否 |
✅ 唯一满足全部三个条件的是第6行:**$ A = \text{假},\ B = \text{真},\ C = \text{假} $**
即:**甲说假话,乙说真话,丙说假话**
我们再用自然语言验证该结果是否自洽:
- 甲说“乙在说谎” → 但乙实际说真话,所以甲的话是**假的** → 符合 $ A = \text{假} $ ✔
- 乙说“丙在说谎” → 丙确实说假话,所以乙的话是**真的** → 符合 $ B = \text{真} $ ✔
- 丙说“甲和乙都在说谎” → 实际是甲说谎(✔),但乙说真话(✘),所以“都在说谎”为**假**;丙说了假话 → 符合 $ C = \text{假} $ ✔
完全自洽,无矛盾。
(补充说明:也可用代数推导——由① $ A = \neg B $,② $ B = \neg C $ ⇒ $ A = \neg(\neg C) = C $,即 $ A = C $;代入③:$ C \leftrightarrow (\neg A \land \neg B) $,因 $ A = C $,得 $ A \leftrightarrow (\neg A \land \neg B) $。左边为 $ A $,右边为 $ \neg A \land \neg B $,只有当 $ A = \text{假} $ 时右边才可能为真(需 $ \neg B = \text{真} $),但若 $ A = \text{假} $,右边为 $ \text{真} \land \neg B $,要使等价成立,右边也须为假 ⇒ $ \neg B = \text{假} $ ⇒ $ B = \text{真} $,从而 $ C = A = \text{假} $,与之前一致。)
三、得出结论
- **甲在说假话**(其声称“乙在说谎”是假的,乙实际说真话);
- **乙在说真话**(其声称“丙在说谎”为真,丙确实在说谎);
- **丙在说假话**(其声称“甲和乙都在说谎”是假的,因为乙说真话)。
✅ **唯一符合所有陈述逻辑的解是:只有乙说真话,甲和丙均说假话。**
(二)编写结构化输出 Prompt
- 代码实现:
from openai import OpenAI
# CoT Prompt - 结构化输出
math_cot_prompt = "请以JSON格式返回一个用户的信息,包含姓名、年龄、爱好和邮箱。姓名设定为‘李四’,年龄25岁,爱好是‘阅读、旅行’,邮箱是‘lisi@example.com’。"
try:
client = OpenAI(
api_key="你的API_KEY",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
completion = client.chat.completions.create(
model="qwen-plus", # 模型列表: https://help.aliyun.com/model-studio/getting-started/models
messages=[
{"role": "user", "content": math_cot_prompt}
]
)
print(completion.choices[0].message.content)
except Exception as e:
print(f"错误信息:{e}")
print("请参考文档:https://help.aliyun.com/model-studio/developer-reference/error-code")
-
解释:
structured_output_prompt构建了一个要求以 JSON 格式输出用户信息的提示。调用call_qwen函数获取通义千问返回的 JSON 格式结果,该结果可直接用于后续的系统集成或数据处理。 -
回答结果:
{
"姓名": "李四",
"年龄": 25,
"爱好": "阅读、旅行",
"邮箱": "lisi@example.com"
}
四、总结
通过今天的学习,我们详细了解了提示工程进阶中的思维链(CoT)和结构化输出技巧,并基于通义千问模型进行了实践。在实际应用中,合理运用这两种技巧能够使模型的输出更加符合业务需求,无论是复杂问题的逻辑推理,还是输出结果的便捷处理,都能得到有效提升。
如果在学习过程中遇到 API 调用失败或模型输出不符合预期的情况,可检查 API 密钥是否正确、请求参数设置是否合理,以及提示内容是否准确引导模型。不断尝试和优化,将有助于更好地掌握这些进阶技巧,为大语言模型的应用开发带来更多可能。
注意:请将"你的通义千问API密钥" 替换为真实的通义千问 API 地址和密钥。实际使用时,需根据通义千问的官方文档对请求参数和提示内容进行适当调整。
希望本文能帮助大家在提示工程的进阶之路上迈出坚实的步伐,欢迎大家在评论区分享学习心得与遇到的问题。
以上就是本次关于提示工程进阶(CoT + 结构化输出)的全部内容,感谢阅读!
更多推荐



所有评论(0)