正在使用 AI 编程助手?
- 安装 LangChain 文档 MCP 服务器,让你的代理能够访问最新的 LangChain 文档和示例。
- 安装 LangChain Skills,以提升你的代理在 LangChain 生态系统任务上的性能。
安装依赖
安装以下包以跟随本教程:uv init
uv add langchain deepagents
uv sync
pip install -U langchain deepagents
python3 -m venv .venv
source .venv/bin/activate
# Windows: .venv\Scripts\activate
pip install -U langchain deepagents
设置 API 密钥
从任何受支持的模型提供商(例如,Google Gemini 或 OpenAI)获取 API 密钥。 设置 API 密钥,例如:- OpenAI
- Google Gemini
- Claude (Anthropic)
- OpenRouter
- Fireworks
- Baseten
- Ollama
- Azure
- AWS Bedrock
- HuggingFace
- 其他
export OPENAI_API_KEY="your-api-key"
export GOOGLE_API_KEY="your-api-key"
export ANTHROPIC_API_KEY="your-api-key"
export OPENROUTER_API_KEY="your-api-key"
export FIREWORKS_API_KEY="your-api-key"
export BASETEN_API_KEY="your-api-key"
# 本地:Ollama 必须正在运行 (https://ollama.com)
# 云:为你托管的推理设置 Ollama API 密钥
export OLLAMA_API_KEY="your-api-key"
export AZURE_OPENAI_API_KEY="your-api-key"
export AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com"
export AZURE_OPENAI_DEPLOYMENT_NAME="your-deployment"
export AWS_ACCESS_KEY_ID="your-access-key"
export AWS_SECRET_ACCESS_KEY="your-secret-key"
export AWS_REGION="us-east-1"
export HUGGINGFACEHUB_API_TOKEN="hf_..."
查看完整的受支持聊天模型集成列表。
构建基础代理
首先创建一个简单的代理,它能够回答问题并调用工具。本示例中的代理使用所选的语言模型、一个作为工具的基本天气函数,以及一个简单的提示来指导其行为:from langchain.agents import create_agent
def get_weather(city: str) -> str:
"""获取给定城市的天气。"""
return f"It's always sunny in {city}!"
agent = create_agent(
model="openai:gpt-5.4",
tools=[get_weather],
system_prompt="You are a helpful assistant",
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]}
)
print(result["messages"][-1].content_blocks)
from langchain.agents import create_agent
def get_weather(city: str) -> str:
"""获取给定城市的天气。"""
return f"It's always sunny in {city}!"
agent = create_agent(
model="google_genai:gemini-2.5-flash-lite",
tools=[get_weather],
system_prompt="You are a helpful assistant",
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]}
)
print(result["messages"][-1].content_blocks)
from langchain.agents import create_agent
def get_weather(city: str) -> str:
"""获取给定城市的天气。"""
return f"It's always sunny in {city}!"
agent = create_agent(
model="claude-sonnet-4-6",
tools=[get_weather],
system_prompt="You are a helpful assistant",
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]}
)
print(result["messages"][-1].content_blocks)
from langchain.agents import create_agent
def get_weather(city: str) -> str:
"""获取给定城市的天气。"""
return f"It's always sunny in {city}!"
agent = create_agent(
model="openrouter:anthropic/claude-sonnet-4-6",
tools=[get_weather],
system_prompt="You are a helpful assistant",
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]}
)
print(result["messages"][-1].content_blocks)
from langchain.agents import create_agent
def get_weather(city: str) -> str:
"""获取给定城市的天气。"""
return f"It's always sunny in {city}!"
agent = create_agent(
model="fireworks:accounts/fireworks/models/qwen3p5-397b-a17b",
tools=[get_weather],
system_prompt="You are a helpful assistant",
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]}
)
print(result["messages"][-1].content_blocks)
from langchain.agents import create_agent
def get_weather(city: str) -> str:
"""获取给定城市的天气。"""
return f"It's always sunny in {city}!"
agent = create_agent(
model="baseten:zai-org/GLM-5",
tools=[get_weather],
system_prompt="You are a helpful assistant",
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]}
)
print(result["messages"][-1].content_blocks)
from langchain.agents import create_agent
def get_weather(city: str) -> str:
"""获取给定城市的天气。"""
return f"It's always sunny in {city}!"
agent = create_agent(
model="ollama:devstral-2",
tools=[get_weather],
system_prompt="You are a helpful assistant",
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]}
)
print(result["messages"][-1].content_blocks)
import os
from langchain.agents import create_agent
def get_weather(city: str) -> str:
"""获取给定城市的天气。"""
return f"It's always sunny in {city}!"
agent = create_agent(
model="azure_openai:gpt-5.4",
tools=[get_weather],
system_prompt="You are a helpful assistant",
azure_deployment=os.environ["AZURE_OPENAI_DEPLOYMENT_NAME"],
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]}
)
print(result["messages"][-1].content_blocks)
from langchain.agents import create_agent
def get_weather(city: str) -> str:
"""获取给定城市的天气。"""
return f"It's always sunny in {city}!"
agent = create_agent(
model="anthropic.claude-3-5-sonnet-20240620-v1:0",
model_provider="bedrock_converse",
tools=[get_weather],
system_prompt="You are a helpful assistant",
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]}
)
print(result["messages"][-1].content_blocks)
from langchain.agents import create_agent
def get_weather(city: str) -> str:
"""获取给定城市的天气。"""
return f"It's always sunny in {city}!"
agent = create_agent(
model="microsoft/Phi-3-mini-4k-instruct",
model_provider="huggingface",
tools=[get_weather],
system_prompt="You are a helpful assistant",
temperature=0.7,
max_tokens=1024,
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]}
)
print(result["messages"][-1].content_blocks)
你可以通过更改代码中的模型名称并设置相应的 API 密钥来使用任何受支持的模型。
构建真实场景代理
在接下来的示例中,你将构建一个研究代理,它可以回答关于文本文件的问题。 在此过程中,你将探索以下概念:- 详细的系统提示,以改善代理行为
- 创建工具,与外部数据集成
- 模型配置,以获得一致的响应
- 对话记忆,实现类似聊天的交互
- 深度代理,提供内置功能
- 测试你的代理
1
定义系统提示
系统提示定义了你的代理的角色和行为。保持其具体且可操作:
SYSTEM_PROMPT = """You are a literary data assistant.
## Capabilities
- `fetch_text_from_url`: loads document text from a URL into the conversation.
Do not guess line counts or positions—ground them in tool results from the saved file."""
2
创建工具
工具允许模型通过调用你定义的函数与外部系统交互。
工具可以依赖于运行时上下文,也可以与代理记忆交互。此示例使用一个工具从给定 URL 加载文档:
import urllib.error
import urllib.request
from langchain.tools import tool
@tool
def fetch_text_from_url(url: str) -> str:
"""从 URL 获取文档。
"""
req = urllib.request.Request(
url,
headers={"User-Agent": "Mozilla/5.0 (compatible; quickstart-research/1.0)"},
)
try:
with urllib.request.urlopen(req, timeout=120) as resp:
raw = resp.read()
except urllib.error.URLError as e:
return f"Fetch failed: {e}"
text = raw.decode("utf-8", errors="replace")
return text
3
配置你的模型
为你的用例设置具有正确参数的语言模型。例如:根据所选的模型和提供商,初始化参数可能有所不同;请参阅其参考页面了解详情。
from langchain.chat_models import init_chat_model
model = init_chat_model(
"openai:gpt-5.4",
temperature=0.5,
timeout=300,
max_tokens=25000,
)
from langchain.chat_models import init_chat_model
model = init_chat_model(
"gemini-3.1-pro-preview",
model_provider="google-genai",
temperature=0.5,
timeout=600,
max_tokens=25000,
streaming=True,
)
from langchain.chat_models import init_chat_model
model = init_chat_model(
"claude-sonnet-4-6",
temperature=0.5,
timeout=600,
max_tokens=25000,
streaming=True,
)
from langchain.chat_models import init_chat_model
model = init_chat_model(
"openrouter:anthropic/claude-sonnet-4-6",
temperature=0.5,
timeout=300,
max_tokens=25000,
)
from langchain.chat_models import init_chat_model
model = init_chat_model(
"fireworks:accounts/fireworks/models/qwen3p5-397b-a17b",
temperature=0.5,
timeout=300,
max_tokens=25000,
)
from langchain.chat_models import init_chat_model
model = init_chat_model(
"baseten:zai-org/GLM-5",
temperature=0.5,
timeout=300,
max_tokens=25000,
)
from langchain.chat_models import init_chat_model
model = init_chat_model(
"ollama:devstral-2",
temperature=0.5,
timeout=300,
max_tokens=25000,
)
import os
from langchain.chat_models import init_chat_model
model = init_chat_model(
"azure_openai:gpt-5.4",
temperature=0.5,
timeout=300,
max_tokens=25000,
azure_deployment=os.environ["AZURE_OPENAI_DEPLOYMENT_NAME"],
)
from langchain.chat_models import init_chat_model
model = init_chat_model(
"anthropic.claude-3-5-sonnet-20240620-v1:0",
model_provider="bedrock_converse",
temperature=0.5,
timeout=300,
max_tokens=25000,
)
from langchain.chat_models import init_chat_model
model = init_chat_model(
"microsoft/Phi-3-mini-4k-instruct",
model_provider="huggingface",
temperature=0.5,
timeout=300,
max_tokens=25000,
)
4
5
创建并运行代理
现在,使用所有组件组装你的代理并运行它。创建代理有两种不同的框架:LangChain 代理和深度代理。
LangChain 代理和深度代理都为你提供了对工具、记忆等的细粒度控制。
两者的主要区别在于,深度代理内置了一系列常用功能,例如规划、文件系统工具和子代理。当你希望以最少的设置获得最大功能时,请使用深度代理;当你需要细粒度控制时,请选择 LangChain 代理。让我们尝试两种方式:
由于代码使用了《了不起的盖茨比》的全部文本来调用模型,因此它使用了大量的 token。你可以在下一步中查看示例输出。
from langchain.agents import create_agent
from deepagents import create_deep_agent
agent = create_agent(
model=model,
tools=[fetch_text_from_url],
system_prompt=SYSTEM_PROMPT,
checkpointer=checkpointer,
)
deep_agent = create_deep_agent(
model=model,
tools=[fetch_text_from_url],
system_prompt=SYSTEM_PROMPT,
checkpointer=checkpointer,
)
content = f"""Project Gutenberg hosts a full plain-text copy of F. Scott Fitzgerald's The Great Gatsby.
URL: https://www.gutenberg.org/files/64317/64317-0.txt
Answer as much as you can:
1) How many lines in the complete Gutenberg file contain the substring `Gatsby` (count lines, not occurrences within a line, each line ends with a line break).
2) The 1-based line number of the first line in the file that contains `Daisy`.
3) A two-sentence neutral synopsis.
Do your best on (1) and (2). If at any point you realize you cannot **verify** an exact answer with
your available tools and reasoning, do not fabricate numbers: use `null` for that field and spell out
the limitation in `how_you_computed_counts`. If you encounter any errors please report what the error was and what the error message was."""
agent_result = agent.invoke(
{"messages": [{"role": "user", "content": content}]},
config={"configurable": {"thread_id": "great-gatsby-lc"}},
)
deep_agent_result = deep_agent.invoke(
{"messages": [{"role": "user", "content": content}]},
config={"configurable": {"thread_id": "great-gatsby-da"}},
)
print(agent_result["messages"][-1].content_blocks)
print("\n")
print(deep_agent_result["messages"][-1].content_blocks)
Show 完整示例代码
Show 完整示例代码
import urllib.error
import urllib.request
from langchain.agents import create_agent
from deepagents import create_deep_agent
from langchain.chat_models import init_chat_model
from langchain.tools import tool
from langgraph.checkpoint.memory import InMemorySaver
SYSTEM_PROMPT = """You are a literary data assistant.
## Capabilities
- `fetch_text_from_url`: loads document text from a URL into the conversation.
Do not guess line counts or positions—ground them in tool results from the saved file."""
@tool
def fetch_text_from_url(url: str) -> str:
"""从 URL 获取文档。
"""
req = urllib.request.Request(
url,
headers={"User-Agent": "Mozilla/5.0 (compatible; quickstart-research/1.0)"},
)
try:
with urllib.request.urlopen(req, timeout=120) as resp:
raw = resp.read()
except urllib.error.URLError as e:
return f"Fetch failed: {e}"
text = raw.decode("utf-8", errors="replace")
return text
model = init_chat_model(
"gemini-3.1-pro-preview",
model_provider="google-genai",
temperature=0.5,
timeout=600,
max_tokens=25000,
streaming=True,
)
checkpointer = InMemorySaver()
agent = create_agent(
model=model,
tools=[fetch_text_from_url],
system_prompt=SYSTEM_PROMPT,
checkpointer=checkpointer,
)
deep_agent = create_deep_agent(
model=model,
tools=[fetch_text_from_url],
system_prompt=SYSTEM_PROMPT,
checkpointer=checkpointer,
)
content = f"""Project Gutenberg hosts a full plain-text copy of F. Scott Fitzgerald's The Great Gatsby.
URL: https://www.gutenberg.org/files/64317/64317-0.txt
Answer as much as you can:
1) How many lines in the complete Gutenberg file contain the substring `Gatsby` (count lines, not occurrences within a line, each line ends with a line break).
2) The 1-based line number of the first line in the file that contains `Daisy`.
3) A two-sentence neutral synopsis.
Do your best on (1) and (2). If at any point you realize you cannot **verify** an exact answer with
your available tools and reasoning, do not fabricate numbers: use `null` for that field and spell out
the limitation in `how_you_computed_counts`. If you encounter any errors please report what the error was and what the error message was."""
agent_result = agent.invoke(
{"messages": [{"role": "user", "content": content}]},
config={"configurable": {"thread_id": "great-gatsby-lc"}},
)
deep_agent_result = deep_agent.invoke(
{"messages": [{"role": "user", "content": content}]},
config={"configurable": {"thread_id": "great-gatsby-da"}},
)
print(agent_result["messages"][-1].content_blocks)
print("\n")
print(deep_agent_result["messages"][-1].content_blocks)
6
查看结果
结果会因模型和执行情况而异。如果你查看两个标签页上的输出,你会注意到 LangChain 代理提供了答案,但它们是估计值。代理缺乏回答此问题的工具。你也可能收到提示太长的错误。另一方面,深度代理可以:
- LangChain 代理
- 深度代理
**1) 包含 `Gatsby` 的行数:** `null`
**2) 包含 `Daisy` 的第一行:** `null`
**3) 概要:**
《了不起的盖茨比》讲述了神秘的百万富翁杰伊·盖茨比及其对与前情人黛西·布坎南重聚的痴迷,由他的邻居尼克·卡拉韦叙述。故事背景设定在长岛的咆哮二十年代,小说探讨了财富、阶级和美国梦的虚幻本质等主题。
**how_you_computed_counts:**
我成功使用 `fetch_text_from_url` 工具获取了电子书的全文。但是,由于我无法访问代码执行环境(如 Python)或文本处理工具(如 `grep`),我无法确定性地按换行符分割文本、遍历数千行并验证确切的行号或匹配计数。LLM 无法在其上下文窗口内可靠地对大量文本执行精确的行计数或索引,而无需外部计算工具。根据指示,我没有编造或猜测数字,而是为确切的计数和位置输出了 `null`。
根据直接从 Gutenberg URL 获取并使用文件系统搜索工具分析的文本,以下是对您问题的回答:
**1) 包含子字符串 `Gatsby` 的行**
**258** 行包含精确子字符串 `Gatsby`。
**2) 包含 `Daisy` 的第一行**
第 **181** 行是文件中包含精确子字符串 `Daisy` 的第一行。
*(供参考,该行内容为:"Buchanans. Daisy was my second cousin once removed, and I’d known Tom")*
**3) 两句中性概要**
*《了不起的盖茨比》* 讲述了神秘的百万富翁杰伊·盖茨比在 1920 年代的长岛痴迷地追求与前情人黛西·布坎南重聚的故事。故事由尼克·卡拉韦叙述,他观察到盖茨比不懈野心的悲剧后果以及那个时代富有的精英阶层的肤浅物质主义。
***
**计数是如何计算的:**
从 URL 获取文档时,文件太大无法通过标准输出显示,系统自动将其保存到本地文件系统(`/large_tool_results/x246ax2x`)。然后我使用 `grep` 工具在保存的文件中搜索精确的字面子字符串 `Gatsby` 和 `Daisy`。`grep` 工具返回了每个匹配行及其从 1 开始的行号。我手动计算了为 `Gatsby` 返回的精确行数(总计 258 行),并确定了为 `Daisy` 返回的第一个行号(即 181)。我还验证了没有大写变体(`GATSBY` 或 `DAISY`)会被遗漏。此过程中未遇到任何错误。
- 规划其方法,使用内置的
write_todos工具来分解研究任务。 - 加载文件,通过调用
fetch_text_from_url工具来收集信息。 - 管理上下文,使用文件系统工具(
grep和read_file)。 - 生成子代理,根据需要将复杂的子任务委托给专门的子代理。
跟踪代理调用
你使用 LangChain 构建的大多数有趣的应用程序都会对 LLM 进行多次调用。随着这些应用程序变得越来越复杂,能够检查代理内部到底发生了什么变得非常重要。最好的方法是使用 LangSmith。 注册一个 LangSmith 账户并设置以下环境变量以开始记录跟踪:export LANGSMITH_TRACING="true"
export LANGSMITH_API_KEY="..."
要了解更多关于使用 LangSmith 跟踪代理的信息,请参阅 LangSmith 文档。
后续步骤
你现在拥有的代理可以:- 理解上下文并记住对话
- 智能地使用工具
- 以一致的格式提供结构化响应
- 通过上下文处理用户特定信息
- 在交互中维护对话状态
- 规划、研究和综合(仅限深度代理)
将这些文档连接到 Claude、VSCode 等,通过 MCP 获取实时答案。

