先我们直接问大模型看他如何回答

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

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

2

3

4

5

6

7

8

9

10

11

李白和白居易的寿命对比如下:

1. **李白(701年-762年)** 

   - 享年约61岁(虚岁62岁)。 

   - 去世原因:普遍认为是病逝,但也有“醉后捞月溺亡”的民间传说。 

2. **白居易(772年-846年)** 

   - 享年74岁(虚岁75岁),在唐代诗人中属长寿。 

   - 晚年生活:辞官隐居洛阳,笃信佛教,生活闲适。 

**结论**:白居易比李白多活约13年,寿命更长。两人虽同属唐代,但白居易出生时李白已去世10年,二者并无交集。

 那么如何引导大模型按照我们期望的结果输出呢?代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

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)转为纯文本
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐