基础使用2.1 基础模型
Chat Model
在LangChain中,与LLM的交互被统一抽象为一套接口,即Model I/O。它可以理解为应用程序与LLM之间的中间层,使开发者无需关心底层模型实现,只需通过一致的方式完成调用。
基于这一抽象,LangChain可以对接多种模型来源,包括OpenAI、各类第三方模型接口以及本地服务,如兼容OpenAI协议的Ollama等。尽管模型来源不同,但调用方式是统一的。以OpenAI为例,典型调用方式如下:
from langchain_openai import ChatOpenAI chat_model = ChatOpenAI( model_name=model_name, # 模型名称 base_url=base_url, # API服务地址 api_key=api_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_name="qwen3.5:0.8b", base_url="http://localhost:11434/v1", api_key="any_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 Model
Embedding Model是Model I/O体系中的另一类核心模型,用来把文本、图片等非结构化数据表示为向量。在这个向量空间里,语义相近的内容会更接近,因此可以用来做相似度检索。在RAG任务中,它会分别将用户问题与知识库文本进行编码,通过相似度找到最相关的内容,提供给LLM作为上下文。
在LangChain中,可以通过Embedding模型完成文本向量化,不同来源的Embedding服务也可以通过统一接口使用。例如,使用本地部署的Ollama嵌入模型生成向量:
from langchain_ollama import OllamaEmbeddings embeddings = OllamaEmbeddings( model="qwen3-embedding:0.6b", base_url="http://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(content=question) ] # 风格2:文言文风格 messages2 = [ SystemMessage(content="请以文言文风格作答,语言简洁典雅"), HumanMessage(content=question) ] 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_prompt=example_template, examples=examples_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)在对话场景中也可以使用基于消息结构的FewShotChatMessagePromptTemplate:
from 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_prompt=example_prompt, examples=examples, ) 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"}))