【零基础入门 LLM 开发 · Day 10】:LangChain 入门------一条管道符串起 prompt 和模型
前九天苦在哪?
用原生 SDK 九天下来,你可能已经发现:每次都要手写 client 初始化、手拼 messages 列表、手取 choices[0].message.content......这些都是重复劳动。
LangChain 就是把这些重复劳动打包成"积木"的框架:prompt 是积木、模型是积木,你用管道符把它们串成流水线。
安装与三个包名
bash
pip install langchain-openai
初学者最容易晕的包名关系:
langchain-core:核心抽象(PromptTemplate、消息类型、LCEL),装别的会自动带上;langchain-openai:OpenAI 系模型的接入层;langchain:全家桶(含各种链、Agent 等)。
完整代码
python
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
load_dotenv()
# 初始化模型(对比 Day 1:参数类似,但不再需要手写 client)
llm = ChatOpenAI(
model=os.getenv("YUMC_MODEL_NAME"),
api_key=os.getenv("YUMC_MODEL_API_KEY"),
base_url=os.getenv("YUMC_MODEL_BASE_URL"),
temperature=0.7,
)
# 提示词模板:{user_input} 是变量占位符
prompt = ChatPromptTemplate.from_messages(
[
("system", "你是一个由YumCode 驱动的智能助手."),
("human", "{user_input}")
]
)
# LCEL:用管道符把积木串成链
chain = prompt | llm
if __name__ == "__main__":
try:
response = chain.invoke({"user_input": "你好,请简单介绍一下你自己"})
print("-----模型回复-----")
print(response.content)
except Exception as e:
print(f"调用失败:{e}")
print("提示:请检查 .env 中的URL 是否可以在当前网络环境下访问。")
逐段拆解
① ChatPromptTemplate.from_messages
用元组列表定义多角色提示词:("system", ...) / ("human", ...)。{user_input} 是占位符,调用时填值------这就是"模板",人设写一次,问题每次换。
② chain = prompt | llm(今天的核心!)
这是 LangChain 最出名的语法 LCEL(LangChain Expression Language):
prompt | llm读作"prompt 的输出,流进 llm 当输入";- 类似 Linux 管道:
cat 文件 | grep 关键词; - 数据流向:
{"user_input": "..."}→ 模板填空变成完整 messages → 交给模型 → 返回结果。
以后链子可以越接越长:prompt | llm | 输出解析器 | 另一个模型------流水线思维。
③ chain.invoke(...)
统一入口:传一个字典,键就是模板里的占位符名。返回的 response.content 和 Day 1 一样,只是不用再翻 choices[0] 了。
④ try/except
网络请求随时可能失败,正式代码永远包一层异常处理,别让用户看到红色堆栈。
原生 SDK vs LangChain 对照表
| 任务 | 原生 SDK(Day 1-9) | LangChain(今天起) |
|---|---|---|
| 初始化模型 | OpenAI(api_key, base_url) |
ChatOpenAI(model, api_key, base_url) |
| 组装对话 | 手拼 messages 列表 |
ChatPromptTemplate 模板 |
| 调用 | client.chat.completions.create(...) |
chain.invoke({...}) |
| 取回复 | resp.choices[0].message.content |
response.content |
今日踩坑点
- 占位符是单花括号
{user_input}:Day 13 会遇到要输出 JSON 的情况,那时花括号必须写成{``{ }}转义------先记住这颗雷。 chain.invoke传的不是字符串而是字典 :invoke("你好")会报错,键名必须和占位符一致。- model 参数忘了配 :
ChatOpenAI不传 model 会有默认值(gpt-3.5 之类),连你自己的服务会 404。
今日小练习
- 必做:把 system 改成你想要的助手人设,再给模板加一个
{style}占位符控制语气(如"正式"/"沙雕")。 - 进阶:用原生 SDK 重写一遍同样的功能,对比两种写法的代码量,体会框架到底帮你省了什么。
明日预告
Day 11:LangChain 的流式输出------比 Day 5 手动拼 delta 简单得多,一行 for 搞定。
附录:完整练习代码
langchainTest.py
python
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
#加载环境变量
load_dotenv()
# 初始化模型
llm = ChatOpenAI(
model = os.getenv("YUMC_MODEL_NAME"),
api_key = os.getenv("YUMC_MODEL_API_KEY"),
base_url = os.getenv("YUMC_MODEL_BASE_URL"),
temperature=0.7,
)
prompt = ChatPromptTemplate.from_messages(
[
("system","你是一个由YumCode 驱动的智能助手."),
("human","{user_input}")
]
)
chain = prompt | llm
if __name__ == "__main__":
try:
response = chain.invoke({"user_input":"你好,请简单介绍一下你自己"})
print("-----模型回复-----")
print(response.content)
except Exception as e:
print(f"调用失败:{e}")
print("提示:请检查 .env 中的URL 是否可以再当前网络环境下访问。")