用 LangChain 驱动本地 Ollama 模型
这两年,大模型几乎成了开发者的“标配工具”: 但你有没有认真想过一个问题: 随着模型体积持续下降、硬件性能快速提升,以及 Ollama 这类工具逐渐成熟, 这篇文章,我们就来完整走一遍: 先给结论: 这是目前本地大模型场景中,最自然、最稳定的一种组合方式。 你可以把 Ollama 理解为: 它解决的问题非常聚焦: 一句话总结: 如果你只是想“问一句、回一句”,直接调 Ollama API 当然也没问题。 这些正是 LangChain 擅长的事情: 所以一个非常自然的分工是: 如果你对部署细节感兴趣,可以参考我之前的文章: 以 简单测试: 如果可以正常对话,说明模型已经在本地成功运行。 接下来进入核心部分: 这里我们使用 OpenAI 兼容协议,这是目前最稳定、生态最完整的一种方式。 几个关键点说明: 到这里,你已经完成了: 这条完整调用链。 在真实项目中,几乎不会直接“裸调”模型。 显式的输出解析,是 LangChain 新 API 的重要特征: 这就是 LangChain 当前主推的 LCEL(表达式)写法, ⚠️ 一个非常重要的变化: 在新的 Runnable 体系中, 到这里,你已经拥有了一个: 的对话系统。 而且 所有数据都只存在你的本地机器上。 非常适合: 不太适合: 最后分享几点真实踩坑后的经验: 模型别贪大 Prompt 比模型更重要 LangChain 要“模块化使用” Memory 要可演进 Ollama 非常适合私有化场景 过去一年,我们讨论最多的问题是: 而现在,越来越多开发者开始认真思考: LangChain + Ollama 并不是为了“替代云”, 如果你正在做: 那么这套组合,非常值得一试。 如果你觉得这篇文章对你有帮助,欢迎 点赞 / 转发 / 收藏。
写代码、查资料、做总结、当智能助手。我们真的必须把所有请求都发到云端 API 吗?
本地运行大模型,已经从早期的“极客尝鲜”,演进为一种可以在真实项目中落地的工程方案。如何使用 LangChain,基于最新 Runnable API,调用本地启动的 Ollama 模型,构建一个真正可用的本地大模型应用。
一、为什么选择 LangChain + Ollama?
Ollama 解决“模型怎么跑”,LangChain 解决“能力怎么用”。
1️⃣ Ollama:本地大模型的“Docker”
专门为大模型设计的一层运行时基础设施。11434)Ollama 把“跑模型”这件事,做成了基础设施能力。
2️⃣ LangChain:AI 应用的“控制中心”
但一旦进入真实工程场景,需求会迅速复杂化:LangChain 负责“编排与逻辑”,Ollama 负责“模型与算力”。
二、准备工作:本地启动 Ollama 模型
1️⃣ 使用 Docker 部署 Ollama(推荐)
docker run \
-d \
--restart=always \
--name ollama \
--gpus=all \
-p 11434:11434 \
-v /home/data/ollama:/root/.ollama \
ollama/ollama2️⃣ 拉取并运行模型
qwen3:8b 为例:ollama pull qwen3:8bollama run qwen3:8b三、LangChain 接入本地 Ollama(OpenAI 协议)
如何用 LangChain 调用本地 Ollama?1️⃣ 安装依赖
pip install langchain langchain-openai2️⃣ 创建 Ollama LLM(ChatOpenAI)
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
name="ollama-ai",
model="qwen3:8b",
base_url="http://localhost:11434/v1",
api_key="your api key",
temperature=0.7,
timeout=300,
)model 必须与 Ollama 中的模型名称一致base_url 指向 Ollama,并注意使用 /v1 后缀3️⃣ 最简单的一次调用
response = llm.invoke("用一句话解释什么是 LangChain")
print(response)LangChain → 本地 Ollama → 本地大模型
四、进阶用法:Prompt + Runnable(LCEL)
1️⃣ PromptTemplate
from langchain_core.prompts import PromptTemplate
prompt = PromptTemplate(
input_variables=["question"],
template="你是一个资深后端工程师,请用简洁、专业的语言回答:{question}",
)2️⃣ 输出解析(StrOutputParser)
from langchain_core.output_parsers import StrOutputParser
parser = StrOutputParser()3️⃣ Runnable 组合(推荐写法)
chain = prompt | llm | parser
response = chain.invoke({
"question": "为什么本地部署大模型越来越流行?"
})
print(response)
比早期的 LLMChain 更透明、也更可组合。五、加入 Memory:真正的本地对话能力
Memory 不再是 Chain 的“隐藏参数”,而是显式的状态管理。1️⃣ 定义对话历史存储
from langchain_core.chat_history import InMemoryChatMessageHistory
store = {}
def get_session_history(session_id: str):
if session_id not in store:
store[session_id] = InMemoryChatMessageHistory()
return store[session_id]2️⃣ Prompt 显式消费 history(关键)
from langchain_core.prompts import PromptTemplate
prompt = PromptTemplate(
input_variables=["history", "question"],
template="""
你是一个资深后端工程师。
以下是之前的对话历史:
{history}
当前用户问题:
{question}
请基于上下文给出连贯、准确的回答。
""".strip()
)这是很多人第一次使用 RunnableWithMessageHistory 时最容易忽略的一点:
历史是否生效,取决于 Prompt 是否显式使用 {history}。3️⃣ 构建带记忆的 Runnable
from langchain_core.runnables.history import RunnableWithMessageHistory
chain = prompt | llm | parser
chat_chain = RunnableWithMessageHistory(
chain,
get_session_history,
input_messages_key="question",
history_messages_key="history",
)4️⃣ 调用(带 session_id)
config = {"configurable": {"session_id": "local-chat"}}
print(chat_chain.invoke(
{"question": "什么是 Ollama?"},
config=config
))
print(chat_chain.invoke(
{"question": "它和 LangChain 有什么关系?"},
config=config
))六、这套方案适合谁?
七、一些来自实践的工程建议
结语
“该用哪个云端大模型?”
“哪些能力,其实可以放回本地?”
而是为我们提供了一个:真正可控、可组合、可落地的本地大模型方案。
下一篇,我会继续分享 LangGraph 在本地大模型场景下的实战用法。











