Chat Model在LangChain中与LLM的交互被统一抽象为一套接口即Model I/O。它可以理解为应用程序与LLM之间的中间层使开发者无需关心底层模型实现只需通过一致的方式完成调用。基于这一抽象LangChain可以对接多种模型来源包括OpenAI、各类第三方模型接口以及本地服务如兼容OpenAI协议的Ollama等。尽管模型来源不同但调用方式是统一的。以OpenAI为例典型调用方式如下from langchain_openai import ChatOpenAI chat_model ChatOpenAI( model_namemodel_name, # 模型名称 base_urlbase_url, # API服务地址 api_keyapi_key # API密钥 )其中model_name表示模型名称base_url表示模型服务地址api_key表示接口密钥。同样地本地模型服务也可以通过相同方式接入。例如使用Ollama时可以先拉取并启动模型ollama pull qwen3.5:0.8b ollama serveOllama的完整使用教程可参阅推理部署框架llama.cpp与Ollama使用指北。Ollama默认监听地址为 http://localhost:11434 并原生兼容OpenAI协议的接口只需调整参数即可在LangChain中调用from langchain_openai import ChatOpenAI chat_model ChatOpenAI( model_nameqwen3.5:0.8b, base_urlhttp://localhost:11434/v1, api_keyany_value # 本地服务通常不校验 ) response chat_model.invoke(请介绍一下你自己) print(response.content)后续示例将统一使用该chat_model并省略初始化过程。关于LangChain与Ollama的配合使用可参考LangChain 1.0光速入门基于本地Ollama部署LLM。从本质上看上述调用过程正是Model I/O的具体体现而一次完整的LLM交互可以拆分为三个步骤首先对输入进行格式化其次调用模型生成结果最后对输出进行解析。这三个阶段分别对应Prompt Template、Model和Output Parser从而形成统一且可扩展的调用流程。2.1.2 Embedding ModelEmbedding Model是Model I/O体系中的另一类核心模型用来把文本、图片等非结构化数据表示为向量。在这个向量空间里语义相近的内容会更接近因此可以用来做相似度检索。在RAG任务中它会分别将用户问题与知识库文本进行编码通过相似度找到最相关的内容提供给LLM作为上下文。在LangChain中可以通过Embedding模型完成文本向量化不同来源的Embedding服务也可以通过统一接口使用。例如使用本地部署的Ollama嵌入模型生成向量from langchain_ollama import OllamaEmbeddings embeddings OllamaEmbeddings( modelqwen3-embedding:0.6b, base_urlhttp://127.0.0.1:11434 ) vector embeddings.embed_query(hello world) print(嵌入向量长度:, len(vector)) print(前10个值:, vector[:10])代码得到的vector即为输入文本的向量表示可用于后续的相似度计算或检索任务。2.2 Message消息机制在LangChain中消息Message是Chat Model交互的基本载体用于统一描述模型输入与输出的结构。一条消息通常由两部分组成角色Role和内容Content。角色用于标识消息的来源或作用内容则包含具体的文本信息。此外消息还可以携带上下文信息和元数据以支持更复杂的对话场景。LangChain提供了多种常见的消息类型以适配不同的交互需求消息类型说明SystemMessage用于设定模型的行为规则、角色身份及上下文约束HumanMessage表示用户输入AIMessage表示模型输出ToolMessage/FunctionMessage表示工具执行结果常用于Agent或函数调用场景在典型的对话流程中SystemMessage用于预设规则HumanMessage提供输入问题AIMessage负责生成回答。这种分工使对话结构更加清晰也便于扩展到多轮对话和Agent等复杂应用场景。示例代码from langchain_core.messages import SystemMessage, HumanMessage question 电风扇的工作原理是什么 # 风格1标准说明 messages1 [ SystemMessage(content请使用标准说明文风格作答要求表达清晰、客观严谨), HumanMessage(contentquestion) ] # 风格2文言文风格 messages2 [ SystemMessage(content请以文言文风格作答语言简洁典雅), HumanMessage(contentquestion) ] resp1 chat_model.invoke(messages1) resp2 chat_model.invoke(messages2) print( 标准说明 ) print(resp1.content) print(\n 文言文风格 ) print(resp2.content)2.3 Prompt Template提示词模板Prompt是与LLM交互的输入用于定义任务目标、背景和输出要求其设计质量直接影响模型效果。在实际业务中输入具有动态性固定Prompt难以复用且适配性有限。为此LangChain引入Prompt Template将静态字符串抽象为可复用模板并通过变量填充在运行时生成Prompt从而提升灵活性与可维护性。有关Prompt的更多内容详见提示词工程指北。PromptTemplate基础文本模板PromptTemplate是最基础的模板类型适用于生成纯文本形式的Prompt其核心能力是通过变量替换实现动态内容生成。PromptTemplate的具体使用见LangChain PromptTemplate 全解析。from langchain_core.prompts import PromptTemplate prompt PromptTemplate.from_template( 请生成一段话{task} ) prompt_text prompt.invoke({ task: 介绍良好阅读习惯的重要性 }).text response chat_model.invoke(prompt_text) print(response.content)这种方式适用于结构简单的单轮任务。但随着任务复杂度提升仅使用PromptTemplate会逐渐暴露出结构不清晰、可控性不足的问题。ChatPromptTemplate对话模板在对话模型场景中直接拼接文本Prompt往往不够清晰因此LangChain提供了ChatPromptTemplate用于按角色组织Prompt结构。from langchain_core.prompts import ChatPromptTemplate chat_prompt ChatPromptTemplate.from_messages([ (system, 你是一名文言文写作助手输出一段自然流畅的文字), (human, 请完成任务{task}) ]) messages chat_prompt.invoke({ task: 介绍良好阅读习惯的重要性 }) response chat_model.invoke(messages) print(response.content)通过显式区分system和human角色可以让Prompt结构更加清晰同时也更贴合对话模型的训练方式。不过当Prompt进一步复杂化时这种方式仍然存在复用困难的问题。MessagePromptTemplate消息模板组件为了支持更复杂的Prompt设计LangChain提供了MessagePromptTemplate将Prompt拆分为更细粒度的组件。from langchain_core.prompts import ( ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate ) chat_prompt ChatPromptTemplate.from_messages([ SystemMessagePromptTemplate.from_template( 你是一个擅长写说明性文字的助手输出必须为一段完整的表述 ), HumanMessagePromptTemplate.from_template( 请生成一段话{task} ) ]) messages chat_prompt.invoke({ task: 介绍良好阅读习惯的重要性 }) response chat_model.invoke(messages) print(response.content)在这种方式下不同角色的Prompt可以独立定义并按需组合适用于复杂系统和团队协作开发。但即使结构清晰模型在输出格式上的稳定性仍难以完全保证。FewShotPromptTemplate少样本提示当需要模型稳定输出特定格式或风格时仅依赖Prompt往往不够。FewShotPromptTemplate通过提供示例引导模型模仿既有格式以示例替代规则使输出更加稳定和可预测。关于相关概念及更详细的使用说明可参考Langchain学习入门。简单示例如下from langchain_core.prompts import PromptTemplate, FewShotPromptTemplate example_template PromptTemplate.from_template( 单词{word}, 英文翻译{translation} ) examples_data [ {word: 苹果, translation: apple}, {word: 快乐, translation: happy} ] few_shot_template FewShotPromptTemplate( example_promptexample_template, examplesexamples_data, prefix请给出一个单词及其英文翻译以下是示例, suffix单词{input_word}英文翻译, input_variables[input_word] ) prompt_text few_shot_template.invoke( {input_word: 计算机} ).to_string() print(prompt_text) response chat_model.invoke(prompt_text) print(response.content)在对话场景中也可以使用基于消息结构的FewShotChatMessagePromptTemplatefrom langchain_core.prompts import ( ChatPromptTemplate, FewShotChatMessagePromptTemplate, ) examples [ {input: 你好, output: Hello}, {input: 谢谢你的帮助, output: Thank you for your help}, ] example_prompt ChatPromptTemplate.from_messages([ (human, {input}), (ai, {output}), ]) few_shot_prompt FewShotChatMessagePromptTemplate( example_promptexample_prompt, examplesexamples, ) final_prompt ChatPromptTemplate.from_messages([ ( system, 你是一个翻译助手将中文翻译成英文。只输出翻译结果不要提供额外解释。 ), few_shot_prompt, (human, {input}), ]) chain final_prompt | chat_model print(chain.invoke({input: 今天天气很好}).content) print(chain.invoke({input: 请稍等一下}).content)partial方法Prompt部分填充通过模板实现动态生成Prompt后常会遇到固定变量反复传递的问题如目标语言、角色设定或业务背景手动处理既繁琐又易出错。此时可用partial方法预先填入这些固定内容相当于提前构建好一部分Prompt。这样便可通过一个通用模板衍生多个可直接使用的版本简单又高效。from langchain_core.prompts import ChatPromptTemplate template ChatPromptTemplate.from_messages([ (system, 将以下文本翻译为{target_lang}保留原意), (human, {text}) ]) zh_translator template.partial(target_lang中文) en_translator template.partial(target_lang英文) result_zh zh_translator.invoke({text: Hello world}) result_en en_translator.invoke({text: 你好世界}) print(result_zh.to_messages()) print(result_en.to_messages())2.4 Output Parser输出解析器LLM默认返回的是纯字符串而实际开发中为了进行后续处理通常需要结构化数据。为此必须先对模型的输出结果进行解析借助解析器将文本转换为特定的数据结构。在LangChain中这类解析器被定义为Output Parser并提供了多种实现以适配不同的输出格式。解析器名称作用StrOutputParser将模型输出直接解析为字符串JsonOutputParser将模型输出解析为JSON格式的结构化数据CommaSeparatedListOutputParser将逗号分隔的文本解析为Python列表XMLOutputParser将模型输出解析为XML格式的结构化数据关于Output Parser的更多介绍见How to Master Output Parsers下面通过一个完整示例演示不同解析器的使用方式from langchain_core.prompts import PromptTemplate from langchain_core.output_parsers import ( StrOutputParser, JsonOutputParser, CommaSeparatedListOutputParser, XMLOutputParser ) # # 1. 字符串解析器StrOutputParser最基础用法 # str_prompt PromptTemplate.from_template( 用一句话介绍什么是{name} ) str_chain str_prompt | chat_model | StrOutputParser() print(StrOutput:, str_chain.invoke({name: LLM})) # # 2. JSON解析器JsonOutputParser结构化输出 # json_parser JsonOutputParser() json_prompt PromptTemplate( template用一句话介绍什么是{name}。\n{format_instructions}, input_variables[name], partial_variables{ format_instructions: json_parser.get_format_instructions() } ) json_chain json_prompt | chat_model | json_parser print(JSON Output:, json_chain.invoke({name: LLM})) # # 3. 列表解析器CommaSeparatedListOutputParser列表结构 # list_parser CommaSeparatedListOutputParser() list_prompt PromptTemplate( template列出{name}的3个特点。\n{format_instructions}, input_variables[name], partial_variables{ format_instructions: list_parser.get_format_instructions() } ) list_chain list_prompt | chat_model | list_parser print(List Output:, list_chain.invoke({name: LLM})) # # 4. XML解析器XMLOutputParser层级结构 # xml_parser XMLOutputParser() xml_prompt PromptTemplate( template用XML格式输出什么是{name}。\n{format_instructions}, input_variables[name], partial_variables{ format_instructions: xml_parser.get_format_instructions() } ) xml_chain xml_prompt | chat_model | xml_parser print(XML Output:, xml_chain.invoke({name: LLM}))