想让大模型回答问题具有推理步骤如何实现?比如问大模型 李白和白居易谁活得的更久?这个问题,我们期望他按照如下这种格式回答:
问:李白去世时的年龄是多少?
答案:李白去世时61岁。
问:白居易去世时的年龄是多少?
答案:白居易去世时74岁。
所以最终答案是:白居易
首先我们直接问大模型看他如何回答
from langchain_openai import ChatOpenAI
import os
from dotenv import load_dotenv
llm = ChatOpenAI(
api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url=os.getenv("DEEP_URL"), # Deepseek 的 API 基础地址
model="deepseek-v3:671b", # Deepseek 对话模型(可选:deepseek-chat-pro 等高级模型)
temperature=0.7, # 温度参数(0-1,越低越稳定)
max_tokens=1024 # 最大生成 tokens
)
response = llm.invoke('李白和白居易谁活得的更久?')
print(response.content)
结果如下:
李白和白居易的寿命对比如下:
1. **李白(701年-762年)**
- 享年约61岁(虚岁62岁)。
- 去世原因:普遍认为是病逝,但也有“醉后捞月溺亡”的民间传说。
2. **白居易(772年-846年)**
- 享年74岁(虚岁75岁),在唐代诗人中属长寿。
- 晚年生活:辞官隐居洛阳,笃信佛教,生活闲适。
**结论**:白居易比李白多活约13年,寿命更长。两人虽同属唐代,但白居易出生时李白已去世10年,二者并无交集。
那么如何引导大模型按照我们期望的结果输出呢?代码如下:
from langchain.prompts.few_shot import FewShotPromptTemplate
from langchain.prompts.prompt import PromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
import os
# 定义少样本学习(Few-Shot Learning)中的示例列表
# 每个示例包含一个复杂问题及其结构化的多步推理答案
# 目的是教会模型:面对需要多跳推理的问题时,应如何分解问题、逐步追问并整合答案
examples = [
{
"question": "乾隆和曹操谁活得更久?",
"answer": """
这里是否需要跟进问题:是的。
追问:乾隆去世时几岁?
中间答案:乾隆去世时87岁。
追问:曹操去世时几岁?
中间答案:曹操去世时66岁。
所以最终答案是:乾隆
""",
},
{
"question": "小米手机的创始人什么时候出生?",
"answer": """
这里是否需要跟进问题:是的。
追问:小米手机的创始人是谁?
中间答案:小米手机 由 雷军 创立。
跟进:雷军什么时候出生?
中间答案:雷军出生于 1969 年 12 月 16 日。
所以最终的答案是:1969 年 12 月 16 日
""",
},
{
"question": "乔治·华盛顿的外祖父是谁?",
"answer": """
这里是否需要跟进问题:是的。
追问:乔治·华盛顿的母亲是谁?
中间答案:乔治·华盛顿的母亲是玛丽·鲍尔·华盛顿。
追问:玛丽·鲍尔·华盛顿的父亲是谁?
中间答案:玛丽·鲍尔·华盛顿的父亲是约瑟夫·鲍尔。
所以最终答案是:约瑟夫·鲍尔
""",
},
{
"question": "《大白鲨》和《皇家赌场》的导演是同一个国家的吗?",
"answer": """
这里是否需要跟进问题:是的。
追问:《大白鲨》的导演是谁?
中间答案:《大白鲨》的导演是史蒂文·斯皮尔伯格。
追问:史蒂文·斯皮尔伯格来自哪里?
中间答案:美国。
追问:皇家赌场的导演是谁?
中间答案:《皇家赌场》的导演是马丁·坎贝尔。
跟进:马丁·坎贝尔来自哪里?
中间答案:新西兰。
所以最终的答案是:不会
""",
},
]
# 定义单个示例的格式模板
# 将每个 example 中的 question 和 answer 按照指定格式拼接
example_prompt = PromptTemplate(
input_variables=["question", "answer"], # 声明模板中使用的变量名
template="Question: {question}\n{answer}" # 实际的文本模板
)
print('---------')
# 构建完整的少样本提示模板(Few-Shot Prompt Template)
# 该模板会自动将 examples 按 example_prompt 格式拼接,并在末尾追加用户输入的问题
prompt = FewShotPromptTemplate(
examples=examples, # 提供的示例列表
example_prompt=example_prompt, # 单个示例的格式
suffix="Question: {input}", # 用户实际输入问题的位置(占位符为 {input})
input_variables=["input"], # 声明整个提示模板接收的输入变量名
)
# 打印生成的完整提示词,用于调试或查看模型实际看到的上下文
print('--------提示词begin--------')
print(prompt.format(input="李白和白居易谁活得的更久?"))
print('--------提示词end--------')
# 配置大语言模型(LLM)参数,使用 DeepSeek 的 API(兼容 OpenAI 接口)
llm = ChatOpenAI(
api_key=os.getenv("DEEPSEEK_API_KEY"), # 从环境变量读取 API 密钥(更安全)
base_url=os.getenv("DEEP_URL"), # 从环境变量读取 DeepSeek 的 API 基础地址
model="deepseek-v3:671b", # 指定使用的模型名称
temperature=0.7, # 控制生成文本的随机性(0~1,值越高越有创造性)
max_tokens=1024 # 限制模型最大输出长度(以 token 为单位)
)
# 创建输出解析器,将模型返回的 AIMessage 对象解析为纯字符串
output_parser = StrOutputParser()
# 使用 LangChain 的管道操作符(|)构建处理链:
# 输入 → 提示模板 → 大模型 → 输出解析 → 最终字符串结果
chain = prompt | llm | output_parser
# 调用链式流程,传入用户问题:“李白和白居易谁活得的更久?”
response = chain.invoke({"input": "李白和白居易谁活得的更久?"})
# 打印模型生成的最终回答
print('--------最终回答--------')
print(response)
--------最终回答--------
这里是否需要跟进问题:是的。
追问:李白去世时几岁?
中间答案:李白去世时61岁。
追问:白居易去世时几岁?
中间答案:白居易去世时75岁。
所以最终答案是:白居易
一、核心目标
教会大语言模型(LLM)如何分步思考 ,解决需要多步推理 (Multi-hop Reasoning)的复杂问题
二、关键技术点
1. 少样本提示(Few-Shot Prompting)
- 概念 :在提示词中提供几个"输入-输出"示例,引导模型模仿回答格式和推理逻辑。
- 作用 :无需微调模型,仅通过提示工程(Prompt Engineering)提升复杂任务表现。
- 实现工具 :
langchain.prompts.few_shot.FewShotPromptTemplate
2. 结构化推理模板设计
- 每个示例包含清晰的推理链条:
- 判断是否需要追问("这里是否需要跟进问题:是的。")
- 分步提出子问题("追问:...")
- 给出中间答案("中间答案:...")
- 最终整合结论("所以最终答案是:...")
- 目的 :让模型学会"先分解问题 → 再逐步求解 → 最后综合答案"的思维模式。
3. LangChain 提示模板组合
PromptTemplate:定义单个示例的格式(如"Question: {question}\n{answer}")FewShotPromptTemplate:自动拼接多个示例 + 用户问题,生成完整提示- 支持动态插入用户输入(通过
{input}占位符)
4. 大模型调用与安全配置
- 使用
ChatOpenAI调用兼容 OpenAI API 的第三方模型(如 DeepSeek) - 关键参数 :
temperature=0.7:平衡创造性与稳定性max_tokens=1024:控制输出长度
- 安全实践 :通过
os.getenv()从环境变量读取 API 密钥,避免硬编码
5. 链式处理(Chain)与输出解析
- 构建数据流管道:
输入 → 提示模板 → 大模型 → 字符串解析 → 最终结果 - 使用
|操作符连接组件(LangChain 的函数式风格) StrOutputParser():将模型返回的结构化消息(如 AIMessage)转为纯文本
到这大家应该感觉到,大模型就是玩提示词(因为大模型本生我们个人是无法左右他的能力,都依赖于大厂,他们发布什么我们用什么),
提示词如何写决定了你AI应用的能力,后面我们会继续玩提示词,敬请期待。