怎么让 AI 听懂你的话?LangChain 输入技巧全解析
文章目录
LangChain AI 模型的输入
LangChain 是一个用于构建基于大语言模型(LLM)应用的开源开发框架。它的名字由 “Lang”(语言)和 “Chain”(链)组成,核心思想是将大模型的能力像积木一样串联起来,构建复杂的 AI 应用。
核心组件:
┌─────────────────────────────────────────────────────────────────┐
│ LangChain 架构 │
├─────────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Models │ │ Prompts │ │ Memory │ │
│ │ 模型接口 │ │ 提示词模板 │ │ 记忆管理 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Chains │ │ Agents │ │ Tools │ │
│ │ 链式编排 │ │ 智能体 │ │ 工具调用 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ RAG │ │ Document │ │ Output │ │
│ │ 检索增强 │ │ 文档加载 │ │ 解析器 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────────┘
1. LangChain 零基础入门:从环境配置到成功调用大模型
你是否想用大模型构建自己的 AI 应用,却被复杂的环境配置搞得焦头烂额?本文将从零开始,带你一步步配置环境、解决各种坑,最终成功调用大模型。
1.1 环境配置:踩坑与解决
1.1.1 Python 版本问题
- 坑点:Python 3.14 太新,很多库不兼容
- 解决方案:如果安装多个版本,记得使用稳定的 Python 3.11
# 查看已安装的 Python 版本
py -0
# 输出示例:
# -V:3.14 * Python 3.14 (64-bit)
# -V:3.11 Python 3.11 (64-bit)
1.1.2 Jupyter 内核配置
- 坑点:Jupyter 仍在使用旧版本 Python
- 解决方案:为 Python 3.11 安装内核
# 安装 ipykernel
py -3.11 -m pip install ipykernel
# 注册内核
py -3.11 -m ipykernel install --user --name python311 --display-name "Python 3.11"
1.1.3 安装 LangChain
# 使用 Python 3.11 安装
py -3.11 -m pip install langchain-openai
1.1.4 验证安装
import sys
print(sys.executable) # 确认是 Python 3.11 路径
!{sys.executable} -m pip list | findstr langchain

1.1.5 导入路径的变化(重要踩坑)
旧版导入(已废弃):
from langchain.schema.messages import HumanMessage, SystemMessage # ❌ 报错
新版导入(正确):
from langchain_core.messages import HumanMessage, SystemMessage # ✅ 正确
原因:LangChain 新版本将核心模块独立为 langchain_core
1.1.6 完整的新旧版对照表
| 旧版导入 | 新版导入 |
|---|---|
from langchain.schema import HumanMessage |
from langchain_core.messages import HumanMessage |
from langchain.schema import SystemMessage |
from langchain_core.messages import SystemMessage |
from langchain.schema import AIMessage |
from langchain_core.messages import AIMessage |
from langchain.prompts import ChatPromptTemplate |
from langchain_core.prompts import ChatPromptTemplate |
from langchain.prompts import FewShotChatMessagePromptTemplate |
from langchain_core.prompts import FewShotChatMessagePromptTemplate |
from langchain.prompts import SystemMessagePromptTemplate |
from langchain_core.prompts import SystemMessagePromptTemplate |
from langchain.prompts import HumanMessagePromptTemplate |
from langchain_core.prompts import HumanMessagePromptTemplate |
from langchain.output_parsers import StrOutputParser |
from langchain_core.output_parsers import StrOutputParser |
1.2 完整代码示例
from langchain_openai import ChatOpenAI
model = ChatOpenAI(
model="gpt-3.5-turbo",
openai_api_key="你的API密钥",
openai_api_base="https://aigc789.top/v1"
)
from langchain_core.messages import HumanMessage, SystemMessage
print("导入成功!")
messages = [
SystemMessage(content="请你作为我的物理课助教,用通俗易懂且间接的语言帮我解释物理概念。"),
HumanMessage(content="什么是波粒二象性?"),
]
response = model.invoke(messages)
reponse
print(response.content)
运行结果:
波粒二象性其实是告诉我们,微观世界里的东西,比如光和电子,有时候表现得像波,有时候又表现得像粒子。你可以想象一下,像海浪一样的波动,能在空间中扩散、叠加和干涉,而小球一样的小粒子则有确定的位置和路径。
当我们用某种方法去观察这些微小东西时,它们有时会像波一样散开、产生纹理;而换一种观察方式,它们又会像小球一样,具有明确的位置。这个现象让我们知道,在很小的尺度上,传统认为的"波"和"粒子"其实不是固定的,而是两种不同的表现形式,是同一个东西的不同面貌。
换句话说,微观世界不完全像我们日常想象的那样简单。它既不像纯粹的波,也不像纯粹的粒子,而是这两者的一个奇妙结合。这个发现开启了现代量子物理的大门,也让我们重新认识了物质和能量的本质。

1.3 技术要点总结
| 技术点 | 说明 |
|---|---|
| Python 版本选择 | 使用 Python 3.11 可避免兼容性问题 |
| Jupyter 内核管理 | 通过 ipykernel 为不同 Python 版本创建独立内核 |
| 新版导入路径 | 使用 langchain_core.messages 而非 langchain.schema.messages |
| 双角色消息结构 | SystemMessage 设定角色,HumanMessage 输入问题 |
| API 调用封装 | LangChain 的 invoke 方法简化了 API 调用 |
1.4 应用场景扩展
该示例可直接应用于以下场景:
-
在线教育:构建智能辅导助手,帮助学生理解学科知识
-
企业培训:打造内部知识问答系统
-
客服系统:让大模型扮演专业客服
-
内容创作:辅助创作者快速理解专业概念
-
个人学习助手:随时解答学习中的疑问
2. LangChain 消息模板:让大模型输入更灵活
在实际的 AI 应用开发中,我们经常需要处理不同场景下的用户输入。如果每次都硬编码提示词,代码会变得臃肿且难以维护。LangChain 提供的消息模板(Message Prompt Template)功能,让我们可以像填空一样动态生成提示词,大大提升了代码的灵活性和可复用性。
2.1 完整代码示例和解析
from langchain_core.prompts import (
SystemMessagePromptTemplate,
AIMessagePromptTemplate,
HumanMessagePromptTemplate,
)
system_template_text = "你是一位专业的翻译,能够将{input_language}翻译成{output_language},并且输出文本会根据用户要求的任何语言风格进行调整。请只输出翻译后的文本,不要有任何其它内容。"
system_prompt_template = SystemMessagePromptTemplate.from_template(system_template_text)
system_prompt_template.input_variables
human_template_text = "文本:{text}\n语言风格:{style}"
human_prompt_template = HumanMessagePromptTemplate.from_template(human_template_text)
human_prompt_template.input_variables
system_prompt = system_prompt_template.format(input_language="英语", output_language="汉语")
system_prompt
human_prompt = human_prompt_template.format(text="I'm so hungry I could eat a horse", style="文言文")
human_prompt
from langchain_openai import ChatOpenAI
model = ChatOpenAI(model="gpt-3.5-turbo",
openai_api_key="你的API密钥",
openai_api_base="https://aigc789.top/v1")
response = model.invoke([
system_prompt,
human_prompt
])
print(response.content)
input_variables = [
{
"input_language": "英语",
"output_language": "汉语",
"text": "I'm so hungry I could eat a horse",
"style": "文言文"
},
{
"input_language": "法语",
"output_language": "英语",
"text": "Je suis désolé pour ce que tu as fait",
"style": "古英语"
},
{
"input_language": "俄语",
"output_language": "意大利语",
"text": "Сегодня отличная погода",
"style": "网络用语"
},
{
"input_language": "韩语",
"output_language": "日语",
"text": "너 정말 짜증나",
"style": "口语"
}
]
for input in input_variables:
response = model.invoke([
system_prompt_template.format(input_language=input["input_language"], output_language=input["output_language"]),
human_prompt_template.format(text=input["text"], style=input["style"])])
print(response.content)
2.1.1 导入消息模板类
from langchain_core.prompts import (
SystemMessagePromptTemplate,
AIMessagePromptTemplate,
HumanMessagePromptTemplate,
)
说明:
- SystemMessagePromptTemplate:系统消息模板,用于定义 AI 的角色和行为
- HumanMessagePromptTemplate:用户消息模板,用于定义用户输入的内容
- AIMessagePromptTemplate:AI 消息模板,用于构建对话历史(本例未使用)
为什么需要模板?
- 让提示词可以动态填充变量
- 避免重复编写相似的提示词
- 便于维护和修改
2.1.2 创建系统消息模板
system_template_text = "你是一位专业的翻译,能够将{input_language}翻译成{output_language},并且输出文本会根据用户要求的任何语言风格进行调整。请只输出翻译后的文本,不要有任何其它内容。"
system_prompt_template = SystemMessagePromptTemplate.from_template(system_template_text)
system_prompt_template.input_variables
# 输出:['input_language', 'output_language']
解析:
- {input_language} 和 {output_language} 是占位符变量
- from_template() 方法将文本转换为可复用的模板对象
- input_variables 属性显示模板中包含的变量列表
这个模板的作用:
- 告诉 AI 它的翻译任务
- 动态指定源语言和目标语言
- 约束输出格式(只输出翻译结果)
2.1.3 创建用户消息模板
human_template_text = "文本:{text}\n语言风格:{style}"
human_prompt_template = HumanMessagePromptTemplate.from_template(human_template_text)
human_prompt_template.input_variables
# 输出:['text', 'style']
解析:
- {text}:待翻译的文本
- {style}:翻译风格(文言文、古英语、网络用语等
2.1.4 模板格式化示例
system_prompt = system_prompt_template.format(input_language="英语", output_language="汉语")
print(system_prompt)
# 输出:你是一位专业的翻译,能够将英语翻译成汉语,并且输出文本会根据用户要求的任何语言风格进行调整。请只输出翻译后的文本,不要有任何其它内容。
human_prompt = human_prompt_template.format(text="I'm so hungry I could eat a horse", style="文言文")
print(human_prompt)
# 输出:
# 文本:I'm so hungry I could eat a horse
# 语言风格:文言文
关键点:
- 使用 format() 方法将变量替换为具体值
- 模板可以重复使用,只需传入不同的参数
2.1.5 单次调用模型
from langchain_openai import ChatOpenAI
model = ChatOpenAI(
model="gpt-3.5-turbo",
openai_api_key="你的API密钥",
openai_api_base="https://aigc789.top/v1"
)
response = model.invoke([
system_prompt,
human_prompt
])
print(response.content)
# 输出:吾饥甚,可啖一马。
流程说明:
- 创建模型实例
- 将格式化后的系统消息和用户消息组合成列表
- 调用 invoke() 方法发送给模型
- 打印模型返回的翻译结果
2.1.6 批量翻译任务列表
input_variables = [
{
"input_language": "英语",
"output_language": "汉语",
"text": "I'm so hungry I could eat a horse",
"style": "文言文"
},
{
"input_language": "法语",
"output_language": "英语",
"text": "Je suis désolé pour ce que tu as fait",
"style": "古英语"
},
{
"input_language": "俄语",
"output_language": "意大利语",
"text": "Сегодня отличная погода",
"style": "网络用语"
},
{
"input_language": "韩语",
"output_language": "日语",
"text": "너 정말 짜증나",
"style": "口语"
}
]
这个列表的作用:
- 定义了 4 个不同的翻译任务
- 每个任务包含:源语言、目标语言、原文、风格
- 展示了模板的灵活性——只需改变参数,就能处理不同的翻译场景
2.1.7 批量处理循环
for input in input_variables:
response = model.invoke([
system_prompt_template.format(
input_language=input["input_language"],
output_language=input["output_language"]
),
human_prompt_template.format(
text=input["text"],
style=input["style"]
)
])
print(response.content)
执行流程:
- 遍历 input_variables 列表中的每个任务
- 用当前任务的数据格式化系统消息模板
- 用当前任务的数据格式化用户消息模板
- 调用模型获取翻译结果
- 打印结果
输出示例:
吾饥甚,可啖一马。
For what thou hast done, I am sorry.
Oggi il tempo è fantastico! 💯🔥
本当にイライラするよ
2.2 技术要点总结
| 技术点 | 说明 |
|---|---|
| 消息模板类 | SystemMessagePromptTemplate、HumanMessagePromptTemplate 用于创建可动态格式化的提示词 |
| 占位符变量 | 使用 {变量名} 定义模板中的可变部分 |
| 模板复用 | 同一个模板可以多次使用,只需传入不同的参数 |
| 动态格式化 | 使用 format() 方法将变量替换为具体值 |
| 批量处理 | 通过列表和循环实现多个任务的自动化处理 |
| 灵活扩展 | 只需修改 input_variables 列表,即可处理新的翻译任务 |
2.3 应用场景扩展
该示例可应用于以下场景:
| 场景 | 说明 |
|---|---|
| 多语言翻译工具 | 支持任意语言对和风格的翻译 |
| 内容本地化 | 将产品文案批量翻译成多语言 |
| 风格化写作 | 根据指定风格改写文本 |
| 批量数据处理 | 处理大量相似格式的文本任务 |
| API 接口封装 | 构建灵活的翻译服务接口 |
3. LangChain Few-Shot 学习:往提示词里塞例子,让大模型学会格式规范
在开发 AI 应用时,我们经常需要让大模型按照特定格式输出内容。比如将用户输入的非结构化信息,格式化成标准化的客户信息卡片。
如果只给模型一句"请格式化客户信息",它可能输出各种乱七八糟的格式。这时就需要Few-Shot Learning(少样本学习)——在提示词中给模型几个示例,让它"照葫芦画瓢"。
下面将详细解析一个使用 LangChain 的 FewShotChatMessagePromptTemplate 实现客户信息格式化的代码,带你掌握"往提示词里塞例子"的核心技巧。
3.1 完整代码示例和解析
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
from langchain_core.prompts import FewShotChatMessagePromptTemplate, ChatPromptTemplate
# 1. 定义示例模板
example_prompt = ChatPromptTemplate.from_messages(
[
("human", "格式化以下客户信息:\n姓名 -> {customer_name}\n年龄 -> {customer_age}\n 城市 -> {customer_city}"),
("ai", "##客户信息\n- 客户姓名:{formatted_name}\n- 客户年龄:{formatted_age}\n- 客户所在地:{formatted_city}")
]
)
# 2. 提供具体示例
examples = [
{
"customer_name": "张三",
"customer_age": "27",
"customer_city": "长沙",
"formatted_name": "张三",
"formatted_age": "27岁",
"formatted_city": "湖南省长沙市"
},
{
"customer_name": "李四",
"customer_age": "42",
"customer_city": "广州",
"formatted_name": "李四",
"formatted_age": "42岁",
"formatted_city": "广东省广州市"
},
]
# 3. 创建 Few-Shot 模板
few_shot_template = FewShotChatMessagePromptTemplate(
example_prompt=example_prompt,
examples=examples,
)
# 4. 构建最终提示词
final_prompt_template = ChatPromptTemplate.from_messages(
[
few_shot_template,
("human", "{input}"),
]
)
# 5. 格式化提示词(注入用户输入)
final_prompt = final_prompt_template.invoke({"input": "格式化以下客户信息:\n姓名 -> 王五\n年龄 -> 31\n 城市 -> 郑州'"})
# 6. 查看格式化后的消息
print("=== 格式化后的提示词消息 ===")
for msg in final_prompt.messages:
print(f"{msg.__class__.__name__}: {msg.content[:50]}...")
# 7. 调用模型
model = ChatOpenAI(
model="gpt-3.5-turbo",
openai_api_key="你的API密钥",
openai_api_base="https://aigc789.top/v1"
)
response = model.invoke(final_prompt)
print("\n=== 模型输出 ===")
print(response.content)
3.1.1 导入必要模块
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
from langchain_core.prompts import FewShotChatMessagePromptTemplate, ChatPromptTemplate
| 模块 | 作用 |
|---|---|
| ChatOpenAI | OpenAI 模型封装 |
| HumanMessage | 用户消息类型(本例实际未直接使用) |
| FewShotChatMessagePromptTemplate | Few-Shot 提示词模板,用于插入示例 |
| ChatPromptTemplate | 通用聊天提示词模板 |
3.1.2 定义示例模板
example_prompt = ChatPromptTemplate.from_messages(
[
("human", "格式化以下客户信息:\n姓名 -> {customer_name}\n年龄 -> {customer_age}\n 城市 -> {customer_city}"),
("ai", "##客户信息\n- 客户姓名:{formatted_name}\n- 客户年龄:{formatted_age}\n- 客户所在地:{formatted_city}")
]
)
这是核心部分
定义了一个对话模板,包含两轮对话:
- Human 消息:用户提供的原始信息(包含占位符)
- AI 消息:模型应该输出的格式化结果(包含占位符)
占位符变量:
{customer_name}、{customer_age}、{customer_city}:原始输入{formatted_name}、{formatted_age}、{formatted_city}:格式化后的输出
作用:告诉模型"当用户给我这种格式的输入,我应该输出那种格式的结果"
3.1.3 提供具体示例
examples = [
{
"customer_name": "张三",
"customer_age": "27",
"customer_city": "长沙",
"formatted_name": "张三",
"formatted_age": "27岁",
"formatted_city": "湖南省长沙市"
},
{
"customer_name": "李四",
"customer_age": "42",
"customer_city": "广州",
"formatted_name": "李四",
"formatted_age": "42岁",
"formatted_city": "广东省广州市"
},
]
每个示例都是一个字典,包含模板中所有占位符的具体值:
| 占位符 | 示例1值 | 示例2值 |
|---|---|---|
customer_name |
张三 | 李四 |
customer_age |
27 | 42 |
customer_city |
长沙 | 广州 |
formatted_name |
张三 | 李四 |
formatted_age |
27岁 | 42岁 |
formatted_city |
湖南省长沙市 | 广东省广州市 |
关键点:formatted_city 不是简单的城市名,而是扩展后的完整地址(省+市),这正是我们希望模型学习的能力!
3.1.4 创建 Few-Shot 模板
few_shot_template = FewShotChatMessagePromptTemplate(
example_prompt=example_prompt,
examples=examples,
)
- 将示例模板和具体示例组合
- 这个模板的作用是:根据 examples 自动生成多轮对话示例
生成的对话示例:
用户:格式化以下客户信息:
姓名 -> 张三
年龄 -> 27
城市 -> 长沙
助手:##客户信息
- 客户姓名:张三
- 客户年龄:27岁
- 客户所在地:湖南省长沙市
用户:格式化以下客户信息:
姓名 -> 李四
年龄 -> 42
城市 -> 广州
助手:##客户信息
- 客户姓名:李四
- 客户年龄:42岁
- 客户所在地:广东省广州市
3.1.5 构建最终提示词
final_prompt_template = ChatPromptTemplate.from_messages(
[
few_shot_template,
("human", "{input}"),
]
)
- 将 Few-Shot 示例和新的用户输入组合
- {input} 是最终的占位符,用于接收用户的新问题
3.1.6 格式化提示词
final_prompt = final_prompt_template.invoke({"input": "格式化以下客户信息:\n姓名 -> 王五\n年龄 -> 31\n 城市 -> 郑州'"})
- 将用户输入注入模板
- 生成完整的消息列表,包含:
- 2 组示例对话
- 1 条新的用户消息
3.1.7 查看格式化后的消息
print("=== 格式化后的提示词消息 ===")
for msg in final_prompt.messages:
print(f"{msg.__class__.__name__}: {msg.content[:50]}...")
输出示例:
=== 格式化后的提示词消息 ===
HumanMessage: 格式化以下客户信息:
姓名 -> 张三
年龄 -> 27
城市 -> 长沙...
AIMessage: ##客户信息
- 客户姓名:张三
- 客户年龄:27岁
- 客户所在地:湖南省长沙市...
HumanMessage: 格式化以下客户信息:
姓名 -> 李四
年龄 -> 42
城市 -> 广州...
AIMessage: ##客户信息
- 客户姓名:李四
- 客户年龄:42岁
- 客户所在地:广东省广州市...
HumanMessage: 格式化以下客户信息:
姓名 -> 王五
年龄 -> 31
城市 -> 郑州'...
3.1.8 调用模型
model = ChatOpenAI(model="gpt-3.5-turbo", ...)
response = model.invoke(final_prompt)
print(response.content)
模型输出示例:
##客户信息
- 客户姓名:王五
- 客户年龄:31岁
- 客户所在地:河南省郑州市

模型学会了:
- 输出格式:使用 ##客户信息 标题和 - 列表
- 年龄添加"岁"后缀
- 城市扩展为"省+市"格式(郑州 → 河南省郑州市)
3.2 技术要点总结
| 技术点 | 说明 |
|---|---|
| 示例模板 | 定义输入输出格式,告诉模型"输入什么样,输出什么样" |
| 具体示例 | 提供真实数据,让模型学习具体的转换规则 |
| FewShotChatMessagePromptTemplate | 自动将示例转换为多轮对话消息 |
| 模板组合 | 将 Few-Shot 示例和用户输入组合成完整提示词 |
| 占位符变量 | 使用 {变量名} 实现模板参数化 |
3.3 Few-Shot 学习的工作原理
┌─────────────────────────────────────────────────────────┐
│ 最终提示词 │
├─────────────────────────────────────────────────────────┤
│ 示例1: │
│ 用户:格式化以下客户信息:姓名 -> 张三,年龄 -> 27... │
│ 助手:##客户信息 - 客户姓名:张三 - 客户年龄:27岁... │
│ │
│ 示例2: │
│ 用户:格式化以下客户信息:姓名 -> 李四,年龄 -> 42... │
│ 助手:##客户信息 - 客户姓名:李四 - 客户年龄:42岁... │
│ │
│ 新问题: │
│ 用户:格式化以下客户信息:姓名 -> 王五,年龄 -> 31... │
│ │
│ 模型根据示例学习到格式规则,输出: │
│ ##客户信息 - 客户姓名:王五 - 客户年龄:31岁... │
└─────────────────────────────────────────────────────────┘
3.4 为什么需要 Few-Shot?
| 方式 | 优点 | 缺点 |
|---|---|---|
| Zero-Shot(无示例) | 简单 | 输出格式不稳定 |
| Few-Shot(有示例) | 格式规范、可控性强 | 消耗更多 Token |
| Fine-tuning(微调) | 效果最好 | 成本高、需要训练数据 |
Few-Shot 是性价比最高的选择:用少量示例就能获得稳定输出,无需训练。
3.5 应用场景扩展
| 场景 | 说明 |
|---|---|
| 数据格式化 | 将非结构化文本转换为结构化数据 |
| 代码生成 | 给模型示例,让它按特定风格生成代码 |
| 报告生成 | 学习报告模板,自动生成标准化报告 |
| 邮件撰写 | 学习邮件格式,自动生成商务邮件 |
| 客服回复 | 学习回复模板,自动生成标准客服回复 |
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)