【智能体开发】用LangChain组织提示词、模型与结果解析:构建可独立测试的处理流程

发布时间:2026/10/10 9:20:46
【智能体开发】用LangChain组织提示词、模型与结果解析:构建可独立测试的处理流程 用LangChain组织提示词、模型与结果解析构建可独立测试的处理流程一、你遇到的问题假设你在做一个“课程反馈分析”功能用户提交一段课程评价文本系统需要从中提取出评分1-5分、情感倾向和关键点列表并交给下游的报表模块使用。最直接的做法是写一个函数拼好提示词调用模型拿到字符串再用正则或json.loads解析。这个做法在第一次跑通时没问题但接下来你会遇到一连串麻烦模型输出的 JSON 偶尔多一个逗号json.loads直接抛异常整个流程断掉想换一个模型做对比测试发现提示词里硬编码了某个模型的特殊格式想单独测试“解析逻辑是否正确”却发现它和模型调用绑死在同一个函数里不连真实 API 就测不了同事想复用你的提示词模板你只能把一大段字符串复制过去。这些问题的根源是提示词、模型调用、结果解析被揉成了一团。LangChain 提供的ChatPromptTemplate、模型接口和输出解析器本质上是把这三者拆成可独立替换、可独立测试的组件。本文要做的就是把它们组合成一条清晰的链并给出能实际验证的测试方法。完成后你将得到一个可复现的 Python 程序一份带三类验收场景的测试表以及一套判断“解析是否正确”的明确标准。二、前置条件与适用环境适用环境Python 3.10LangChain 生态的 Python 包。操作系统不限Windows/macOS/Linux 均可命令以 Bash 风格给出Windows 用户可在 Git Bash 或 WSL 中执行。你需要具备的入门知识Python 基础语法、pip安装依赖、环境变量设置。不需要 LangChain 经验本文会解释用到的每个核心概念。你需要准备的一个模型服务的 API Key本文以 OpenAI 兼容接口为例其他提供商的接入方式在代码中留有替换位置一个隔离的目录不要在已有项目中直接运行约 15 分钟。本文使用的模型与接口选择LangChain 的init_chat_model支持统一方式接入多个提供商。本文选择openai作为示例提供商因为它的接口最通用。如果你使用 Ollama 本地模型或 DeepSeek 等只需修改模型标识链的其余部分不变。这一点会在代码中说明。三、为什么要把三件事拆开一条 LangChain 链的骨架是这样的prompt | model | parser这三个组件各自承担明确职责提示词PromptTemplate / ChatPromptTemplate负责把输入变量渲染成模型能理解的格式。ChatPromptTemplate支持系统消息、用户消息、AI 消息的多角色结构比单字符串的PromptTemplate更适合需要约束模型行为的场景。模型ChatModel负责接收消息列表并返回模型输出。LangChain 的模型接口是统一的无论底层是 OpenAI、Anthropic 还是本地 Ollamainvoke的调用方式一致。输出解析器OutputParser负责把模型返回的字符串或消息对象转成结构化数据。PydanticOutputParser允许你用一个 Pydantic 模型描述期望的输出结构并自动生成“格式指令”注入提示词引导模型按 schema 输出。拆开之后你可以单独测试解析器给它一段固定的 JSON 字符串看它是否正确转成 Pydantic 对象也可以单独测试提示词给它变量看渲染出的消息列表是否符合预期。模型调用成为唯一需要真实网络的部分其余逻辑都可以在离线状态下验证。需要说明的是LangChain 较新版本推荐用with_structured_output配合 Pydantic 模型来获取结构化输出这种方式在支持工具调用的模型上更可靠。本文选择“提示词注入格式指令 PydanticOutputParser”的经典路线原因是它在不支持工具调用的模型上同样可用且解析逻辑完全独立于模型便于做离线测试。两种方式并不互斥你可以根据模型能力选择。四、完整实现文件清单文件用途config.py从环境变量读取模型标识和 API 配置schemas.py定义输出数据的 Pydantic 模型parser_test.py用固定测试数据验证解析器main.py组装链并运行完整流程.env可选存放 API Key不提交到版本控制4.1 定义输出 schema# schemas.pyfromtypingimportLiteralfrompydanticimportBaseModel,FieldclassCourseFeedback(BaseModel):从课程评价文本中提取的结构化反馈。rating:intField(description课程评分1到5的整数)sentiment:Literal[positive,neutral,negative]Field(description情感倾向)key_points:list[str]Field(description评价中提到的关键点每个点用1到3个词概括)Literal类型约束了情感倾向只能取三个值。Field的description会被PydanticOutputParser写进格式指令告诉模型每个字段的含义。4.2 构建提示词模板# prompts.pyfromlangchain_core.promptsimportChatPromptTemplate SYSTEM_TEMPLATE你是一个课程反馈分析助手。 从用户提供的课程评价中提取评分、情感倾向和关键点。 严格按照提供的JSON格式输出不要添加任何额外说明。HUMAN_TEMPLATE课程评价如下 {feedback_text} {format_instructions}defbuild_prompt(format_instructions:str)-ChatPromptTemplate:returnChatPromptTemplate.from_messages([(system,SYSTEM_TEMPLATE),(human,HUMAN_TEMPLATE),]).partial(format_instructionsformat_instructions)这里有两个关键选择。第一用ChatPromptTemplate而不是PromptTemplate因为系统消息可以对模型行为形成更稳定的约束。第二用.partial()把格式指令预填进去这样调用链时只需要传feedback_text一个变量。格式指令来自解析器不是手写的。4.3 组装链# main.pyimportosfromlangchain.chat_modelsimportinit_chat_modelfromlangchain_core.output_parsersimportPydanticOutputParserfromschemasimportCourseFeedbackfrompromptsimportbuild_promptdefbuild_chain(model_id:str):parserPydanticOutputParser(pydantic_objectCourseFeedback)promptbuild_prompt(parser.get_format_instructions())modelinit_chat_model(modelmodel_id,temperature0)returnprompt|model|parserparser.get_format_instructions()返回一段文本描述了模型应该输出的 JSON 结构。temperature0让输出尽可能稳定减少格式波动。init_chat_model会根据模型标识自动推断提供商。如果你用 OpenAI模型标识类似gpt-4o-mini如果用 DeepSeek标识以deepseek开头会被推断为 DeepSeek 提供商如果用 Ollama需要显式指定model_providerollama。4.4 环境配置# 在隔离目录中执行python-mvenv venvsourcevenv/bin/activate# Windows: venv\Scripts\activatepipinstalllangchain langchain-openai pydantic python-dotenv# 设置 API Key不要写入代码文件exportOPENAI_API_KEY你的keyinit_chat_model会自动读取OPENAI_API_KEY环境变量。如果你用其他提供商对应的环境变量名不同例如 DeepSeek 可能需要DEEPSEEK_API_KEY查阅该提供商的 LangChain 集成文档确认。五、如何验证解析是否正确解析器是整个流程里最需要独立测试的部分。模型输出不可控但解析逻辑是确定性的给同样的字符串必须得到同样的结果。5.1 解析器独立测试# parser_test.pyfromlangchain_core.output_parsersimportPydanticOutputParserfromlangchain_core.exceptionsimportOutputParserExceptionfromschemasimportCourseFeedbackdeftest_parser_normal():parserPydanticOutputParser(pydantic_objectCourseFeedback)raw{rating: 5, sentiment: positive, key_points: [内容扎实, 节奏好]}resultparser.parse(raw)assertisinstance(result,CourseFeedback)assertresult.rating5assertresult.key_points[内容扎实,节奏好]print(正常场景通过)deftest_parser_invalid_rating():parserPydanticOutputParser(pydantic_objectCourseFeedback)raw{rating: 9, sentiment: positive, key_points: [还行]}try:parser.parse(raw)print(边界场景失败评分9不应通过)exceptException:print(边界场景通过超出范围的评分被拒绝)deftest_parser_missing_field():parserPydanticOutputParser(pydantic_objectCourseFeedback)raw{rating: 4, key_points: [不错]}try:parser.parse(raw)print(失败场景失败缺少sentiment字段不应通过)exceptException:print(失败场景通过缺失字段被拒绝)if__name____main__:test_parser_normal()test_parser_invalid_rating()test_parser_missing_field()运行方式python parser_test.py预期输出正常场景通过 边界场景通过超出范围的评分被拒绝 失败场景通过缺失字段被拒绝关于边界场景的一个技术说明Pydantic 默认不会拒绝超出范围的整数除非你在Field中加了约束。上面的test_parser_invalid_rating实际上会失败评分 9 会被接受除非把schemas.py中的rating字段改为rating:intField(description课程评分1到5的整数,ge1,le5)ge和le是 Pydantic 的数值约束加上后评分超出 1-5 范围会抛出验证错误。这个细节恰恰说明了独立测试解析器的价值如果你不单独测就不会发现 schema 缺少约束。5.2 完整链的验收场景下表给出三类验收场景。正常场景需要真实 API Key边界场景和失败场景可以在不调用模型的情况下通过直接测试解析器来验证。场景类型测试目的输入预期结果判定方法正常验证完整链能产出结构化对象一段包含明确评分和情感的评价返回CourseFeedback实例字段齐全isinstance(result, CourseFeedback)为 True边界验证评分约束是否生效JSON 中rating为 0 或 6抛出验证异常捕获ValidationError或OutputParserException失败验证缺失字段是否被拒绝JSON 中缺少sentiment抛出验证异常捕获ValidationError或OutputParserException对于正常场景完整链的调用方式frommainimportbuild_chainimportos chainbuild_chain(gpt-4o-mini)resultchain.invoke({feedback_text:这门课讲得很清楚节奏也舒服就是作业稍微多了点。给4分吧。})print(type(result))# class schemas.CourseFeedbackprint(result.rating)# 4print(result.sentiment)# positiveprint(result.key_points)# 关键点列表具体措辞因模型而异模型输出不要求逐字匹配。key_points的内容因模型而异验收标准是字段存在、类型正确、评分在合理范围、关键点非空。不要用固定字符串做断言。5.3 常见故障定位故障一OutputParserException提示“Failed to parse”。原因通常是模型在 JSON 前后加了说明文字或者输出了不完整的 JSON。定位方法先绕过解析器直接打印模型原始输出fromlangchain_core.runnablesimportRunnableLambdafrommainimportbuild_chain chainbuild_chain(gpt-4o-mini)raw_chainchain[:-1]|RunnableLambda(lambdamsg:msg.content)rawraw_chain.invoke({feedback_text:...})print(repr(raw))看到原始输出后就知道是格式问题还是 schema 问题。格式问题可以尝试用OutputFixingParser包装原解析器让模型自动修复schema 问题则需要调整提示词或字段描述。故障二init_chat_model报“model_provider not found”。原因是你用的模型标识没有对应的集成包。解决安装对应包如langchain-deepseek或显式传model_provider参数。故障三评分约束不生效。如 5.1 所述Pydantic 默认不做范围检查。确认schemas.py中rating字段是否带有ge1, le5。六、适用边界与未覆盖的部分本文的链是同步、单轮、无状态的。以下情况不在本文范围内需要额外设计多轮对话需要维护消息历史ChatPromptTemplate的MessagesPlaceholder可以承接历史消息流式输出PydanticOutputParser是聚合式解析不支持流式。如果需要流式考虑使用with_structured_output配合支持流式的模型解析失败自动重试可以用RetryWithErrorOutputParser它会带着原始指令和错误信息让模型重新输出生产级并发与限流需要额外的调度和错误恢复逻辑。本文选择的最小闭环是让读者掌握“提示词—模型—解析器”三段式结构的搭建方法并用离线测试验证解析逻辑的确定性。把模型调用隔离在最小范围内是整个设计最核心的工程决策。验证状态已完成的核验解析器的独立测试代码逻辑经静态检查测试用例覆盖正常、边界、失败三类场景提示词构建和链的组装方式对照了 LangChain 官方文档中ChatPromptTemplate、PydanticOutputParser和init_chat_model的用法说明Pydantic 字段约束的说明基于 Pydantic 的标准行为ge/le参数用于数值范围限制。未实际执行的验证完整链调用真实模型的部分未执行因为本文写作环境没有可用的 API Key。正常场景的预期输出是基于 LangChain 文档中类似示例的推断不是实测结果不同提供商DeepSeek、Ollama 等的init_chat_model兼容性未逐一验证。如果你使用非 OpenAI 提供商建议先用parser_test.py确认解析逻辑再接入模型。参考资料LangChain 官方文档Prompt Templates 快速参考核验日期2026-10-09LangChain 官方文档Custom Output Parsers核验日期2026-10-09LangChain 官方文档Output Parsers 类型表v0.1核验日期2026-10-09LangChain API 文档init_chat_model核验日期2026-10-09KodeKloud 教程Pydantic Output Parser 完整示例核验日期2026-10-09

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询