随着大语言模型(LLM)的爆发式发展,LangChain 作为一个强大的编排框架,极大地降低了我们与各类大模型交互的门槛。无论你是在构建简单的问答机器人,还是复杂的多智能体系统,“模型调用”“提示词构建”都是最基础也是最核心的基石。

今天,我们就结合一张非常经典的 LangChain 知识点脑图,深入拆解模型调用的底层逻辑、四种 Message 角色,以及四种(尽管原笔记标题写的是三种,实际写了四种)实用的 Prompt 传递方式。

一、 模型调用的“四大金刚”方法

LangChain 对底层 LLM 接口进行了高度抽象,无论你使用的是 OpenAI、Anthropic 还是百度的文心一言,都通过一套统一的接口进行交互。根据不同的业务场景,LangChain 提供了四种核心的调用方法:

1. invoke() —— 最基础的同步调用

这是最常用的单次请求方法。当你向模型发送一个 Prompt,并希望完整地等待回复后再进行下一步操作时,使用 invoke。它的特点是阻塞式的,过程简单直观,非常适合在脚本或非实时交互场景中使用。

2. ainvoke() —— 异步调用的“魔法”

如果你的应用构建在异步框架(如 FastAPI、Sanic 等)上,或者你需要同时处理多个不相关的请求,ainvoke 就是你的救星。它支持 await 语法,能够在等待模型响应时不阻塞主线程,大幅提升高并发场景下的系统吞吐量。

3. stream() —— 丝滑的流式响应

大模型存在一定的推理时延,如果使用 invoke 等几秒甚至十几秒才吐出全部答案,用户会感到非常卡顿。stream() 允许模型将生成的 Token 像水流一样逐字(或逐段)返回。这对于开发类似 ChatGPT 的“打字机效果”交互界面至关重要,能极大地提升用户的体验感。

4. batch() —— 批量请求的“推土机”

当你有一组固定不变的 Prompt(例如对数千封电子邮件同时进行摘要)时,batch() 方法可以将它们打包成一个批次一次性发送给 API。这不仅比循环调用 invoke 快得多,还能在底层自动进行并发处理,最大化利用模型的并发配额,大幅节省总处理时间。


二、 消息(Messages)的概念:大模型的“人格”划分

单纯扔给模型一句“今天天气怎么样”往往不够专业。为了引导大模型发挥出更好的效果,我们需要将 Prompt 细分为不同的“角色”。LangChain 将对话历史高度封装成了以下几种 Message 类型:

  • SystemMessage(系统提示词):这是给大模型设定的“人格设定”和“行为准则”。例如:“你是一位资深 Python 开发者,说话要简洁、专业”、“你只回答和编程有关的问题”。SystemMessage 是控制模型输出的核心“闸门”。

  • HumanMessage(用户提示词):代表了用户的真实提问或指令。这是对话流程中最常规的输入。

  • AIMessage(AI 返回的结果):这条不是我们填写的,而是模型上一轮输出的结果。在需要长上下文记忆的对话中,必须把之前对话的 AIMessage 一并传回去,这样模型才知道上下文。

  • ToolMessage(工具提示词):这是大模型 Agent 时代的产物。当大模型决定调用外部工具(如联网搜索、计算器)时,我们需要把工具执行后的返回结果包装成 ToolMessage 传给模型,以便它根据结果生成最终答案。


三、 四种 Prompt 传递方式:你选哪一种?

很多人刚接触 LangChain 时,会对如何传参感到困惑。图片中列出了四种方式(笔记标题写“三种方式”,实际上是四种,这正好体现了 LangChain 的灵活性与兼容性)。我们来逐一解析:

方式 1:纯文本调用(最基础)

llm.invoke("你好,请介绍一下自己。")

适用场景:简单的单轮对话、不需要系统设定的无关痛痒的测试。缺点是没法设定 SystemMessage,也无法构建复杂的多轮对话上下文。

方式 2:使用消息类型对象(最推荐,类型安全)

from langchain_core.messages import SystemMessage, HumanMessage

llm.invoke([
    SystemMessage(content="你是一个幽默的喜剧演员。"),
    HumanMessage(content="讲个笑话吧。")
])

优势:这是 LangChain 官方推荐的最佳实践。由于使用了类对象,你的 IDE(如 VSCode)可以提供代码补全和类型检查,一旦属性名写错(例如把 content 拼错),代码会在运行时之前就报错,非常适合在大型商业项目中使用。

方式 3:使用元组列表(轻量级)

llm.invoke([
    ("system", "你是一个翻译助手,只把中文译成英文。"),
    ("human", "我爱编程。")
])

优势:写法极其简洁,不需要引入额外的 SystemMessage 类。它利用元组的第一个元素指定角色,第二个元素指定内容。适合在需要快速搭建原型、对代码行数要求精简的场合使用。

方式 4:使用字典列表(原生兼容)

llm.invoke([
    {"role": "system", "content": "你是一位资深战略顾问。"},
    {"role": "human", "content": "帮我分析一下电动汽车行业的趋势。"}
])

优势:这种格式与 OpenAI 官方 API 的原始参数结构完全一致。如果你的代码之前是基于 OpenAI SDK 写的,想要迁移到 LangChain,这种写法可以直接复用数据结构,迁移成本最低。

四、 综合实战:用一段代码跑起来

让我们把所有概念融合在一起,写一个真正的 Python 脚本(假设你配置好了 OpenAI 环境):

from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage, HumanMessage

# 1. 初始化模型(设定温度0.7,适当增加创造性)
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.7)

# 2. 构建 Prompt(使用最推荐的类对象方式)
messages = [
    SystemMessage(content="你是一个精通武侠小说的文学大师。你的回答必须充满诗意和江湖气息。"),
    HumanMessage(content="什么是孤独?")
]

# 3. 调用模型(测试流式输出)
print("--- 大师的高见 ---\n")
for chunk in llm.stream(messages):
    print(chunk.content, end="", flush=True)
print("\n")

代码解析

  • SystemMessage 给了模型“武侠文学大师”的人设。

  • HumanMessage 提出了一个哲学问题。

  • 采用 stream() 方法返回,你会看到大模型像真人说话一样,逐字逐句地输出带有古风色彩的答案,而不是一下子全部蹦出来。

五、 结语:灵活背后的统一

从图片中的简单几行代码提纲,我们可以延伸出 LangChain 在设计上的巨大魅力:它既提供了统一的调用入口(invoke 等),又提供了高度灵活的 Prompt 组装修饰(四种消息角色和四种传参格式)。

掌握了模型调用的基本姿态,你就拥有了驾驭大语言模型的基础能力。建议你在实际项目中,优先使用类对象来构建多轮对话,并根据系统对实时性的要求,在 stream 和 invoke 之间做出权衡。

技术是表象,灵活运用才是精髓。LangChain 的世界还有很多有趣的组件(如 Chain、Agent、Memory)等待你去探索,打好今天这层地基,未来的构建将事半功倍!

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐