LangChain双模型流水线:用架构设计解决AI应用调参难题 1. 项目缘起为什么你的LangChain应用总在“严谨”与“创意”间摇摆如果你刚开始用LangChain构建AI应用大概率遇到过这种困境当你需要一个严谨、准确的答案时比如从文档里提取一个具体的日期或数字你调用的模型却给你来了一段天马行空的“创作”而当你希望它写点有创意的文案或故事时它又变得死板、啰嗦像在背诵说明书。这种“拧巴”的体验根源往往不在于模型本身不行而在于我们默认的“一个模型包打天下”的粗暴用法。在AI应用开发的早期为了快速验证想法我们通常会选择一个模型比如GPT-3.5或GPT-4然后通过精心设计提示词Prompt来引导它完成所有任务。这就像让一位既精通法律条文又擅长写诗的专家同时处理合同审查和广告文案。虽然理论上可行但效率低下且极易“精神分裂”——为了满足“严谨”的要求提示词会变得冗长、充满限制从而扼杀了“创意”反之为了激发“创意”又不得不牺牲一部分准确性和可控性。更关键的是调参的复杂性呈指数级上升。你需要在一个提示词里平衡两种截然不同的任务目标调整温度temperature、top_p等参数时往往顾此失彼。温度调低了创意枯竭温度调高了严谨性崩塌。这就是为什么标题说“90%的AI新手不会调参”——不是他们不想而是在单模型架构下这几乎是一个无解的多目标优化难题。我最初也深陷其中直到将软件工程中“单一职责”和“流水线”的思想引入AI应用架构。与其让一个模型“精神分裂”不如为“严谨”和“创意”分别匹配合适的“专家”模型并通过LangChain的智能路由Routing或条件链Conditional Chains将它们串联起来形成一条高效、可控的“双模型流水线”。这套方案的核心价值在于用架构设计替代复杂的提示词工程和参数微调让代码结构本身来保证不同任务的质量。接下来我将手把手带你实现这套流水线并深入每个环节的设计逻辑与避坑要点。2. 架构核心理解“严谨”与“创意”任务的技术分水岭在动手写代码之前我们必须从技术层面厘清“严谨型任务”和“创意型任务”的本质区别。这决定了后续的模型选型、提示词设计和流水线编排策略。很多新手失败的第一步就是错误地定义了任务的边界。2.1 严谨型任务的技术特征与模型需求严谨型任务的核心是“确定性输出”和“事实准确性”。典型场景包括信息提取Information Extraction从非结构化文本如报告、邮件中提取结构化信息如人名、日期、金额、产品型号。摘要Summarization对长文档进行客观、无偏见的浓缩要求不丢失关键事实。分类Classification将文本归入预定义的类别如情感分析正面/负面/中性、意图识别。问答QA基于给定上下文Context回答问题答案必须严格源自上下文。这类任务对模型的要求是强指令跟随能力模型必须严格遵守提示词中的格式、规则和约束。低随机性输出应尽可能一致、可重复。温度temperature参数通常需要设置得很低如0.1或0。强大的上下文理解与推理能力需要准确理解文本中的逻辑关系和事实细节。对“幻觉”Hallucination的低容忍度模型不能凭空捏造信息。因此为严谨型任务选择模型时我们更倾向于那些在指令微调Instruction Tuning和强化学习人类反馈RLHF上表现突出且已知具有较低幻觉率的模型。例如OpenAI的GPT-4系列、Anthropic的Claude 3 Opus或专门为代码、推理任务优化的DeepSeek-Coder等。它们的共同点是逻辑严谨但可能相对“保守”和“昂贵”。2.2 创意型任务的技术特征与模型需求创意型任务的核心是“发散性思维”和“新颖性”。典型场景包括内容生成Content Generation撰写营销文案、博客文章、故事、诗歌。头脑风暴Brainstorming生成产品创意、活动方案、故事大纲。风格转换Style Transfer将一段文字改写成另一种风格如正式变口语化严肃变幽默。对话与角色扮演Chat Role-playing模拟特定角色进行开放域对话。这类任务对模型的要求恰恰相反丰富的想象力和语言多样性能够生成新颖、不落俗套的文本。高随机性与探索性需要一定的“灵感火花”温度temperature参数可以设置得较高如0.7-1.0。对格式和规则的灵活处理不必严格遵循固定模板允许即兴发挥。对事实准确性的要求相对宽松在创作场景中适当的虚构和夸张是被允许甚至鼓励的。为此我们可能会选择那些在创意写作评测中表现优异或者参数规模更大、训练数据更偏向开放域对话和文学作品的模型。例如一些开源的、未经严格事实对齐的模型或者在创意写作任务上微调过的模型变体。它们的优点是“有灵气”、“便宜”但可能逻辑性稍弱容易偏离主题。2.3 双模型流水线的设计哲学理解了上述分水岭双模型流水线的设计就呼之欲出了任务路由Task Routing。整个流水线的第一步不是一个模型开始工作而是一个“调度器”来分析用户输入判断这属于“严谨”还是“创意”任务然后将任务分发给对应的“专家”模型。这样做的好处是降维打击专业化每个模型只需在其擅长的领域做到极致无需妥协。成本优化创意任务可能使用更便宜、更快的模型而只在需要高精度时调用昂贵的模型。参数简化每个模型可以使用其任务类型的最优默认参数如严谨任务temperature0.1创意任务temperature0.8无需动态调整。可维护性可以独立升级或更换流水线中的任何一个模型而不会影响另一个。接下来的章节我们将把这个架构落地为代码。3. 环境搭建与核心工具链选型工欲善其事必先利其器。在开始构建流水线前我们需要搭建一个稳定、可复现的开发环境并选择一套高效的工具链。这里我会给出一个兼顾生产可靠性和开发便利性的方案并解释每个选择背后的原因。3.1 基础环境与依赖管理强烈建议使用虚拟环境来隔离项目依赖避免包冲突。这里以Python的venv为例# 创建项目目录并进入 mkdir langchain-dual-pipeline cd langchain-dual-pipeline # 创建虚拟环境 python -m venv venv # 激活虚拟环境 # Windows: venv\Scripts\activate # macOS/Linux: source venv/bin/activate接下来创建requirements.txt文件。这里的选择至关重要langchain0.1.0 langchain-openai0.0.5 langchain-community0.0.10 pydantic2.0.0 python-dotenv1.0.0为什么是langchain0.1.0LangChain处于快速迭代期API变动频繁。0.1.x是一个相对稳定的LTS版本社区资料丰富避免了最新版可能带来的意外Break Change。这是我们追求“严谨性”的一环。langchain-openai与langchain-communityLangChain v0.1.x采用了模块化架构。核心框架langchain只包含最基本的功能集成具体模型如OpenAI需要单独的包langchain-openai而一些社区贡献的组件、工具则放在langchain-community中。这种设计让依赖更清晰。pydantic2.0.0LangChain大量使用Pydantic进行数据验证和设置管理。Pydantic v2在性能和功能上有巨大提升是必选项。python-dotenv用于安全地管理API密钥等环境变量是生产级应用的基本安全要求。安装依赖pip install -r requirements.txt3.2 模型服务选型与配置我们的流水线需要两个或两类模型。为了演示的通用性和可访问性我选择OpenAI的模型作为示例但你完全可以替换为Claude、Gemini或本地部署的Ollama模型。严谨型任务模型GPT-4。它在复杂推理、指令跟随和减少幻觉方面是目前综合表现最好的选择之一。虽然成本高但对于关键任务值得投资。创意型任务模型GPT-3.5-Turbo。它在创意写作、对话生成上性价比极高响应速度快足以满足大多数创意需求。注意在实际生产中你可以根据成本、延迟和具体任务效果进行更精细的搭配。例如对于极度严谨的金融摘要可能使用Claude 3 Opus对于简单的文案润色可能使用更便宜的GPT-3.5-Turbo-Instruct甚至开源模型。将你的OpenAI API密钥保存在项目根目录的.env文件中OPENAI_API_KEYsk-your-actual-api-key-here然后在代码中通过dotenv加载from dotenv import load_dotenv load_dotenv() # 这会读取.env文件中的变量到环境变量 import os api_key os.getenv(OPENAI_API_KEY)3.3 初始化模型客户端在LangChain中我们通过ChatOpenAI类来调用模型。这里的关键是为不同任务创建不同的模型实例并预设好各自的参数。from langchain_openai import ChatOpenAI # 严谨型任务模型GPT-4低温保证确定性 strict_llm ChatOpenAI( modelgpt-4-turbo-preview, # 或 gpt-4 temperature0.1, # 关键参数低温度输出稳定 max_tokens2000, # 根据任务设定合理的上限 request_timeout60, # 设置超时避免长时间挂起 ) # 创意型任务模型GPT-3.5-Turbo较高温度激发多样性 creative_llm ChatOpenAI( modelgpt-3.5-turbo, temperature0.8, # 关键参数较高温度输出多样 max_tokens1500, request_timeout30, )实操心得request_timeout参数经常被忽略但在生产环境中至关重要。网络波动或API服务不稳定可能导致请求挂起设置超时可以让你的应用更健壮并有机会进行重试或降级处理。给GPT-4设置更长的超时是合理的因为它的推理通常更耗时。4. 实现智能任务路由流水线的“大脑”流水线的核心是“路由”Routing即判断一个用户查询应该交给strict_llm还是creative_llm。一个简单的if-else判断看似可行但面对千变万化的自然语言规则会迅速变得难以维护。更优雅的方式是让一个AI模型或一个轻量级分类器来帮我们做这个判断。4.1 设计路由提示词Router Prompt我们设计一个提示词让模型根据查询内容将其分类。这里我们依然使用creative_llmGPT-3.5-Turbo来完成路由判断因为它成本低、速度快且分类本身不需要极强的严谨性。from langchain.prompts import ChatPromptTemplate from langchain.schema.output_parser import StrOutputParser # 定义路由分类的提示词模板 ROUTER_PROMPT_TEMPLATE 你是一个智能任务分类器。请根据用户的问题判断它属于以下哪一类任务 A. 严谨型任务需要精确、基于事实、逻辑严密、无歧义的答案。通常涉及信息提取、总结、分类、基于给定上下文的问答、代码生成、数据分析等。例如“从这段会议纪要里提取所有行动项和负责人”、“总结这篇科研论文的核心发现”、“将这条用户反馈归类为‘功能请求’、‘Bug报告’还是‘咨询’”。 B. 创意型任务需要想象力、发散思维、创造性表达或开放性回答。通常涉及写作、头脑风暴、创意生成、角色扮演、风格转换等。例如“为我们的新产品写一句吸引人的广告语”、“构思三个关于时间旅行的短篇小说开头”、“用幽默的方式解释什么是区块链”。 请只输出单个字母 A 或 B不要输出任何其他文字。 用户问题{question} router_prompt ChatPromptTemplate.from_template(ROUTER_PROMPT_TEMPLATE) # 构建路由链 router_chain router_prompt | creative_llm | StrOutputParser()为什么这样设计提示词明确角色赋予模型“分类器”的明确角色聚焦其任务。清晰定义用具体的描述和例子来界定“严谨”和“创意”减少模型误判。格式化输出强制要求输出“A”或“B”便于后续程序化处理。StrOutputParser用于解析模型的文本输出。使用创意模型路由判断允许一定的模糊性使用更快更便宜的模型是合理的成本权衡。4.2 构建路由函数接下来我们创建一个函数它接受用户问题调用路由链并返回对应的模型实例。async def route_question(question: str): 路由用户问题到合适的模型。 返回: (model_type, llm_instance) try: # 异步调用路由链提高并发性能 response await router_chain.ainvoke({question: question}) response response.strip().upper() if response A: return strict, strict_llm elif response B: return creative, creative_llm else: # 如果模型没有按格式输出默认回退到严谨模型安全选择 print(f路由输出异常: {response} 默认使用严谨模型。) return strict_fallback, strict_llm except Exception as e: # 路由过程发生错误如网络问题也回退到严谨模型 print(f路由过程出错: {e} 默认使用严谨模型。) return strict_fallback, strict_llm避坑要点错误处理与回退策略路由本身可能失败网络、API限流或者模型可能不按格式输出。我们必须有健壮的回退机制Fallback。这里选择回退到strict_llm是因为在无法确定意图时提供一个准确但可能保守的答案比提供一个充满幻觉的创意答案更安全。这是构建可靠AI应用的关键思维。异步调用使用ainvoke而非invoke。在Web服务器或异步框架中这能避免阻塞提升整体吞吐量。如果你的应用是纯同步的用invoke也可。日志记录打印路由结果和异常便于后期监控和优化提示词。4.3 测试路由逻辑在继续构建完整流水线前先测试一下我们的“大脑”是否工作正常。# 简单的测试函数 async def test_router(): test_questions [ 帮我计算一下这份财务报表中的净利润率是多少, 为‘智能咖啡杯’想五个有趣的社交媒体标签。, 阅读下面这段客户支持对话总结用户遇到的核心问题是什么[对话文本...], 写一首关于秋天落叶的俳句。, ] for q in test_questions: model_type, llm await route_question(q) print(f问题: {q[:50]}...) print(f 路由结果: {model_type}) print(- * 40) # 运行测试 import asyncio asyncio.run(test_router())预期输出中财务计算和问题总结应被路由到strict而想标签和写俳句应被路由到creative。如果发现误判就需要回头优化ROUTER_PROMPT_TEMPLATE中的描述和例子。这是一个迭代过程。5. 构建专业化处理链让“专家”模型各司其职路由完成后问题被分发到对应的模型。但直接让模型回答还不够“专业”。我们需要为每类任务构建一个“处理链”Chain这个链包含了针对该类任务优化的提示词模板、可能的上下文处理以及输出格式要求。这才是发挥模型最大效力的地方。5.1 严谨型任务处理链对于严谨型任务提示词的核心是结构化、无歧义和可验证。from langchain.prompts import ChatPromptTemplate, HumanMessagePromptTemplate, SystemMessagePromptTemplate # 系统消息定义角色和核心原则 strict_system_message SystemMessagePromptTemplate.from_template( 你是一个严谨、准确、注重事实的AI助手。你的职责是提供基于证据、逻辑清晰、无歧义的答案。 你必须遵守以下规则 1. 严格基于用户提供的信息和上下文进行回答。如果信息不足请明确说明“根据已有信息无法确定”。 2. 绝对不要捏造、猜测或添加未被证实的信息。 3. 如果涉及计算或推理请清晰地展示你的步骤。 4. 答案应简洁、直接优先使用列表、表格等结构化格式呈现。 5. 如果用户问题模糊请请求澄清而不是自行假设。 ) # 人类消息模板用于嵌入用户问题和可能的上下文 strict_human_template 上下文信息可能为空 {context} 用户问题{question} 请根据以上信息提供严谨准确的回答。 strict_human_message HumanMessagePromptTemplate.from_template(strict_human_template) # 组合成完整的提示词 strict_prompt ChatPromptTemplate.from_messages([strict_system_message, strict_human_message]) # 构建严谨型处理链提示词 - 模型 - 输出解析器 strict_chain strict_prompt | strict_llm | StrOutputParser()关键设计解析系统消息System Message这是设定模型行为基调的关键。我们明确强调了“基于证据”、“不要捏造”、“展示步骤”等原则这比在用户问题中反复强调更有效。上下文Context变量留出了{context}占位符。在实际应用中严谨任务常常需要搭配“检索增强生成RAG”。例如先从向量数据库中检索相关文档片段作为context提供给模型让答案有据可依。这是实现严谨性的核心技术。结构化输出倾向在提示词中鼓励使用列表、表格这能迫使模型进行更结构化的思考产出更易解析和使用的答案。5.2 创意型任务处理链对于创意型任务提示词的核心是激发灵感、减少限制、鼓励多样性。creative_system_message SystemMessagePromptTemplate.from_template( 你是一个富有创造力、想象力和幽默感的AI助手。你的任务是帮助用户进行头脑风暴、创作和产生新颖的想法。 请发挥你的创意提供生动、有趣、出人意料的回答。不要被常规思维束缚鼓励探索不同的角度和风格。 如果用户没有指定风格你可以自由发挥尝试不同的口吻如幽默、诗意、激昂、简洁。 目标是激发灵感而不仅仅是提供标准答案。 ) creative_human_template 用户请求{question} 请发挥你的创意给出令人印象深刻的回答。 creative_human_message HumanMessagePromptTemplate.from_template(creative_human_template) creative_prompt ChatPromptTemplate.from_messages([creative_system_message, creative_human_message]) # 构建创意型处理链 creative_chain creative_prompt | creative_llm | StrOutputParser()关键设计解析解放天性系统消息使用了“富有创造力”、“想象力”、“幽默感”、“出人意料”等词语旨在降低模型的“心理防线”鼓励其跳出标准应答模式。风格鼓励明确提到可以尝试不同口吻这给了模型更大的发挥空间。对于创意任务模糊的指令有时比精确的指令更能产生好结果。简化模板人类消息模板非常简洁避免用复杂的规则束缚模型的创意过程。5.3 可选的输出后处理有时我们可能希望对输出进行后处理。例如对于严谨型任务的输出我们可能想自动提取其中的关键数据点对于创意型输出可能想过滤掉不合适的语言。这可以通过在链的最后添加一个RunnableLambda来实现。from langchain.schema.runnable import RunnableLambda def post_process_strict(output: str) - str: 后处理严谨型任务的输出例如确保没有以‘抱歉’开头的逃避回答 if output.startswith(抱歉) or output.startswith(我无法): # 可以在这里添加更复杂的重试或降级逻辑 return 根据当前信息我无法提供一个确切的答案。请提供更多细节或上下文。 # 简单的清理移除多余的空行 return \n.join(line.strip() for line in output.splitlines() if line.strip()) def post_process_creative(output: str) - str: 后处理创意型任务的输出例如确保长度适中 # 如果输出过长可以截断并添加省略号根据需求调整 max_length 1000 if len(output) max_length: return output[:max_length] ...\n【输出因过长被截断】 return output # 将后处理函数加入链中 strict_chain_with_post strict_chain | RunnableLambda(post_process_strict) creative_chain_with_post creative_chain | RunnableLambda(post_process_creative)后处理不是必须的但它为流水线增加了额外的控制层和鲁棒性。6. 组装完整流水线与实战测试现在我们将路由器和两个处理链组装起来形成一个完整的、端到端的双模型流水线。这里我们会创建一个主函数它接收用户输入自动完成路由、分发、处理和返回结果的全过程。6.1 构建主流水线函数async def dual_model_pipeline(question: str, context: str ) - dict: 双模型流水线主函数。 参数: question: 用户问题 context: 可选的上下文信息用于严谨型任务 返回: dict: 包含路由结果、使用的模型类型和最终答案 # 1. 路由 model_type, llm_instance await route_question(question) # 2. 根据路由结果选择处理链并执行 if model_type.startswith(strict): # 严谨型任务传入上下文 print(f[流水线] 执行严谨型任务使用模型: {llm_instance.model_name}) answer await strict_chain_with_post.ainvoke({context: context, question: question}) else: # creative # 创意型任务通常不需要额外上下文 print(f[流水线] 执行创意型任务使用模型: {llm_instance.model_name}) answer await creative_chain_with_post.ainvoke({question: question}) # 3. 返回结构化结果 return { question: question, routed_to: model_type, model_used: llm_instance.model_name, answer: answer }这个函数清晰地体现了流水线的三个阶段路由Route、执行Execute、返回Return。它返回一个字典包含了完整的执行轨迹便于调试和日志记录。6.2 综合实战测试让我们用几个更复杂的例子来测试整个流水线模拟真实场景。async def run_integration_tests(): # 测试用例1需要严谨分析的财务问题带上下文 context_finance 公司2023年第四季度财报摘要 - 营业收入人民币1,200万元 - 营业成本人民币700万元 - 税费人民币100万元 - 净利润人民币400万元 question1 基于提供的财报计算毛利率和净利率并列出计算步骤。 # 测试用例2创意营销任务 question2 为我们新推出的‘AI智能笔记本’能自动整理会议纪要并生成待办事项构思三条不同风格的广告语分别针对职场精英、学生和科技爱好者。 # 测试用例3模糊问题看路由如何判断 question3 分析一下当前新能源汽车市场的竞争格局。 test_cases [ (question1, context_finance), (question2, ), (question3, ), ] for q, ctx in test_cases: print(\n *60) print(f测试问题: {q}) if ctx: print(f附带上下文长度: {len(ctx)} 字符) result await dual_model_pipeline(q, ctx) print(f路由决策: {result[routed_to]} (模型: {result[model_used]})) print(f答案:\n{result[answer]}) print(*60) # 运行集成测试 asyncio.run(run_integration_tests())预期结果与观察点问题1应被路由到strictGPT-4。答案应包含清晰的计算步骤“毛利率 (营业收入 - 营业成本) / 营业收入 (1200-700)/1200 ≈ 41.67%”“净利率 净利润 / 营业收入 400/1200 ≈ 33.33%”。输出应该是数字和列表格式非常结构化。问题2应被路由到creativeGPT-3.5-Turbo。答案应提供三条风格迥异的广告语例如对职场精英突出“效率”对学生突出“学习助手”对科技爱好者突出“黑科技”。语言应该生动、有感染力。问题3这是一个有趣的边界案例。“分析竞争格局”既有需要事实依据的严谨一面又可能需要一些概括性的、观点性的创意表达。路由器的判断取决于提示词中例子的偏向。它很可能被路由到strict因为“分析”一词更偏向于严谨推理。观察这里的路由结果有助于我们进一步优化路由提示词。6.3 处理边界案例与优化测试中可能会暴露一些问题路由模糊像“分析竞争格局”这类问题。优化方法是在ROUTER_PROMPT_TEMPLATE中增加更多此类边界案例的说明例如“如果问题要求基于公开事实和数据进行系统性分析即使需要一些概括也属于严谨型任务A。”创意任务不够“炸”如果觉得创意输出平淡可以调整creative_llm的temperature到0.9或1.0或者在系统消息中加入更具体的激发语句如“请给出至少一个让人眼前一亮、出乎意料的点子”。严谨任务输出啰嗦如果GPT-4的回答过于详细可以在strict_system_message中增加“答案请尽可能精炼聚焦于核心信息”的指令。7. 进阶从流水线到智能体Agent与性能考量基础流水线已经能解决大部分问题。但对于更复杂的场景比如一个任务中同时包含严谨和创意环节或者需要动态调用工具如计算器、搜索引擎我们可以引入LangChain的智能体Agent概念将双模型流水线升级为更强大的智能体系统。7.1 设计一个两阶段智能体假设用户请求是“帮我分析一下特斯拉和比亚迪最近一年的股价走势并用一个生动的比喻来总结它们的竞争关系。” 这个任务明显包含两个阶段1) 严谨的数据查找与分析需要工具2) 创意的比喻生成。我们可以设计一个智能体它首先使用strict_llm作为“大脑”调用搜索工具获取股价数据并进行初步分析然后将分析结果传递给creative_llm让它生成比喻。from langchain.agents import AgentExecutor, create_react_agent from langchain.tools import Tool # 假设我们有一个能获取股价信息的工具这里用模拟函数代替 from langchain.agents import load_tools # 注意以下代码为概念演示需要安装相关包并配置工具API # 1. 为严谨模型配置工具例如搜索、计算 # 这里需要你根据实际情况安装和配置真实工具如SerpAPI、Wikipedia等 # tools load_tools([serpapi, llm-math], llmstrict_llm) # 2. 创建严谨分析智能体 # strict_agent create_react_agent(strict_llm, tools) # strict_agent_executor AgentExecutor(agentstrict_agent, toolstools, verboseTrue) # 3. 模拟一个分析结果 analysis_result 特斯拉(TSLA)与比亚迪(BYD)过去一年股价分析 - 特斯拉年初约110美元经历大幅波动年底约180美元年度涨幅约64%。波动性较大受马斯克言论、宏观经济影响显著。 - 比亚迪年初约25美元港股折算走势相对稳健年底约32美元年度涨幅约28%。受中国电动车市场增长和公司强劲销量支撑。 总体而言特斯拉像一艘装备精良但颠簸的太空船冲劲足但起伏大比亚迪像一列稳步加速的高铁路线稳健势头持续。 # 4. 将分析结果交给创意模型进行比喻润色 creative_prompt_for_agent ChatPromptTemplate.from_messages([ SystemMessagePromptTemplate.from_template(你是一个擅长用比喻的作家。), HumanMessagePromptTemplate.from_template( 请基于以下严谨的金融分析创作一个生动、贴切、令人印象深刻的比喻来总结这两家公司的竞争关系。 分析原文 {analysis} 请只输出你构思的比喻不要重复分析内容。 ) ]) creative_chain_for_agent creative_prompt_for_agent | creative_llm | StrOutputParser() async def two_stage_agent_demo(): # 第一阶段严谨分析此处模拟结果 # factual_analysis strict_agent_executor.invoke({input: 分析特斯拉和比亚迪最近一年的股价走势}) print(第一阶段严谨分析完成。) # 第二阶段创意生成 final_metaphor await creative_chain_for_agent.ainvoke({analysis: analysis_result}) print(\n生成的比喻) print(final_metaphor) # asyncio.run(two_stage_agent_demo())这个架构将流水线从“选择模型”提升到了“编排工作流”能力更强大。7.2 性能、成本与监控考量在生产环境中部署双模型流水线还需考虑以下几点延迟路由本身增加了一次API调用会带来额外的延迟约0.5-2秒。对于延迟敏感的应用可以考虑使用更快的模型如GPT-3.5-Turbo-Instruct或本地轻量级分类模型进行路由。实现路由缓存对相似的问题直接返回缓存的路由结果。成本路由调用和创意任务使用GPT-3.5-Turbo成本较低严谨任务使用GPT-4成本高。需要监控各模型的Token使用量优化提示词以减少不必要的消耗。对于内部工具可以权衡是否所有严谨任务都需要GPT-4。监控与评估需要记录每次请求的路由决策、使用的模型、Token消耗和响应时间。更重要的是建立评估机制例如通过人工抽样或自动化评分如答案与标准答案的相似度来持续优化路由提示词和各专业链的提示词。降级与熔断当某个模型API如GPT-4不可用时流水线应能自动降级如将所有任务路由到GPT-3.5-Turbo并提示用户当前为降级模式。这需要在外层添加异常捕获和降级逻辑。7.3 扩展性支持更多模型和任务类型当前架构是二元的strict/creative。很容易扩展为多元分类。例如你可以定义更多任务类型code: 代码生成与解释使用Code Llama或GPT-4-Turbo。reasoning: 复杂逻辑推理使用Claude 3 Opus或GPT-4。translation: 翻译任务使用专门的翻译模型。只需修改路由提示词增加类别定义和例子并在主函数中增加对应的处理链即可。这种架构的优势在于其清晰的模块化使得添加新的“专家”模型变得非常简单。经过以上七个部分的拆解与实践我们从“为什么需要双模型”的痛点出发逐步实现了从环境准备、模型选型、智能路由、专业化链构建到完整流水线组装和进阶扩展的全过程。这套代码的价值不在于用了多高级的模型而在于它提供了一种用工程化思维解决AI调参难题的范式。它将复杂的、相互冲突的调参目标分解为独立的、可优化的子模块让每个部分都能在其专精的领域达到最佳状态。下次当你发现提示词越来越长、参数怎么调都不对劲时不妨想想是不是该让不同的模型专家来协同工作了