Ollama: LangChain集成
LangChain 是 AI 应用的编排大师——模型是演员,Chain 是剧本,Agent 是导演。
💡 提示:LangChain 的核心是 Agent/Chain/Tool 三层架构——Chain 是固定流水线(Prompt→LLM→Parser),Tool 是可调用的外部能力(查询数据库、搜索文档),Agent 则是自主决策的调度器,动态选择调用哪些 Tool。90% 场景用 Chain 足够,需要动态决策时才用 Agent。
📋 前置知识:需要先掌握以下内容
- 第5课:REST API入门
- 第7课:Python SDK集成
1. 你将学到
- LangChain + Ollama 连接配置
- Prompt Template + Chain 链式提示工程
- Output Parser 结构化输出
- Tool-calling Agent 工具调用
- Alice 的 SaaS 指标分析 Agent
2. 一个初创 CTO 的真实故事
(1) 痛点:每月手动分析 50 份指标报告
Alice 的 SaaS 公司有 50 个业务指标,每月需人工分析趋势并撰写报告。一个分析师花 3 天完成,且容易遗漏异常信号。
(2) 解法:LangChain Agent 自动分析
用 LangChain + Ollama 构建 AI Agent,自动读取指标数据、识别异常、生成分析报告:
PYTHON
from langchain_ollama import ChatOllama
llm = ChatOllama(model="qwen2.5", temperature=0.2)
result = llm.invoke("Analyze the 20% drop in MRR last month")
3. LangChain + Ollama 连接
💡 提示:
ChatOllama 的 base_url 参数默认指向 http://localhost:11434。若 Ollama 部署在其他主机或 Docker 容器中,需显式设置 base_url="http://ollama:11434" 等对应地址。
(1) 安装与初始化
BASH
pip install langchain langchain-ollama langchain-community
(2) 两大核心组件
| 组件 | 类名 | 用途 |
|---|---|---|
| Chat Model | ChatOllama | 对话生成 |
| Embeddings | OllamaEmbeddings | 文本向量化 |
flowchart TD
A[LangChain App] --> B[ChatOllama<br/>qwen2.5 / llama3.2]
A --> C[OllamaEmbeddings<br/>nomic-embed-text]
B --> D[Ollama Server<br/>localhost:11434]
C --> D
| ChatOllama 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| model | str | — | 模型名称 |
| temperature | float | 0.8 | 随机性 |
| base_url | str | http://localhost:11434 | 服务地址 |
| num_ctx | int | 2048 | 上下文窗口 |
▶ 示例 1: ChatOllama 基础调用
PYTHON
from langchain_ollama import ChatOllama
from langchain_core.messages import HumanMessage, SystemMessage
# Initialize ChatOllama
llm = ChatOllama(model="qwen2.5", temperature=0.3)
# Simple invocation
response = llm.invoke("What is RAG?")
print(response.content)
# With system message
response = llm.invoke([
SystemMessage(content="You are a data analyst. Be concise."),
HumanMessage(content="What causes MRR to drop?")
])
print(response.content)
输出:
TEXT
📖 仅展示
# 执行成功
4. Prompt Template + Chain
(1) 链式提示工程
Prompt Template 让提示词可参数化、可复用、可组合:
flowchart LR
A[Input Variables] --> B[PromptTemplate]
B --> C[ChatOllama]
C --> D[Output Parser]
D --> E[Structured Result]
| Chain 类型 | 说明 | 适用场景 |
|---|---|---|
| LLMChain | Prompt → LLM → Output | 单步推理 |
| SequentialChain | 多 Chain 串联 | 多步分析 |
| RouterChain | 根据输入路由 | 分流处理 |
▶ 示例 2: Prompt Template + Chain
PYTHON
from langchain_ollama import ChatOllama
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
llm = ChatOllama(model="qwen2.5", temperature=0.3)
# Define prompt template
prompt = ChatPromptTemplate.from_messages([
("system", "You are a {role}. Be concise and professional."),
("human", "{input}")
])
# Build chain: prompt -> llm -> parser
chain = prompt | llm | StrOutputParser()
# Invoke with variables
result = chain.invoke({
"role": "customer service agent for e-commerce",
"input": "Customer wants to cancel order #12345"
})
print(result)
输出:
TEXT
📖 仅展示
# 执行成功
5. Output Parser 结构化输出
⚠️ 警告: 小模型(3B 参数以下)生成 JSON 结构不稳定,
PydanticOutputParser 可能频繁解析失败。建议使用 8B+ 模型配合 format="json" 参数,并在代码中加入 try/except 重试逻辑。
(1) 常用 Output Parser
| Parser | 用途 | 输出格式 |
|---|---|---|
| StrOutputParser | 纯文本 | string |
| JsonOutputParser | JSON 对象 | dict |
| PydanticOutputParser | Pydantic 模型 | typed object |
| CommaSeparatedListOutputParser | 逗号分隔列表 | list[str] |
(2) Pydantic 结构化输出对比
| 方式 | 优点 | 缺点 |
|---|---|---|
| format=json | 简单 | 无类型校验 |
| JsonOutputParser | 有 schema 提示 | 解析可能失败 |
| PydanticOutputParser | 完整类型校验 | 依赖模型遵循 schema |
▶ 示例 3: Pydantic 结构化输出
PYTHON
from langchain_ollama import ChatOllama
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field
# Define output schema
class CustomerIntent(BaseModel):
intent: str = Field(description="Customer intent category")
confidence: float = Field(description="Confidence score 0-1")
order_number: str | None = Field(description="Order number if mentioned")
# Create parser
parser = PydanticOutputParser(pydantic_object=CustomerIntent)
# Build chain with format instructions
llm = ChatOllama(model="qwen2.5", temperature=0.1, format="json")
prompt = ChatPromptTemplate.from_messages([
("system", "Classify the customer intent.\n{format_instructions}"),
("human", "{query}")
])
chain = prompt | llm | parser
# Invoke
result = chain.invoke({
"query": "I want to track my order #88765",
"format_instructions": parser.get_format_instructions()
})
print(f"Intent: {result.intent}")
print(f"Confidence: {result.confidence}")
print(f"Order: {result.order_number}")
输出:
TEXT
📖 仅展示
# 执行成功
6. Tool-calling Agent
⚠️ 注意:Agent 可能产生不稳定输出——本地模型的推理循环可能出现"死循环"(反复调用同一工具)或"幻觉工具调用"(调用不存在的工具)。务必设置
max_iterations=3-5 限制循环次数,并用 temperature=0 提高确定性。3B 模型的 Agent 能力有限,建议 8B+。
💡 提示: Ollama 本地模型的 Function Calling 能力不如 GPT-4 稳定。推荐使用 ReAct Agent +
@tool 装饰器模式替代原生 Function Calling,兼容性更好,且 temperature=0 可提高工具调用的确定性。
(1) Agent 架构
flowchart TD
A[User Input] --> B[Agent]
B --> C{Need Tool?}
C -->|Yes| D[Call Tool]
D --> E[Tool Result]
E --> B
C -->|No| F[Final Answer]
| Agent 类型 | 说明 | 适用场景 |
|---|---|---|
| ReAct Agent | 推理+行动循环 | 需调用工具的复杂任务 |
| Structured Chat | 结构化工具调用 | 多工具多参数 |
| OpenAI Functions | 函数调用模式 | Ollama 部分支持 |
(2) 工具定义模式
| 定义方式 | 说明 | 示例 |
|---|---|---|
| @tool 装饰器 | 简单工具 | @tool def func(...) |
| StructuredTool | 带描述工具 | StructuredTool.from_function(...) |
| Pydantic + BaseTool | 强类型工具 | class MyTool(BaseTool) |
▶ 示例 4: ReAct Agent 实战
PYTHON
from langchain_ollama import ChatOllama
from langchain_core.tools import tool
from langchain.agents import AgentExecutor, create_react_agent
from langchain_core.prompts import PromptTemplate
# Define tools
@tool
def get_order_status(order_id: str) -> str:
"""Get the status of an order by its ID."""
# Simulated database lookup
orders = {
"12345": "Shipped, arriving in 2 days",
"88765": "Processing, shipping tomorrow",
"99999": "Delivered on 2024-01-15"
}
return orders.get(order_id, f"Order {order_id} not found")
@tool
def check_product_stock(product_name: str) -> str:
"""Check if a product is in stock."""
stock = {
"wireless headphones": "In stock: 45 units",
"laptop stand": "Out of stock, restock in 3 days",
"usb cable": "In stock: 200 units"
}
return stock.get(product_name.lower(), f"Product '{product_name}' not found")
# Build agent
llm = ChatOllama(model="qwen2.5", temperature=0)
tools = [get_order_status, check_product_stock]
prompt = PromptTemplate.from_template(
"""Answer the following question. You have access to these tools:
{tools}
Use this format:
Question: the input question
Thought: what to do
Action: tool name (one of [{tool_names}])
Action Input: tool input
Observation: tool output
... (repeat Thought/Action/Action Input/Observation)
Thought: I know the final answer
Final Answer: the final answer
Question: {input}
{agent_scratchpad}"""
)
agent = create_react_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# Run agent
result = agent_executor.invoke({
"input": "What is the status of order 88765?"
})
print(result["output"])
输出:
TEXT
📖 仅展示
# 函数定义成功
7. 综合示例:Alice 的 SaaS 指标分析 Agent
ℹ️ 信息: LangChain 的
AgentExecutor 默认 max_iterations=15,但本地模型推理较慢,建议设为 3-5 防止无限循环。同时设置 verbose=True 便于观察 Agent 的推理过程。
PYTHON
# ============================================
# Comprehensive: SaaS metrics analysis agent
# Uses LangChain + Ollama for automated analysis
# ============================================
from langchain_ollama import ChatOllama
from langchain_core.tools import tool
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain.agents import AgentExecutor, create_react_agent
from langchain_core.prompts import PromptTemplate
import json
# Simulated metrics database
METRICS_DB = {
"mrr": {"current": 85000, "previous": 106250, "change": -20},
"churn_rate": {"current": 8.5, "previous": 5.2, "change": 63},
"arr": {"current": 1020000, "previous": 1275000, "change": -20},
"active_users": {"current": 12500, "previous": 11800, "change": 6},
"cac": {"current": 250, "previous": 180, "change": 39},
"ltv": {"current": 2400, "previous": 3200, "change": -25}
}
@tool
def get_metric(metric_name: str) -> str:
"""Get a SaaS metric value. Available: mrr, churn_rate, arr, active_users, cac, ltv."""
data = METRICS_DB.get(metric_name.lower())
if data:
return json.dumps(data)
return f"Metric '{metric_name}' not found. Available: {list(METRICS_DB.keys())}"
@tool
def compare_metrics(metric1: str, metric2: str) -> str:
"""Compare two metrics and identify correlations."""
m1 = METRICS_DB.get(metric1.lower())
m2 = METRICS_DB.get(metric2.lower())
if not m1 or not m2:
return "One or both metrics not found."
return json.dumps({
"metric1": {"name": metric1, **m1},
"metric2": {"name": metric2, **m2},
"correlation_note": "Both metrics show negative trends"
})
# Build analysis agent
llm = ChatOllama(model="qwen2.5", temperature=0.2)
tools = [get_metric, compare_metrics]
prompt = PromptTemplate.from_template(
"""You are a SaaS metrics analyst. Analyze data and provide insights.
Available tools: {tools}
Format:
Question: the input
Thought: what to do
Action: tool name from [{tool_names}]
Action Input: tool input
Observation: tool output
... (repeat as needed)
Thought: I have enough information
Final Answer: detailed analysis with actionable recommendations
Question: {input}
{agent_scratchpad}"""
)
agent = create_react_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True, max_iterations=5)
# Run analysis
if __name__ == "__main__":
result = executor.invoke({
"input": "MRR dropped 20% last month. Analyze the key metrics and identify likely causes with recommendations."
})
print("\n=== Analysis Report ===")
print(result["output"])
❓ 常见问题
Q langchain-ollama 和 langchain-community 有什么区别?
A 是官方 Ollama 集成包,包含 ChatOllama 和 OllamaEmbeddings。 也包含旧版集成,但推荐用官方包。
Q Agent 的工具调用不稳定怎么办?
A 降低 temperature 到 0,确保工具描述清晰,使用 format=json 强制结构化输出。小模型(3B)Agent 能力有限,建议 8B+。
Q LangChain 的 Chain 和 Agent 怎么选?
A 固定流程用 Chain(Prompt → LLM → Parser),动态决策用 Agent(自主选择工具和步骤)。90% 场景 Chain 足够。
Q PydanticOutputParser 解析失败怎么办?
A 加 强制 JSON 输出。加 在 prompt 中明确格式。失败时回退到 JsonOutputParser。
Q Ollama 模型支持 Function Calling 吗?
A 部分支持。qwen2.5 和 llama3.1 有一定 Function Calling 能力,但不如 GPT-4 稳定。建议用 ReAct Agent + tool 装饰器替代。
Q 如何调试 Agent 的推理过程?
A 设置 查看 Agent 的 Thought/Action/Observation 循环。LangSmith( tracelangchain.com)可可视化完整执行链。
📖 小节
- ChatOllama 是 LangChain 连接 Ollama 的核心类,支持对话和流式输出
- Prompt Template 让提示可参数化,Chain 让流程可组合
- Output Parser 将 LLM 文本转为结构化数据(JSON/Pydantic/List)
- ReAct Agent 实现推理+行动循环,可调用自定义工具
- Alice 用 LangChain Agent 自动分析 SaaS 指标,3 天工作缩短到 3 分钟
- Agent 需 8B+ 模型才能稳定,3B 模型推理能力不足
📝 作业
- 基础题(难度⭐):用 ChatOllama + PromptTemplate 构建一个 Chain,实现客服意图分类(输出 JSON 格式)。
- 进阶题(难度⭐⭐):创建一个带 2 个工具(查询订单 + 查库存)的 ReAct Agent,测试 3 个不同问题的工具调用。
- 挑战题(难度⭐⭐⭐):为 Alice 构建 SaaS 指标分析 Agent——包含至少 4 个工具(获取指标、对比指标、生成图表描述、发送告警),输出结构化分析报告。