LangChain + Ollama 集成实战:本地 LLM 应用开发完全指南
上个月我看了一眼 OpenAI 的账单,$52.3。说实话,当时心里有点小崩溃——我一个个人开发者,偶尔玩玩 AI,居然花了这么多钱。然后我想起了本地跑着的 Ollama,免费的 Llama 3.1 就在那里等着我用。
但问题来了:直接调用 Ollama API 写应用,代码量有点多。请求格式、响应解析、错误处理……每写一次都觉得繁琐。这时候 LangChain 就派上用场了——一套封装好的接口,Chat、RAG、Agent 全都能用,还能一行代码切换模型。
本文是 Ollama 本地 LLM 实战指南系列的框架集成篇,会带你从 langchain-ollama 包入门,一路走到 Chat、RAG、Agent 三大实战场景。如果你已经读过系列前几篇(API 调用、多模型部署),这篇会把那些零散的知识串成一个完整的开发框架。
langchain-ollama 包入门
先说说我踩过的一个坑。之前我用的是 langchain_community.llms.Ollama,代码跑起来没问题,但总觉得哪里不对劲——每次查阅文档,看到的都是 “langchain-ollama” 这个包。后来才知道,LangChain 官方把 Ollama 集成拆成了一个独立包,就是 langchain-ollama。
为什么推荐用官方包?
类型提示更完善,IDE 自动补全更友好。维护节奏跟 LangChain 主版本同步,不用担心兼容问题。还有就是社区包可能随时被废弃,官方包是长期方案——这点挺重要的,我之前踩过社区包废弃的坑。
安装一行命令搞定:
pip install langchain-ollama
装好后,你会发现这个包提供了三个核心类,各自对应不同的场景:
| 类名 | 用途 | 典型场景 |
|---|---|---|
ChatOllama | 对话模型 | 多轮聊天、问答系统 |
OllamaLLM | 文本补全 | 单次生成、文本续写 |
OllamaEmbeddings | 向量嵌入 | RAG、语义搜索 |
我实测下来,90% 的场景用 ChatOllama 就够了。对话模型支持多轮交互,还能流式输出——那种逐字显示的效果,用户体验比一次性返回整个回答好太多了。
一个最小示例,让你感受下有多简单:
from langchain_ollama import ChatOllama
# 初始化模型
llm = ChatOllama(
model="llama3.1:8b", # 模型名称,需要先在 Ollama 拉取
temperature=0.7 # 随机性参数,0-1 之间
)
# 发送消息
response = llm.invoke("你好,请介绍一下你自己")
print(response.content)
运行这段代码前,确保你已经用 ollama pull llama3.1:8b 拉取了模型。如果还没装 Ollama,可以回看系列第一篇入门文章。
嵌入模型 OllamaEmbeddings 用法类似,主要用于把文本转成向量。后面 RAG 部分会详细用到,这里先给个简单示例:
from langchain_ollama import OllamaEmbeddings
embeddings = OllamaEmbeddings(model="nomic-embed-text")
# 单条文本嵌入
vector = embeddings.embed_query("这是一段测试文本")
print(f"向量维度: {len(vector)}") # 通常输出 768 或更高
# 多条文本批量嵌入
vectors = embeddings.embed_documents([
"第一段文本",
"第二段文本"
])
nomic-embed-text 是目前主流的嵌入模型,专门为语义检索设计。向量维度高(通常 768+),检索效果比通用模型好不少。
Chat 应用实战:多轮对话与流式输出
单独调用一次 API 很简单,但真实的聊天场景要复杂得多——用户会连续追问,模型需要记住之前的对话内容。LangChain 用消息列表来处理这个问题。
多轮对话实现
LangChain 的消息类型有三种:
SystemMessage:设定模型角色和行为(比如”你是一个专业的程序员助手”)HumanMessage:用户输入AIMessage:模型回复
看代码:
from langchain_ollama import ChatOllama
from langchain_core.messages import HumanMessage, AIMessage, SystemMessage
llm = ChatOllama(model="llama3.1:8b", temperature=0.7)
# 构建对话历史
messages = [
SystemMessage(content="你是一个擅长解释技术概念的开发者助手,回答要简洁易懂。"),
HumanMessage(content="什么是 REST API?"),
AIMessage(content="REST API 是一种网络服务接口设计风格,使用 HTTP 方法(GET/POST/PUT/DELETE)操作资源。简单说,就是用 URL 访问数据。"),
HumanMessage(content="那 GraphQL 和它有什么区别?")
]
# 模型会基于整个对话历史生成回复
response = llm.invoke(messages)
print(response.content)
这段代码里,模型能看到之前的回答,知道用户是在追问 GraphQL 和 REST 的区别。如果没有 AIMessage 那条记录,模型可能会从头解释 GraphQL,用户体验就断了。
流式输出:让响应更有”活着”的感觉
流式输出的好处是用户不用盯着空白屏幕等结果——文字一个个蹦出来,像有人在打字。这种体验对长回答尤其重要。
from langchain_ollama import ChatOllama
llm = ChatOllama(model="llama3.1:8b")
# 流式输出
print("模型回答:", end="", flush=True)
for chunk in llm.stream("用 Python 写一个快速排序算法,并解释原理"):
print(chunk.content, end="", flush=True)
print() # 最后换行
stream() 方法返回一个迭代器,每个 chunk 包含一小段文本。flush=True 确保内容即时显示,不会缓存到缓冲区。
我实测过,流式输出的延迟感比一次性返回低很多——尤其是回答超过 100 字的时候。用户会觉得系统”在思考”,而不是”卡住了”。
RAG 应用实战:本地知识库检索
RAG(Retrieval-Augmented Generation)是目前最实用的 LLM 应用场景之一。简单说:先从文档库检索相关内容,再让模型基于这些内容生成回答。这样模型就能”知道”它训练数据里没有的信息。
RAG 流程拆解
一个完整的 RAG 系统包含五个步骤:
- 加载文档 —— 把 PDF、TXT、Markdown 等文件读进来
- 分割文本 —— 文档太长,切成小片段方便检索
- 生成向量 —— 用嵌入模型把文本转成数字向量
- 存储索引 —— 存到向量数据库(这里用 ChromaDB)
- 检索生成 —— 用户提问时,检索相关片段,让模型回答
下面是完整代码,我跑过一遍,能正常工作:
from langchain_ollama import ChatOllama, OllamaEmbeddings
from langchain_chroma import Chroma
from langchain_community.document_loaders import PyPDFLoader, TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
# === 1. 加载文档 ===
# 支持 PDF、TXT、Markdown 等多种格式
loader = TextLoader("./my_document.txt") # 替换成你的文档路径
docs = loader.load()
# === 2. 分割文本 ===
# chunk_size=1000 是常用参数,每个片段约 1000 字符
# chunk_overlap=200 让片段之间有重叠,避免信息断裂
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
splits = text_splitter.split_documents(docs)
# === 3 & 4. 生成向量并存储 ===
embeddings = OllamaEmbeddings(model="nomic-embed-text")
vectorstore = Chroma.from_documents(
documents=splits,
embedding=embeddings,
persist_directory="./chroma_db" # 持久化存储路径
)
# === 5. 构建检索器 ===
# search_kwargs={"k": 4} 表示检索最相关的 4 个片段
retriever = vectorstore.as_retriever(search_kwargs={"k": 4})
# === 6. 构建 RAG Chain ===
template = """基于以下上下文回答问题。如果上下文中没有相关信息,请明确说明"文档中没有相关信息"。
上下文:
{context}
问题:{question}
"""
prompt = ChatPromptTemplate.from_template(template)
llm = ChatOllama(model="llama3.1:8b")
# LangChain 的 LCEL 语法,用 | 符号串联各个组件
rag_chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
# === 7. 查询 ===
response = rag_chain.invoke("文档的主要内容是什么?")
print(response)
这段代码看起来有点长,但拆开看其实很清晰。关键是 rag_chain 的构建——用 LangChain 的 LCEL(LangChain Expression Language)语法,把检索器、提示模板、模型、输出解析器串联起来。
几个实用参数调整建议:
chunk_size 如果文档内容密集(技术文档),可以调到 800;如果是散文类内容,1000-1500 也行。
k 值(检索片段数量)通常 3-5 个就够了,太多会稀释相关性,太少可能漏掉关键信息。
persist_directory 一定要设置,不然每次重启都要重新构建向量库,耗时又浪费。
我第一次跑 RAG 的时候没设置持久化,结果每次改代码都要重新跑嵌入,慢得让人崩溃。后来加上 persist_directory,构建完的向量库直接加载,几秒就能启动。
Agent 应用实战:JSON-based 工具调用
Agent 和普通对话最大的区别是:Agent 能调用外部工具。
举个例子,用户问”北京今天天气怎么样”,普通对话模型只能瞎编一个答案。Agent 会先调用天气查询工具,拿到真实数据后再回答。
Ollama 工具调用的坑
这里有个问题要坦诚说:Ollama 的工具调用支持不如 OpenAI 完善。OpenAI 的模型原生支持 function calling,能准确识别什么时候该调用工具、怎么传参数。Ollama 的模型(包括 Llama 3.1)在这方面还不太成熟。
怎么办?LangChain 官方给出了一个方案:JSON-based Agent。
思路是让模型输出结构化的 JSON,Agent 框架解析这个 JSON 来决定调用什么工具。实测下来,效果还不错——虽然不如 OpenAI 原生工具调用那么流畅,但能完成基本的任务。
自定义工具示例
先定义几个简单的工具函数:
from langchain_ollama import ChatOllama
from langchain_core.tools import tool
# 定义工具
@tool
def get_weather(city: str) -> str:
"""获取指定城市的天气信息"""
# 这里是模拟数据,实际可接入天气 API
weather_data = {
"北京": "晴朗,25°C,空气质量良好",
"上海": "多云,22°C,有小雨可能",
"深圳": "炎热,30°C,紫外线强"
}
return weather_data.get(city, f"未找到 {city} 的天气数据")
@tool
def calculate(expression: str) -> str:
"""执行数学计算"""
try:
result = eval(expression) # 注意:生产环境需更安全的实现
return f"计算结果:{result}"
except:
return "计算错误,请检查表达式"
@tool
def search_local_docs(query: str) -> str:
"""搜索本地文档库"""
# 这里可以接入前面 RAG 部分的检索器
return f"搜索 '{query}' 的结果:找到了 3 条相关记录"
@tool 装饰器把普通函数变成 LangChain 工具。函数的 docstring 会自动变成工具描述,模型根据描述判断什么时候该用哪个工具。
然后创建 JSON Agent:
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_ollama import ChatOllama
from langchain_core.prompts import ChatPromptTemplate
llm = ChatOllama(model="llama3.1:8b")
tools = [get_weather, calculate, search_local_docs]
# 创建提示模板
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个有用的助手,可以使用工具完成任务。"),
("human", "{input}"),
("placeholder", "{agent_scratchpad}"),
])
# 创建 Agent
agent = create_tool_calling_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# 执行任务
response = agent_executor.invoke({
"input": "帮我查一下北京今天的天气,然后计算 23 + 45"
})
print(response["output"])
verbose=True 会打印 Agent 的思考过程,方便调试。你会看到模型输出的工具调用决策过程。
实测体验:
我跑了几个任务,JSON Agent 的成功率大概 70-80%。简单任务(查天气、算数)基本没问题,复杂任务(多个工具组合)偶尔会出错——比如参数格式不对,或者选错工具。这是目前本地 LLM Agent 的通病,不像 OpenAI 那样稳定。
如果你对 Agent 要求比较高,可以考虑:
- 用更强的模型(比如 Qwen 2.5 或 DeepSeek)
- 简化任务流程,减少工具数量
- 或者干脆用 OpenAI 的原生工具调用,成本虽然高,但稳定性好太多
OpenAI vs Ollama:一行代码切换
很多人问我:LangChain 代码写得挺好的,能不能既用 OpenAI 又用 Ollama?答案是:能,而且简单到你不敢相信。
切换方式一:改 import
假设你有一段用 OpenAI 的代码:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4", temperature=0.7)
response = llm.invoke("解释量子计算")
切换到 Ollama,只需要改一行 import:
from langchain_ollama import ChatOllama
llm = ChatOllama(model="llama3.1:8b", temperature=0.7)
response = llm.invoke("解释量子计算")
其他代码——提示模板、Chain 构建、输出解析——全部不用改。LangChain 的抽象层做得足够好,模型切换对业务逻辑几乎透明。
切换方式二:OpenAI-Compatible API
Ollama 还提供了一个”假装自己是 OpenAI” 的方式——OpenAI-Compatible API。好处是连 import 都不用改:
from langchain_openai import ChatOpenAI
# 只改 base_url 和 api_key,其他不动
llm = ChatOpenAI(
model="llama3.1:8b",
base_url="http://localhost:11434/v1", # Ollama 的 OpenAI 兼容端点
api_key="ollama" # 随意填,Ollama 不验证
)
response = llm.invoke("解释量子计算")
这种方式适合什么场景?你的项目已经大量用了 ChatOpenAI,不想改代码结构,但又想测试本地模型的效果。
对比总结
说了这么多切换方法,到底什么时候该用 Ollama,什么时候该用 OpenAI?我把关键差异整理成一张表:
| 对比项 | OpenAI (GPT-4) | Ollama (Llama 3.1) |
|---|---|---|
| 成本 | $0.03/1K input tokens | 免费(消耗本地 GPU 电费) |
| 隐私 | 数据上传云端,合规敏感场景需谨慎 | 本地处理,数据不出门 |
| 工具调用 | 原生支持,稳定可靠 | 需 JSON Agent,成功率 70-80% |
| 响应速度 | 快(云端优化,1-3 秒首字节) | 取决于本地 GPU(3-10 秒不等) |
| 模型能力 | GPT-4 是目前最强之一 | Llama 3.1 8B 属中强,够用但不如 GPT-4 |
我的建议是:
- 个人学习、原型开发:用 Ollama,省钱还能随便折腾
- 生产环境、高并发:用 OpenAI,稳定性和响应速度有保障
- 隐私敏感数据:用 Ollama,数据不出本地
- 复杂 Agent 任务:用 OpenAI,工具调用更稳定
最理想的状态是两者都有——开发阶段用 Ollama 省成本,上线后用 OpenAI 保稳定。切换成本只有一行代码,何乐而不为。
总结
说到这里,LangChain + Ollama 的集成路径你已经有了完整的地图。
我们从 langchain-ollama 包入门,认识了 ChatOllama、OllamaLLM、OllamaEmbeddings 三大核心类。然后分别实战了三种场景:Chat 多轮对话(流式输出让体验更流畅)、RAG 知识库检索(本地文档变智能问答)、Agent 工具调用(JSON Agent 是目前的折中方案)。最后对比了 OpenAI 和 Ollama 的切换策略——一行代码就能切换,成本从每月 $50 变成免费。
什么时候选 Ollama?
一句话:当你想省钱、保隐私、或者只是想学习 LLM 开发的时候。本地跑起来,随便折腾,不用担心账单爆炸。
什么时候还是得用 OpenAI?
复杂 Agent 任务、高并发生产环境、对响应速度和稳定性要求高的场景。本地 LLM 目前还替代不了云端后的体验。
如果你还没动手试试,建议先从 Chat 场景开始——代码最简单,效果最直观。跑通后再尝试 RAG,把本地文档接入进来,感受”模型能读懂你的资料”的那种惊喜。Agent 可以放后面,因为工具调用的坑还有点多,需要耐心调试。
系列后面还有更多内容:多模型部署(如何在 LangChain 中切换不同模型)、性能调优(让本地 LLM 跑得更快)、生产部署(把本地应用变成可用的服务)。感兴趣的话可以继续跟进。
有问题欢迎在评论区聊,或者直接去 GitHub 找我。代码示例我都跑过一遍,应该能正常工作——如果遇到报错,多半是模型没拉取或者依赖没装好,按报错信息排查就行。
LangChain + Ollama 集成开发
从安装配置到 Chat、RAG、Agent 三大场景实战,一站式掌握本地 LLM 应用开发
⏱️ 预计耗时: 60 分钟
- 1
步骤1: 安装 langchain-ollama 包
运行安装命令:
```bash
pip install langchain-ollama
```
确保已安装 Ollama 并拉取模型(如 `ollama pull llama3.1:8b`)。 - 2
步骤2: 创建 Chat 应用
初始化 ChatOllama 并发送消息:
```python
from langchain_ollama import ChatOllama
llm = ChatOllama(model="llama3.1:8b", temperature=0.7)
response = llm.invoke("你好")
print(response.content)
```
支持多轮对话和流式输出。 - 3
步骤3: 构建 RAG 知识库
五步流程:
• 加载文档(TextLoader / PyPDFLoader)
• 分割文本(RecursiveCharacterTextSplitter)
• 生成向量(OllamaEmbeddings)
• 存储索引(ChromaDB)
• 检索生成(RAG Chain)
关键参数:chunk_size=1000, k=4, persist_directory 必设。 - 4
步骤4: 实现 Agent 工具调用
定义工具函数并创建 JSON Agent:
```python
@tool
def get_weather(city: str) -> str:
"""获取天气信息"""
...
agent = create_tool_calling_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools)
```
成功率约 70-80%,复杂任务建议用 OpenAI。 - 5
步骤5: 切换 OpenAI / Ollama
方式一:改 import
```python
from langchain_ollama import ChatOllama # 用 Ollama
from langchain_openai import ChatOpenAI # 用 OpenAI
```
方式二:OpenAI-Compatible API(不改 import)
```python
llm = ChatOpenAI(
base_url="http://localhost:11434/v1",
api_key="ollama"
)
```
常见问题
langchain-ollama 和 langchain_community.llms.Ollama 有什么区别?
ChatOllama 和 OllamaLLM 该用哪个?
RAG 系统中 chunk_size 和 k 值怎么设置?
Ollama 的工具调用为什么不如 OpenAI 稳定?
如何在 OpenAI 和 Ollama 之间切换?
Ollama 适合生产环境吗?
12 分钟阅读 · 发布于: 2026年4月7日 · 修改于: 2026年4月8日
相关文章
Ollama Embedding 实战:本地向量检索与 RAG 搭建
Ollama Embedding 实战:本地向量检索与 RAG 搭建
Ollama 多模型并行运行:Qwen、Llama、DeepSeek 配置实战
Ollama 多模型并行运行:Qwen、Llama、DeepSeek 配置实战
Ollama Modelfile 参数详解:创建专属定制模型的完整指南

评论
使用 GitHub 账号登录后即可评论