一、背景介绍:为什么需要 langchain-ollama

如果你已经会用 requests 直接打 Ollama 的 HTTP 接口,可能会问:再套一层 LangChain,是不是过度工程?我一开始也这么想,直到真正动手做了一个稍微复杂点的应用——带工具调用的 RAG 助手。那一刻我才意识到,自己拿 requests 拼的那套东西,本质上是在重新实现一遍 LangChain 已经打磨好的抽象。

具体来说,这层抽象至少帮我省掉了三件事:

  1. 接口标准化。LangChain 的 BaseChatModel 接口让 Ollama、OpenAI、Anthropic、Gemini 等模型在调用层完全一致。换模型就是换一行 import,不用动业务代码。
  2. 生态复用。LangChain 的 RunnablePromptTemplateOutputParserToolMemory 都能直接套用,不必重造轮子。
  3. 流式与异步原生支持.stream().astream().batch() 这些方法开箱即用,写起来比手撸 SSE 解析舒服得多。

至于为什么要单独的 langchain-ollama 包,而不是老的 langchain.llms.Ollama?这是 LangChain 自 0.2 版本起的"模块化拆分"策略:把每个 provider 拆成独立的 langchain-xxx 包,独立迭代、独立维护、互不绑架。langchain-ollama 就是 Ollama 那一支的官方实现,由 LangChain 团队和 Ollama 团队共同维护,更新比社区分支及时得多。

那"本地"和"云端"在这里指什么? 我想澄清一下,免得后文产生歧义:

  • 本地模型:在你自己的机器上跑 ollama serve,模型权重也在本地,默认监听 http://localhost:11434
  • 云端模型:把 Ollama 部署在远程服务器(自建 VPS、公司内网 GPU 机器,或者 Ollama 官方的 Turbo/Cloud 服务),通过 base_url 指向那个地址。模型权重在云端,调用方只发请求。

langchain-ollama 对这两种场景一视同仁——这正是它最让人舒服的地方。


二、使用步骤:从 Hello World 到工具调用

2.1 环境准备

我用的是 Python 3.11,建议至少 3.9+。先建个干净的虚拟环境再装包:

pip install -U langchain langchain-ollama
# 这里我用的 uv add langchain-ollama

如果你打算用本地模型,确认 Ollama 服务已经在跑(ollama serve 或者图形客户端常驻);如果走远程,准备好 base_url 和(可选的)API Key。

2.2 第一次对话:ChatOllama

ChatOllama 是聊天模型的封装,对应 Ollama 的 /api/chat 接口。最小可用片段:

from langchain_ollama import ChatOllama
from langchain_core.messages import HumanMessage, SystemMessage

llm = ChatOllama(
    model="qwen2.5:7b",
    temperature=0.3,
)

messages = [
    SystemMessage(content="你是一名简洁直接的中文技术顾问。"),
    HumanMessage(content="一句话解释什么是 RAG。"),
]

resp = llm.invoke(messages)
print(resp.content)

跑通这段,整个链路就算打通了。invoke 是同步阻塞调用,适合脚本场景;如果是 Web 服务,更推荐 ainvoke(异步)或 stream(流式)。

2.3 切换到云端:只改一行

这是我最想强调的部分。把上面的代码迁到云端 Ollama,业务逻辑一行都不用动,只在初始化时多传一个 base_url

llm = ChatOllama(
    model="qwen2.5:72b",
    base_url="https://ollama.your-company.com",
    temperature=0.3,
    client_kwargs={"headers": {"Authorization": "Bearer YOUR_TOKEN"}},
)

如果远程服务有鉴权(Nginx Basic Auth、API Gateway、或 Ollama Cloud 的 Token),通过 client_kwargs 注入 HTTP header 即可。我自己的做法是:本地开发时用 llama3.1:8b 快速调试,正式跑业务时切到云端的 qwen2.5:72b,两套配置写进 .env,靠环境变量切换:

import os
from langchain_ollama import ChatOllama

llm = ChatOllama(
    model=os.getenv("LLM_MODEL", "qwen2.5:7b"),
    base_url=os.getenv("OLLAMA_BASE_URL", "http://localhost:11434"),
    temperature=0.3,
)

调试 → 生产 的切换成本,几乎为零。

2.4 流式输出

写聊天界面绕不开流式。langchain-ollama 的流式接口和 LangChain 主线完全一致:

for chunk in llm.stream("用三句话介绍一下 LangChain。"):
    print(chunk.content, end="", flush=True)

异步版本就是 async for chunk in llm.astream(...),搭配 FastAPI 的 StreamingResponse 几乎是肌肉记忆。

2.5 结构化输出与工具调用

这是 langchain-ollama 比裸 HTTP 调用值钱的地方。Ollama 在 0.3 之后原生支持 tool calling,langchain-ollama 把它适配成了 LangChain 通用的 bind_tools 接口:

from langchain_core.tools import tool
from langchain_ollama import ChatOllama

@tool
def get_weather(city: str) -> str:
    """根据城市名查询当前天气。"""
    return f"{city} 今天 24°C,多云。"

llm = ChatOllama(model="qwen2.5:7b").bind_tools([get_weather])

resp = llm.invoke("北京今天天气怎么样?")
print(resp.tool_calls)

如果想直接拿到结构化的 Pydantic 对象,可以用 with_structured_output

from pydantic import BaseModel, Field

class Summary(BaseModel):
    title: str = Field(description="一句话标题")
    keywords: list[str] = Field(description="3 到 5 个关键词")

structured_llm = ChatOllama(model="qwen2.5:7b").with_structured_output(Summary)
result = structured_llm.invoke("请总结这段文字:……(略)……")
print(result.title, result.keywords)

注意一点:结构化输出和工具调用对模型本身有要求qwen2.5llama3.1mistral-nemo 这些较新的模型支持得不错;老一点的模型(如 llama2)会经常输出格式错乱。选模型时要先去 ollama.com/library 看一眼标签里有没有 tools 字样。

2.6 嵌入向量:OllamaEmbeddings

做 RAG 离不开向量化。langchain-ollama 也提供了对应的封装:

from langchain_ollama import OllamaEmbeddings

embeddings = OllamaEmbeddings(
    model="bge-m3",
    base_url=os.getenv("OLLAMA_BASE_URL", "http://localhost:11434"),
)

vec = embeddings.embed_query("向量数据库是什么?")
print(len(vec))  # 1024 维

中文场景下我推荐 bge-m3nomic-embed-text,前者中文召回更准,后者英文文档场景更轻量。


三、写在最后

回头看,langchain-ollama 真正的价值不在于它包了多少花哨的功能,而在于它把"本地"和"云端"两种部署模式,统一在了同一套调用接口下。这意味着我们终于可以理直气壮地说:“开发时用本地模型省钱,上线时切云端模型省心”,而不必为这种切换付出重写代码的代价。

更进一步,它还无缝接入了 LangChain 的整个生态——Prompt 模板、Output Parser、Tool、Agent、Memory、LCEL 表达式语言。哪怕你以后把后端从 Ollama 换成 OpenAI 或 Anthropic,业务层也几乎不用动。这种"前向兼容性",对一个还在快速演进的 AI 应用项目来说,是非常珍贵的护城河。

如果你正打算从"调通模型"走向"做一个真正的 AI 应用",我会强烈推荐花半天时间把 langchain-ollama 摸熟。门槛不高,回报很大——这种工具,值得放进你的常备工具箱里。


参考文献

  1. LangChain 官方文档:ChatOllama 集成. https://python.langchain.com/docs/integrations/chat/ollama/
  2. LangChain 官方文档:OllamaEmbeddings. https://python.langchain.com/docs/integrations/text_embedding/ollama/
  3. langchain-ollama PyPI 主页. https://pypi.org/project/langchain-ollama/
  4. langchain-ollama GitHub 源码. https://github.com/langchain-ai/langchain/tree/master/libs/partners/ollama
  5. Ollama 官方文档:API 参考. https://github.com/ollama/ollama/blob/main/docs/api.md
  6. Ollama Tool Calling 公告. https://ollama.com/blog/tool-support
  7. LangChain 0.2 模块化拆分说明. https://blog.langchain.dev/langchain-v0-2/
  8. BAAI BGE-M3 模型介绍. https://huggingface.co/BAAI/bge-m3
  9. Chroma 向量数据库文档. https://docs.trychroma.com
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐