该教程旨在带大家从 0 起步,掌握用 Python 开发大模型应用的技能。若当前内容让你感到晦涩,可回溯本合集的前期文章,降低学习难度。
1. 为什么要学"输出解析器"?
没有解析器 | 有了解析器 |
---|---|
AI 想回啥就回啥,格式千奇百怪 | 让 AI 先立规矩再说话 |
正则/字符串切割写到崩溃 | 一行代码直接拿到 Python 对象 |
线上崩了才发现格式变了 | 解析失败就抛异常,提前暴露问题 |
2. CommaSeparatedListOutputParser(逗号列表解析器)
2.1. 它到底干啥?
• 给模型下指令 :请用英文逗号 ,
把答案分开
• 帮你解析 :把 "#ff0000,#00ff00,#0000ff"
直接变成 ['#ff0000','#00ff00','#0000ff']
2.2. 具体实践
2.2.1. 安装
pip install langchain langchain-deepseek
2.2.2. 创建解析器
Python
from langchain.output_parsers import CommaSeparatedListOutputParser
parser = CommaSeparatedListOutputParser()
# 打印看看解析器生成的"命令"长啥样
print(parser.get_format_instructions())
# 输出:Your response should be a list of items separated by commas...
2.2.3. 把"命令"塞进提示词
Python
from langchain.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages([
("system", "你是一名色彩设计师。{format_instructions}"),
("human", "请给出 5 个符合{theme}主题的背景色十六进制色号"),
])
2.2.4. 调用模型
Python
from langchain_deepseek import ChatDeepSeek
llm = ChatDeepSeek(model="deepseek-chat", temperature=0)
prompt_with_fmt = prompt.format_prompt(
format_instructions=parser.get_format_instructions(),
theme="夏季"
)
response = llm.invoke(prompt_with_fmt.to_messages())
colors = parser.parse(response.content)
print(colors) # ['#87CEEB', '#FFA07A', '#32CD32', '#FFD700', '#FF69B4']
3. PydanticOutputParser(JSON → Python 对象)
3.1. 它到底干啥?
• 给模型下指令 :请按 JSON Schema 输出
• 帮你解析 :把 JSON 字符串直接变成 Python 数据类(Pydantic 模型)
3.2. 具体实践
3.2.1. 定义"说明书"
Python
from typing import List
from pydantic import BaseModel, Field
class BookInfo(BaseModel):
book_name: str = Field(..., description="书名")
book_author: str = Field(..., description="作者")
genres: List[str] = Field(..., description="题材列表")
3.2.2. 创建解析器
Python
from langchain.output_parsers import PydanticOutputParser
parser = PydanticOutputParser(pydantic_object=BookInfo)
print(parser.get_format_instructions())
# 输出:The JSON should have fields "book_name", "book_author", "genres"...
3.2.3. 塞进提示词
Python
prompt = ChatPromptTemplate.from_messages([
("system", "从用户提供的原始文本中提取书籍信息。{format_instructions}"),
("human", "{raw_text}"),
])
3.2.4. 调用模型
Python
raw = "《三体》是刘慈欣写的硬核科幻巨作,涉及文明冲突和宇宙社会学。"
book: BookInfo = (prompt | llm | parser).invoke({"raw_text": raw})
print(book.book_name) # 三体
print(book.book_author) # 刘慈欣
print(book.genres) # ['科幻', '文明冲突', '宇宙社会学']
如果 AI 把字段拼错或类型不对,Pydantic 会立即抛出 ValidationError,帮你提前发现。
4. LangChain LCEL 管道写法(|
符号到底啥意思?)
4.1. 一句话理解
把 提示 → 调用模型 → 解析结果 像乐高一样串成一条链,数据从左到右自动流动。
4.2. 从最熟悉的 "函数组合" 开始
Python
# 传统写法
out = func3(func2(func1(data)))
# 管道写法
chain = func1 | func2 | func3
out = chain.invoke(data)
在 LangChain 里:
func1
是 PromptTemplatefunc2
是 LLMfunc3
是 OutputParser
4.3. 优点一览
场景 | 传统写法 | 管道写法 |
---|---|---|
加日志 | 手动包函数 | chain = chain.with_listeners(...) |
加缓存 | 手动写缓存 | chain = chain.with_cache() |
并行/批处理 | 手写循环 | chain.batch([...]) |
类型提示 | 弱 | 全程保持类型安全 |
4.4 最小可运行示例
Python
from langchain.prompts import ChatPromptTemplate
from langchain.output_parsers import CommaSeparatedListOutputParser
from langchain_deepseek import ChatDeepSeek
parser = CommaSeparatedListOutputParser()
prompt = ChatPromptTemplate.from_messages([
("system", "你是一名色彩设计师。{format_instructions}"),
("human", "请给出 3 个符合{theme}主题的背景色")
]).partial(format_instructions=parser.get_format_instructions())
llm = ChatDeepSeek(model="deepseek-chat", temperature=0)
# 一行完成 prompt → llm → parser
chain = prompt | llm | parser
colors = chain.invoke({"theme": "夏日清凉"})
print(colors) # ['#87CEEB', '#32CD32', '#FFD700']
5. 完整示例代码
5.1. 输出颜色列表
Python
from langchain.prompts import ChatPromptTemplate
from langchain.output_parsers import CommaSeparatedListOutputParser
from langchain_deepseek import ChatDeepSeek
def get_theme_colors_common(theme):
# 1. 创建解析器
parser = CommaSeparatedListOutputParser()
# 2. 构建提示词模版
prompt = ChatPromptTemplate.from_messages([
("system", "你是一名色彩设计师。{format_instructions}"),
("human", "请给出 5 个符合{theme}主题的背景色十六进制色号"),
])
# 3. 把解析器塞进模版
prompt_with_fmt = prompt.format_prompt(format_instructions=parser.get_format_instructions(), theme=theme)
llm = ChatDeepSeek(model="deepseek-chat", temperature=0)
# 4. 调用模型
response = llm.invoke(prompt_with_fmt.to_messages())
return parser.parse(response.content)
def get_theme_colors_pipeline(theme):
# 1. 创建解析器
parser = CommaSeparatedListOutputParser()
# 2. 构建提示词模版
prompt = ChatPromptTemplate.from_messages([
("system", "你是一名色彩设计师。{format_instructions}"),
("human", "请给出 5 个符合{theme}主题的背景色十六进制色号"),
])
# 3. 把解析器塞进模版
prompt_with_fmt = prompt.partial(format_instructions=parser.get_format_instructions())
llm = ChatDeepSeek(model="deepseek-chat", temperature=0)
# 4. 调用模型
chain = prompt_with_fmt | llm | parser
return chain.invoke({"theme": theme})
if __name__ == "__main__":
common_colors = get_theme_colors_common("夏季")
pipeline_colors = get_theme_colors_pipeline("夏季")
print(common_colors)
print(pipeline_colors)
5.2. 解析书籍信息
Python
from typing import List
from pydantic import BaseModel, Field
from langchain.output_parsers import PydanticOutputParser
from langchain_deepseek import ChatDeepSeek
from langchain.prompts import ChatPromptTemplate
class BookInfo(BaseModel):
book_name: str = Field(..., description="书名")
book_author: str = Field(..., description="作者")
genres: List[str] = Field(..., description="题材列表")
parser = PydanticOutputParser(pydantic_object=BookInfo)
prompt = ChatPromptTemplate.from_messages([
("system", "从用户提供的原始文本中提取书籍信息。{format_instructions}"),
("human", "{raw_text}"),
])
prompt_with_fmt = prompt.partial(format_instructions=parser.get_format_instructions())
llm = ChatDeepSeek(model="deepseek-chat", temperature=0)
raw = "《三体》是刘慈欣写的硬核科幻巨作,涉及文明冲突和宇宙社会学。"
book: BookInfo = (prompt_with_fmt | llm | parser).invoke({"raw_text": raw})
print(book.book_name)
print(book.book_author)
print(book.genres)