从这节课开始,我们将对 LangChain 中的六大核心组件一一进行详细的剖析。
模型
位于 LangChain 框架的最底层,它是基于语言模型构建的应用的核心元素,因为所谓 LangChain 应用开发,就是以 LangChain 作为框架,通过 API 调用大模型来解决具体问题的过程。
整个 LangChain 框架的逻辑都是由 LLM 这个发动机来驱动的。没有模型,LangChain 这个框架也就失去了它存在的意义

Model I/O
我们可以把对模型的使用过程拆解成三块,分别是输入提示(对应图中的 Format)、调用模型(对应图中的 Predict)和输出解析(对应图中的 Parse)。这三块形成了一个整体,因此在 LangChain 中这个过程被统称为 Model I/O(Input/Output)

在模型 I/O 的每个环节,LangChain 都为咱们提供了模板和工具,快捷地形成调用各种语言模型的接口。
提示模板:使用模型的第一个环节是把提示信息输入到模型中,你可以创建 LangChain 模板,根据实际需求动态选择不同的输入,针对特定的任务和应用调整输入。
语言模型:LangChain 允许你通过通用接口来调用语言模型。这意味着无论你要使用的是哪种语言模型,都可以通过同一种方式进行调用,这样就提高了灵活性和便利性。
输出解析:LangChain 还提供了从模型输出中提取信息的功能。通过输出解析器,你可以精确地从模型的输出中获取需要的信息,而不需要处理冗余或不相关的数据,更重要的是还可以把大模型给回的非结构化文本,转换成程序可以处理的结构化数据
先来看看 LangChain 中提示模板的构建
提示模板
现在"提示工程"这个词特别流行,所谓 Prompt Engineering,就是专门研究对大语言模型的提示构建
希望为销售的每一种鲜花生成一段简介文案,那么每当你的员工或者顾客想了解某种鲜花时,调用该模板就会生成适合的文字
这个提示模板的生成方式如下:
ini
# 导入LangChain中的提示模板
from langchain.prompts import PromptTemplate
# 创建原始模板
template = """您是一位专业的鲜花店文案撰写员。\n
对于售价为 {price} 元的 {flower_name} ,您能提供一个吸引人的简短描述吗?
"""
# 根据原始模板创建LangChain提示模板
prompt = PromptTemplate.from_template(template)
# 打印LangChain提示模板的内容
print(prompt)
提示模板的具体内容如下:
ini
input_variables=['flower_name', 'price']
output_parser=None partial_variables={}
template='/\n您是一位专业的鲜花店文案撰写员。
\n对于售价为 {price} 元的 {flower_name} ,您能提供一个吸引人的简短描述吗?\n'
template_format='f-string'
validate_template=True
PromptTemplate 的 from_template 方法就是将一个原始的模板字符串转化为一个更丰富、更方便操作的 PromptTemplate 对象,这个对象就是 LangChain 中的提示模板。LangChain 提供了多个类和函数,也为各种应用场景设计了很多内置模板,使构建和使用提示变得容易
将会使用这个刚刚构建好的提示模板来生成提示,并把提示输入到大语言模型中
语言模型
LangChain 中支持的模型有三大类。
大语言模型(LLM) ,也叫 Text Model,这些模型将文本字符串作为输入,并返回文本字符串作为输出。Open AI 的 text-davinci-003、Facebook 的 LLaMA、ANTHROPIC 的 Claude,都是典型的 LLM。
聊天模型(Chat Model),主要代表 Open AI 的 ChatGPT 系列模型。这些模型通常由语言模型支持,但它们的 API 更加结构化。具体来说,这些模型将聊天消息列表作为输入,并返回聊天消息。
用语言模型,让模型帮我们写文案,并且返回文案的结果
python
import os
from pathlib import Path
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate
BASE_PATH = Path(__file__).resolve().parent
load_dotenv(BASE_PATH / ".env")
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
if not OPENAI_API_KEY:
raise RuntimeError("未读取到 OPENAI_API_KEY:请在脚本同级 .env 中设置 OPENAI_API_KEY=xxx")
# 创建 Prompt 模板
prompt = PromptTemplate.from_template(
"请为价格为 {price} 元的 {flower_name} 写一段优雅的销售文案。"
)
# 创建模型(关键:base_url + 模型名)
model = ChatOpenAI(
model="moonshot-v1-8k",
temperature=0,
openai_api_key=OPENAI_API_KEY,
openai_api_base="https://api.moonshot.cn/v1",
)
# 构造输入
input_text = prompt.format(flower_name="玫瑰", price="50")
# 调用模型
output = model.invoke(input_text)
print(output)
输出

复用提示模板,我们可以同时生成多个鲜花的文案。
ini
import os
from pathlib import Path
from dotenv import load_dotenv
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
BASE_PATH = Path(__file__).resolve().parent
load_dotenv(BASE_PATH / ".env")
# 设置 Moonshot API Key
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")
# 创建提示模板
template = """您是一位专业的鲜花店文案撰写员。
对于售价为 {price} 元的 {flower_name} ,请提供一个吸引人的简短描述。
"""
prompt = PromptTemplate.from_template(template)
# 创建 Moonshot Chat 模型
model = ChatOpenAI(
model="moonshot-v1-8k",
temperature=0.7,
base_url="https://api.moonshot.cn/v1",
)
# 多种花
flowers = ["玫瑰", "百合", "康乃馨"]
prices = ["50", "30", "20"]
# 批量生成文案
for flower, price in zip(flowers, prices):
input_prompt = prompt.format(flower_name=flower, price=price)
response = model.invoke(input_prompt)
print(response.content)
print("-" * 50)

LangChain 的优势所在:
我们只需要定义一次模板,就可以用它来生成各种不同的提示。对比单纯使用 f-string 来格式化文本,这种方法更加简洁,也更容易维护。而 LangChain 在提示模板中,还整合了 output_parser、template_format 以及是否需要 validate_template 等功能。
更重要的是,使用 LangChain 提示模板,我们还可以很方便地把程序切换到不同的模型,而不需要修改任何提示相关的代码。
输出解析
LangChain 提供的解析模型输出的功能,使你能够更容易地从模型输出中获取结构化的信息,这将大大加快基于语言模型进行应用开发的效率。
在开发具体应用的过程中,很明显我们不仅仅需要文字,更多情况下我们需要的是程序能够直接处理的、结构化的数据。
比如说,在这个文案中,如果你希望模型返回两个字段:
description:鲜花的说明文本 reason:解释一下为何要这样写上面的文案
那么,模型可能返回的一种结果是: A:"文案是:让你心动!50 元就可以拥有这支充满浪漫气息的玫瑰花束,让 TA 感受你的真心爱意。为什么这样说呢?因为爱情是无价的,50 元对应热恋中的情侣也会觉得值得。"
上面的回答并不是我们在处理数据时所需要的,我们需要的是一个类似于下面的 Python 字典。
B:{description: "让你心动!50 元就可以拥有这支充满浪漫气息的玫瑰花束,让 TA 感受你的真心爱意。" ; reason: "因为爱情是无价的,50 元对应热恋中的情侣也会觉得值得。"} 那么从 A 的笼统言语,到 B 这种结构清晰的数据结构,如何自动实现?这就需要 LangChain 中的输出解析器上场了。
通过 LangChain 的输出解析器来重构程序,让模型有能力生成结构化的回应,同时对其进行解析,直接将解析好的数据存入 CSV 文档。
ini
from langchain_core.output_parsers import JsonOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
import os
from pathlib import Path
import pandas as pd
from dotenv import load_dotenv
BASE_PATH = Path(__file__).resolve().parent
load_dotenv(BASE_PATH / ".env")
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")
# 使用 Moonshot
model = ChatOpenAI(
model="moonshot-v1-8k",
base_url="https://api.moonshot.cn/v1",
temperature=0.7
)
# JSON 解析器
parser = JsonOutputParser()
prompt = PromptTemplate.from_template(
"""您是一位专业的鲜花店文案撰写员。
对于售价为 {price} 元的 {flower_name} ,
请返回 JSON 格式:
{{
"description": "...",
"reason": "..."
}}
"""
)
flowers = ["玫瑰", "百合", "康乃馨"]
prices = ["50", "30", "20"]
df = pd.DataFrame(columns=["flower", "price", "description", "reason"])
for flower, price in zip(flowers, prices):
input_text = prompt.format(flower_name=flower, price=price)
response = model.invoke(input_text).content
parsed = parser.parse(response)
parsed["flower"] = flower
parsed["price"] = price
df.loc[len(df)] = parsed
print(df.to_dict(orient="records"))
df.to_csv("flowers_with_descriptions.csv", index=False)
输出结果
css
[{'flower': '玫瑰', 'price': '50', 'description': '精选玫瑰,绽放爱与浪漫。每一朵都是爱的使者,为您的情感传递增添一份独特魅力。', 'reason': '我们精心挑选的玫瑰,以其高雅的姿态和鲜艳的色彩,成为表达爱意的经典之选。它的价格合理,品质上乘,是您传递温馨祝福的不二之选。'}, {'flower': '百合', 'price': '30', 'description': '这款百合以其洁白无瑕的姿态和沁人心脾的香气,成为花店中的优雅之选。每一朵百合都经过精心挑选,确保其新鲜度和品质,为您的日常生活或特殊场合增添一抹清新与雅致。', 'reason': '30元的售价既体现了百合的高性价比,也反映了我们对顾客的真诚回馈。在保持亲民价格的同时,我们注重花卉的品质和顾客的购物体验,让您的每一分花费都物有所值。'}, {'flower': '康乃馨', 'price': '20', 'description': '康乃馨,以其优雅的姿态和温馨的色彩,被誉为母亲之花,象征着爱、魅力和尊敬。每一朵康乃馨都承载着对母亲的深情厚意,是表达感激和敬爱之情的完美选择。', 'reason': '售价20元的康乃馨,以其适中的价格和深远的情感寓意,成为送给母亲或特别女性的不二之选。它不仅代表着对她们的感激之情,也传递着温馨和尊重的信息,适合在母亲节、生日或其他特别场合表达心意。'}]