从手写提示词到结构化数据一文搞定LangChain核心输出解析 引言在开发大模型应用时我们常常面临两个核心问题如何高效地组织和管理提示词Prompt—— 避免代码中到处拼接字符串如何让模型返回程序可直接使用的结构化数据—— 而不是自然语言段落LangChain 提供了完善的解决方案PromptTemplate系列管理输入OutputParser系列处理输出。本文将带你从零开始掌握这两大模块并完成多个实战案例。一、Prompt 基础与模板1.1 什么是 PromptPrompt就是给模型的指令。简单示例python请用中文介绍一下LangChain。但在实际项目中Prompt 往往包含角色设定、任务描述、输入数据和约束条件python system 你是一名资深技术顾问擅长用通俗语言解释复杂概念。 human 请向非技术人员介绍LangChain字数控制在200字以内。如果每次都在代码中拼接会产生大量重复和易错代码。Prompt 模板将固定部分与变量分离提高复用性和可维护性。1.2 PromptTemplate纯文本模板适用于不需要区分系统/用户角色的简单文本任务。python from langchain_core.prompts import PromptTemplate template PromptTemplate.from_template( 请为产品{product_name}写一句广告语突出{feature}。 ) prompt template.invoke({product_name: 智能手环, feature: 超长续航}) print(prompt) # 输出请为产品智能手环写一句广告语突出超长续航。1.3 ChatPromptTemplate聊天消息模板推荐使用因为它可以构建结构化的消息列表SystemMessage / HumanMessage / AIMessage更符合现代对话模型的输入习惯。python from langchain_core.prompts import ChatPromptTemplate chat_template ChatPromptTemplate.from_messages([ (system, 你是一位{role}回答要简洁专业。), (human, {question}) ]) prompt_value chat_template.invoke({ role: AI产品经理, question: 什么是RAG }) # 内部会生成 [SystemMessage, HumanMessage]模板类型输出形式适用场景PromptTemplate纯字符串简单文本生成无角色区分ChatPromptTemplate消息列表聊天、Agent、多轮对话二、Prompt 编写最佳实践掌握以下四个原则就能写出高质量的 Prompt明确角色—— 让模型以特定身份思考明确任务—— 说清楚要做什么明确约束—— 限制输出格式、字数、风格给出输入字段—— 让模型清楚每个变量的含义三、实战案例Prompt 篇案例1商品文案生成器根据商品信息自动生成电商文案。代码01_product_copywriter.pypython from langchain_core.prompts import ChatPromptTemplate from utils.model_factory import get_deepSeek_model model get_deepSeek_model() template ChatPromptTemplate.from_messages([ (system, 你是一名资深电商文案写手擅长用吸引人的语言描述产品。), (human, 请为以下商品撰写一段电商文案150字以内包含标题和卖点。 商品名称{name} 核心卖点{feature} 适用人群{target} ) ]) prompt template.invoke({ name: 智能保温杯, feature: 24小时保温智能测温健康提醒, target: 注重健康的办公族 }) response model.invoke(prompt) print(response.content)案例2学习计划生成器根据学习目标生成分阶段计划。代码02_study_plan.pypython from langchain_core.prompts import ChatPromptTemplate from utils.model_factory import get_deepSeek_model model get_deepSeek_model() template ChatPromptTemplate.from_messages([ (system, 你是一位资深学习规划师。), (human, 为以下学习目标制定一份为期{days}天的学习计划。 目标{goal} 当前水平{level} 每日可用时间{hours}小时 请按阶段列出每日任务并给出学习建议。 ) ]) prompt template.invoke({ goal: 从零开始学习Python数据分析, days: 30, level: 零基础, hours: 2 }) response model.invoke(prompt) print(response.content)案例3客服回复生成器模拟根据用户问题和订单信息生成回复。代码03_customer_reply.pypython from langchain_core.prompts import ChatPromptTemplate from utils.model_factory import get_deepSeek_model model get_deepSeek_model() template ChatPromptTemplate.from_messages([ (system, 你是一名专业客服回复要礼貌且解决问题。), (human, 用户问题{question} 订单状态{status} 物流信息{logistics} 请生成一段客服回复给出明确解决方案。 ) ]) prompt template.invoke({ question: 我的快递显示签收但我没收到, status: 已签收, logistics: 2025-01-15 10:00 已由门卫代收 }) response model.invoke(prompt) print(response.content)四、MessagesPlaceholder插入多轮对话历史在构建聊天应用时经常需要将历史消息插入到模板中。MessagesPlaceholder专门用于此。python from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder prompt ChatPromptTemplate.from_messages([ (system, 你是一个乐于助人的AI助手。), MessagesPlaceholder(history, optionalTrue, n_messages4), # 最多保留4条 (human, {question}) ]) history [ (human, 我叫小明), (ai, 你好小明有什么可以帮你), (human, 我喜欢Python), (ai, Python是很好的语言) ] prompt_value prompt.invoke({ history: history, question: 我刚才说了什么 }) # 实际只会插入最近4条历史消息如果超过参数说明variable_name输入变量名optional是否必须传入默认Falsen_messages最多保留最近几条消息五、结构化输出让程序读懂模型结果模型返回的自然语言虽然易读但程序难以直接处理。我们需要让模型输出JSON或其他结构化格式。5.1 StrOutputParser简单的字符串提取如果只想要纯文本内容StrOutputParser可以将AIMessage转为普通字符串并支持管道组合。python from langchain_core.output_parsers import StrOutputParser from langchain_core.prompts import ChatPromptTemplate model get_deepSeek_model() parser StrOutputParser() chain ChatPromptTemplate.from_template(翻译成中文{text}) | model | parser result chain.invoke({text: LangChain is awesome!}) print(result) # 直接打印字符串为什么不用response.content在管道|中每个组件必须是Runnable而.content是属性不是 Runnable。StrOutputParser正是为了合规接入管道。5.2 Pydantic 定义输出结构使用Pydantic声明期望的字段及类型让模型按此格式返回。python from pydantic import BaseModel, Field from typing import Literal class ResumeInfo(BaseModel): name: str Field(description候选人姓名) years_of_experience: int Field(description工作年限) skills: list[str] Field(description掌握的技术技能) target_position: str Field(description目标岗位)5.3 PydanticOutputParser手动解析该解析器会根据 Pydantic 模型生成格式说明get_format_instructions()并嵌入 Prompt最后将模型输出解析成对象。案例简历信息抽取 (02_resume_extractor.py)python from langchain_core.output_parsers import PydanticOutputParser from langchain_core.prompts import ChatPromptTemplate from pydantic import BaseModel, Field from utils.model_factory import get_deepSeek_model model get_deepSeek_model() class ResumeInfo(BaseModel): name: str Field(description姓名) years_of_experience: int Field(description工作年限) skills: list[str] Field(description掌握的技术技能) target_position: str Field(description目标岗位) parser PydanticOutputParser(pydantic_objectResumeInfo) format_instructions parser.get_format_instructions() template ChatPromptTemplate.from_messages([ (system, 你是一名招聘分析助手。\n{format_instructions}), (human, {resume_content}) ]) resume_text 我叫张三工作10年擅长Python、LangChain、FastAPI想找智能体开发岗位。 prompt template.invoke({ format_instructions: format_instructions, resume_content: resume_text }) response model.invoke(prompt) result parser.invoke(response) print(result.name) # 张三 print(result.years_of_experience) # 10 print(result.skills) # [Python, LangChain, FastAPI] print(result.target_position) # 智能体开发5.4 with_structured_output更简洁的方式如果模型服务支持如 OpenAI、DeepSeek 的 JSON 模式可以直接在模型上绑定输出结构。python structured_model model.with_structured_output(ResumeInfo, methodjson_mode) result structured_model.invoke(从简历中提取信息...) # 返回的 result 就是 ResumeInfo 实例注意使用 DeepSeek 时需指定methodjson_mode否则会报错。案例商品评论分析 (03_review_analyzer.py)python from typing import Literal from langchain_core.prompts import ChatPromptTemplate from pydantic import BaseModel, Field from utils.model_factory import get_deepSeek_model class ReviewAnalysis(BaseModel): sentiment: Literal[正面, 负面, 中性] Field(description情感倾向) keywords: list[str] Field(description关键词) summary: str Field(description评论总结) needs_reply: bool Field(description是否需要商家回复) model get_deepSeek_model() structured_model model.with_structured_output(ReviewAnalysis, methodjson_mode) template ChatPromptTemplate.from_messages([ (system, 你是评论分析专家严格按JSON格式输出。), (human, 分析评论{review}) ]) prompt template.invoke({ review: 鼠标手感不错也很安静但是用了两周滚轮就有异响。 }) result structured_model.invoke(prompt) print(result.sentiment) # 负面 print(result.keywords) # [手感, 安静, 滚轮异响] print(result.summary) # 用户认可手感但反映滚轮质量问题 print(result.needs_reply)# True案例工单分类 (04_ticket_classifier.py)python from typing import Literal from langchain_core.output_parsers import PydanticOutputParser from langchain_core.prompts import ChatPromptTemplate from pydantic import BaseModel, Field from utils.model_factory import get_deepSeek_model class TicketResult(BaseModel): category: Literal[订单, 物流, 退款, 产品, 其他] Field(description工单分类) priority: Literal[低, 中, 高] Field(description优先级) reason: str Field(description分类原因) parser PydanticOutputParser(pydantic_objectTicketResult) format_instructions parser.get_format_instructions() template ChatPromptTemplate.from_messages([ (system, 客服工单分类助手。\n{format_instructions}), (human, {question}) ]) prompt template.invoke({ format_instructions: format_instructions, question: 订单显示已签收但我没收到商品请处理。 }) response model.invoke(prompt) result parser.invoke(response) print(result.category) # 物流 print(result.priority) # 高 if result.priority 高: print(立即转人工)六、处理解析错误模型输出不稳定时可能返回不符合结构的内容。应捕获OutputParserException或通用异常。python from langchain_core.exceptions import OutputParserException try: result parser.parse(response.content) except OutputParserException as e: print(解析失败原始输出, response.content) print(错误信息, e) # 可进行重试、日志记录或人工干预七、结构化方式对比方式优点缺点适用场景StrOutputParser简单、管道兼容仅返回字符串摘要、翻译、问答PydanticOutputParser清晰、可自定义需手动拼接格式说明需要精细控制解析过程with_structured_output代码简洁依赖模型服务支持现代大模型OpenAI/DeepSeek等建议先掌握PydanticOutputParser理解原理实际项目优先使用with_structured_output。八、工具函数封装减少重复代码为了让案例更干净我们将模型初始化抽到utils/model_factory.pypython # utils/model_factory.py from langchain_openai import ChatOpenAI import os def get_deepSeek_model(temperature0): return ChatOpenAI( modeldeepseek-chat, api_keyos.getenv(DEEPSEEK_API_KEY), base_urlhttps://api.deepseek.com/v1, temperaturetemperature )这样每个案例只需导入get_deepSeek_model即可。九、常见问题解答Q1Prompt 越长越好吗不是。应清晰简洁避免过多无关要求否则模型可能顾此失彼。Q2模型为什么不完全按指令输出大模型是概率性生成不能保证100%服从。若输出格式关键需配合结构化输出和程序校验。Q3PromptTemplatevsChatPromptTemplate如果模型支持多角色消息System/Human优先用ChatPromptTemplate本课程所有案例均使用它。Q4为什么temperature0对于信息抽取、分类等确定性任务温度设为0可获得最稳定输出。Q5with_structured_output没看到 JSON 字符串因为 LangChain 内部已将 JSON 自动解析为 Pydantic 对象你拿到的直接就是模型实例。 总结通过本文你学会了使用PromptTemplate/ChatPromptTemplate管理提示词编写高质量 Prompt 的四个原则三个业务案例文案、计划、客服实战MessagesPlaceholder处理聊天历史三种输出解析器StrOutputParser、PydanticOutputParser、with_structured_output结构化输出案例简历抽取、评论分析、工单分类处理解析错误和异常掌握这些技能你就能构建出既易于维护又能与业务系统无缝对接的 LLM 应用。