Skip to main content
您可以在 Claude 文档中找到有关 Anthropic 最新模型的信息,包括其成本、上下文窗口和支持的输入类型。
API 参考有关所有功能和配置选项的详细文档,请前往 ChatAnthropic API 参考。
AWS Bedrock 和 Google VertexAI请注意,某些 Anthropic 模型也可以通过 AWS Bedrock 和 Google VertexAI 访问。请参阅 ChatBedrockChatVertexAI 集成,以通过这些服务使用 Anthropic 模型。对于在 AWS Bedrock 上使用与 ChatAnthropic 相同 API 的 Anthropic 模型,请使用 langchain-aws 中的 ChatAnthropicBedrock

概述

集成详情

可序列化JS/TS 支持下载量最新版本
ChatAnthropiclangchain-anthropicbeta(npm)Downloads per monthPyPI - Latest version

模型功能

工具调用结构化输出图像输入音频输入视频输入令牌级流式传输原生异步令牌使用情况Logprobs

设置

要访问 Anthropic (Claude) 模型,您需要安装 langchain-anthropic 集成包并获取 Claude API 密钥。

安装

pip install -U langchain-anthropic

凭证

前往 Claude 控制台 注册并生成 Claude API 密钥。完成此操作后,设置 ANTHROPIC_API_KEY 环境变量:
import getpass
import os

if "ANTHROPIC_API_KEY" not in os.environ:
    os.environ["ANTHROPIC_API_KEY"] = getpass.getpass("Enter your Anthropic API key: ")
要启用模型调用的自动跟踪,请设置您的 LangSmith API 密钥:
os.environ["LANGSMITH_API_KEY"] = getpass.getpass("Enter your LangSmith API key: ")
os.environ["LANGSMITH_TRACING"] = "true"

实例化

现在我们可以实例化我们的模型对象并生成聊天补全:
from langchain_anthropic import ChatAnthropic

model = ChatAnthropic(
    model="claude-haiku-4-5-20251001",
    # temperature=,
    # max_tokens=,
    # timeout=,
    # max_retries=,
    # ...
)
有关所有可用实例化参数的详细信息,请参阅 ChatAnthropic API 参考。
推理地理位置要控制模型推理运行的位置以满足数据驻留要求,请在创建 ChatAnthropic 时传递 inference_geo。有关支持的值,请参阅 Anthropic 文档。

调用

messages = [
    (
        "system",
        "You are a helpful translator. Translate the user sentence to French.",
    ),
    (
        "human",
        "I love programming.",
    ),
]
ai_msg = model.invoke(messages)
print(ai_msg.text)
J'adore la programmation.
for chunk in model.stream(messages):
    print(chunk.text, end="")
AIMessageChunk(content="J", id="run-272ff5f9-8485-402c-b90d-eac8babc5b25")
AIMessageChunk(content="'", id="run-272ff5f9-8485-402c-b90d-eac8babc5b25")
AIMessageChunk(content="a", id="run-272ff5f9-8485-402c-b90d-eac8babc5b25")
AIMessageChunk(content="ime", id="run-272ff5f9-8485-402c-b90d-eac8babc5b25")
AIMessageChunk(content=" la", id="run-272ff5f9-8485-402c-b90d-eac8babc5b25")
AIMessageChunk(content=" programm", id="run-272ff5f9-8485-402c-b90d-eac8babc5b25")
AIMessageChunk(content="ation", id="run-272ff5f9-8485-402c-b90d-eac8babc5b25")
AIMessageChunk(content=".", id="run-272ff5f9-8485-402c-b90d-eac8babc5b25")
要从流中聚合完整消息:
stream = model.stream(messages)
full = next(stream)
for chunk in stream:
    full += chunk
full
AIMessageChunk(content="J'aime la programmation.", id="run-b34faef0-882f-4869-a19c-ed2b856e6361")
ai_msg = await model.ainvoke(messages)

# stream
async for chunk in model.astream(messages):
    print(chunk.text, end="")

# batch
await model.abatch([messages])
AIMessage(
    content="J'aime la programmation.",
    response_metadata={
        "id": "msg_01Trik66aiQ9Z1higrD5XFx3",
        "model": "claude-sonnet-4-6",
        "stop_reason": "end_turn",
        "stop_sequence": None,
        "usage": {"input_tokens": 25, "output_tokens": 11},
    },
    id="run-5886ac5f-3c2e-49f5-8a44-b1e92808c929-0",
    usage_metadata={
        "input_tokens": 25,
        "output_tokens": 11,
        "total_tokens": 36,
    },
)
有关支持的调用方法的更多信息,请参阅我们的模型指南。

内容块

当使用工具、扩展思考和其他功能时,来自单个 Anthropic AIMessage 的内容可以是单个字符串,也可以是 Anthropic 内容块的列表。 例如,当 Anthropic 模型调用工具时,工具调用是消息内容的一部分(也暴露在标准化的 AIMessage.tool_calls 中):
from langchain_anthropic import ChatAnthropic
from typing_extensions import Annotated

model = ChatAnthropic(model="claude-haiku-4-5-20251001")


def get_weather(
    location: Annotated[str, ..., "Location as city and state."]
) -> str:
    """Get the weather at a location."""
    return "It's sunny."


model_with_tools = model.bind_tools([get_weather])
response = model_with_tools.invoke("Which city is hotter today: LA or NY?")
response.content
[{'text': "I'll help you compare the temperatures of Los Angeles and New York by checking their current weather. I'll retrieve the weather for both cities.",
  'type': 'text'},
 {'id': 'toolu_01CkMaXrgmsNjTso7so94RJq',
  'input': {'location': 'Los Angeles, CA'},
  'name': 'get_weather',
  'type': 'tool_use'},
 {'id': 'toolu_01SKaTBk9wHjsBTw5mrPVSQf',
  'input': {'location': 'New York, NY'},
  'name': 'get_weather',
  'type': 'tool_use'}]
使用 content_blocks 将以 LangChain 的标准格式呈现内容,该格式与其他模型提供商保持一致。阅读有关内容块的更多信息。
response.content_blocks
您还可以使用 tool_calls 属性以标准格式专门访问工具调用:
response.tool_calls
[{'name': 'GetWeather',
  'args': {'location': 'Los Angeles, CA'},
  'id': 'toolu_01Ddzj5PkuZkrjF4tafzu54A'},
 {'name': 'GetWeather',
  'args': {'location': 'New York, NY'},
  'id': 'toolu_012kz4qHZQqD4qg8sFPeKqpP'}]

工具

Anthropic 的工具使用功能允许您定义 Claude 可以在对话期间调用的外部函数。这使得动态信息检索、计算以及与外部系统的交互成为可能。 有关如何将工具绑定到模型实例的详细信息,请参阅 ChatAnthropic.bind_tools
有关 Claude 内置工具(代码执行、Web 浏览、文件 API 等)的信息,请参阅内置工具
from pydantic import BaseModel, Field


class GetWeather(BaseModel):
    '''Get the current weather in a given location'''

    location: str = Field(description="The city and state, e.g. San Francisco, CA")


class GetPopulation(BaseModel):
    '''Get the current population in a given location'''

    location: str = Field(description="The city and state, e.g. San Francisco, CA")


model_with_tools = model.bind_tools([GetWeather, GetPopulation])
ai_msg = model_with_tools.invoke("Which city is hotter today and which is bigger: LA or NY?")
ai_msg.tool_calls
[
    {
        "name": "GetWeather",
        "args": {"location": "Los Angeles, CA"},
        "id": "toolu_01KzpPEAgzura7hpBqwHbWdo",
    },
    {
        "name": "GetWeather",
        "args": {"location": "New York, NY"},
        "id": "toolu_01JtgbVGVJbiSwtZk3Uycezx",
    },
    {
        "name": "GetPopulation",
        "args": {"location": "Los Angeles, CA"},
        "id": "toolu_01429aygngesudV9nTbCKGuw",
    },
    {
        "name": "GetPopulation",
        "args": {"location": "New York, NY"},
        "id": "toolu_01JPktyd44tVMeBcPPnFSEJG",
    },
]

严格工具使用

严格工具使用需要 langchain-anthropic>=1.1.0。有关支持的模型,请参阅 Claude 文档
Anthropic 支持选择加入对工具调用的严格模式遵循。这保证了工具名称和参数通过约束解码得到验证和正确类型化。 在没有严格模式的情况下,Claude 有时会生成无效的工具输入,从而破坏您的应用程序:
  • 类型不匹配passengers: "2" 而不是 passengers: 2
  • 缺少必填字段:省略函数期望的字段
  • 无效的枚举值:超出允许集的值
  • 模式违规:嵌套对象不符合预期结构
严格工具使用保证模式合规的工具调用:
  • 工具输入严格遵循您的 input_schema
  • 保证字段类型和必填字段
  • 消除对格式错误输入的错误处理
  • 工具 name 始终来自提供的工具
使用严格工具使用使用标准工具调用
构建可靠性至关重要的智能体工作流简单的单轮工具调用
具有许多参数或嵌套对象的工具原型设计和实验
需要特定类型(例如 int vs str)的函数
要启用严格工具使用,请在调用 bind_tools 时指定 strict=True
from langchain_anthropic import ChatAnthropic

model = ChatAnthropic(model="claude-sonnet-4-6")

def get_weather(location: str) -> str:
    """Get the weather at a location."""
    return "It's sunny."

model_with_tools = model.bind_tools([get_weather], strict=True)
考虑一个预订系统,其中 passengers 必须是整数:
from langchain_anthropic import ChatAnthropic
from typing import Literal

model = ChatAnthropic(model="claude-sonnet-4-6")

def book_flight(
    destination: str,
    departure_date: str,
    passengers: int,
    cabin_class: Literal["economy", "business", "first"]
) -> str:
    """Book a flight to a destination.

    Args:
        destination: The destination city
        departure_date: Date in YYYY-MM-DD format
        passengers: Number of passengers (must be an integer)
        cabin_class: The cabin class for the flight
    """
    return f"Booked {passengers} passengers to {destination}"

model_with_tools = model.bind_tools(
    [book_flight],
    strict=True,
    tool_choice="any",
)
response = model_with_tools.invoke("Book 2 passengers to Tokyo, business class, 2025-01-15")

# With strict=True, passengers is guaranteed to be int, not "2" or "two"
print(response.tool_calls[0]["args"]["passengers"])
2
严格工具使用有一些需要注意的 JSON 模式限制。有关更多详细信息,请参阅 Claude 文档 如果您的工具模式使用了不受支持的功能,您将收到 400 错误。在这些情况下,请简化模式或使用标准(非严格)工具调用。

输入示例

对于复杂工具,您可以提供使用示例以帮助 Claude 正确使用它们。这可以通过在工具的 extras 参数中设置 input_examples 来完成。
from langchain_anthropic import ChatAnthropic
from langchain.tools import tool

@tool(
    extras={
        "input_examples": [
            {
                "query": "weather report",
                "location": "San Francisco",
                "format": "detailed"
            },
            {
                "query": "temperature",
                "location": "New York",
                "format": "brief"
            }
        ]
    }
)
def search_weather_data(query: str, location: str, format: str = "brief") -> str:
    """Search weather database with specific query and format preferences.

    Args:
        query: The type of weather information to retrieve
        location: City or region to search
        format: Output format, either 'brief' or 'detailed'
    """
    return f"{format.title()} {query} for {location}: Data found"

model = ChatAnthropic(model="claude-sonnet-4-6")
model_with_tools = model.bind_tools([search_weather_data])

response = model_with_tools.invoke(
    "Get me a detailed weather report for Seattle"
)
extras 参数还支持:

细粒度工具流式传输

Anthropic 支持细粒度工具流式传输,这可以减少流式传输具有大参数的工具调用时的延迟。 细粒度流式传输不是在传输前缓冲整个参数值,而是在参数数据可用时立即发送。对于大工具参数,这可以将初始延迟从 15 秒减少到大约 3 秒。
细粒度流式传输可能会返回无效或部分的 JSON 输入,特别是如果响应在完成之前达到 max_tokens。请为不完整的 JSON 数据实现适当的错误处理。
要为应增量流式传输工具参数的工具启用细粒度工具流式传输,请在工具上设置 extras={"eager_input_streaming": True}。该值将通过工具定义传递给 Anthropic API。
from langchain_anthropic import ChatAnthropic
from langchain.tools import tool

model = ChatAnthropic(model="claude-sonnet-4-6")

@tool(extras={"eager_input_streaming": True})
def write_document(title: str, content: str) -> str:
    """Write a document with the given title and content."""
    return f"Document '{title}' written successfully"

model_with_tools = model.bind_tools([write_document])

# Stream tool calls with reduced latency
for chunk in model_with_tools.stream(
    "Write a detailed technical document about the benefits of streaming APIs"
):
    print(chunk.content)
流式传输数据作为 input_json_delta 块到达 chunk.content。您可以累积这些块以构建完整的工具参数:
import json

from langchain_anthropic import ChatAnthropic
from langchain.tools import tool

model = ChatAnthropic(model="claude-sonnet-4-6")

@tool(extras={"eager_input_streaming": True})
def write_document(title: str, content: str) -> str:
    """Write a document with the given title and content."""
    return f"Document '{title}' written successfully"

model_with_tools = model.bind_tools([write_document])

accumulated_json = ""

for chunk in model_with_tools.stream("Write a document about AI"):
    for block in chunk.content:
        if isinstance(block, dict) and block.get("type") == "input_json_delta":
            accumulated_json += block.get("partial_json", "")
            try:
                # Try to parse accumulated JSON
                parsed = json.loads(accumulated_json)
                print(f"Complete args: {parsed}")
            except json.JSONDecodeError:
                # JSON is still incomplete, continue accumulating
                pass
Complete args: {'title': 'Artificial Intelligence: An Overview', 'content': '# Artificial Intelligence: An Overview...

程序化工具调用

程序化工具调用需要 langchain-anthropic>=1.3.0。有关支持的模型,请参阅 Claude 文档
工具可以配置为可从 Claude 的代码执行环境调用,从而在涉及大数据处理或多工具工作流的上下文中减少延迟和令牌消耗。 有关详细信息,请参阅 Claude 的程序化工具调用指南。要使用此功能:
  • 在您的工具集中包含代码执行内置工具
  • 在您希望以编程方式调用的工具上指定 extras={"allowed_callers": ["code_execution_20250825"]}
请参阅下面使用 create_agent 的完整示例。
您可以在初始化时指定 reuse_last_container 以自动重用先前模型响应的代码执行容器。
from langchain.agents import create_agent
from langchain.tools import tool
from langchain_anthropic import ChatAnthropic


@tool(extras={"allowed_callers": ["code_execution_20250825"]})
def get_weather(location: str) -> str:
    """Get the weather at a location."""
    return "It's sunny."

tools = [
    {"type": "code_execution_20250825", "name": "code_execution"},
    get_weather,
]

model = ChatAnthropic(
    model="claude-sonnet-4-6",
    reuse_last_container=True,
)

agent = create_agent(model, tools=tools)

input_query = {
    "role": "user",
    "content": "What's the weather in Boston?",
}

result = agent.invoke({"messages": [input_query]})

多模态

Claude 支持图像和 PDF 输入作为内容块,既支持 Anthropic 的原生格式(请参阅视觉PDF 支持文档),也支持 LangChain 的标准格式

支持的输入方法

方法图像PDF
Base64 内联数据
HTTP/HTTPS URL
Files API
Files API 也可用于将文件上传到容器,以便与 Claude 的内置代码执行工具一起使用。有关详细信息,请参阅代码执行部分。

图像输入

使用带有列表内容格式的 HumanMessage 提供图像输入和文本。
from langchain_anthropic import ChatAnthropic
from langchain.messages import HumanMessage

model = ChatAnthropic(model="claude-sonnet-4-6")

message = HumanMessage(
    content=[
        {"type": "text", "text": "Describe the image at the URL."},
        {
            "type": "image",
            "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg",
        },
    ]
)
response = model.invoke([message])

PDF 输入

提供 PDF 文件输入和文本。
from langchain_anthropic import ChatAnthropic
from langchain.messages import HumanMessage

model = ChatAnthropic(model="claude-sonnet-4-6")

message = HumanMessage(
    content=[
        {"type": "text", "text": "Summarize this document."},
        {
            "type": "file",
            "url": "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
            "mime_type": "application/pdf",
        },
    ]
)
response = model.invoke([message])

扩展思考

某些 Claude 模型支持扩展思考功能,该功能将输出导致其最终答案的逐步推理过程。 请参阅 Claude 文档 中的兼容模型。 要使用扩展思考,请在初始化 ChatAnthropic 时指定 thinking 参数。如果需要,也可以在调用期间作为参数传递。 对于 Claude Sonnet 及更早的模型,您需要指定令牌预算。对于 Claude Opus 4.6+,您可以使用自适应思考,它会自动确定预算。
import json
from langchain_anthropic import ChatAnthropic

model = ChatAnthropic(
    model="claude-sonnet-4-6",
    max_tokens=5000,
    thinking={"type": "enabled", "budget_tokens": 2000},
)

response = model.invoke("What is the cube root of 50.653?")
print(json.dumps(response.content_blocks, indent=2))
[
  {
    "type": "reasoning",
    "reasoning": "To find the cube root of 50.653, I need to find the value of $x$ such that $x^3 = 50.653$.\n\nI can try to estimate this first. \n$3^3 = 27$\n$4^3 = 64$\n\nSo the cube root of 50.653 will be somewhere between 3 and 4, but closer to 4.\n\nLet me try to compute this more precisely. I can use the cube root function:\n\ncube root of 50.653 = 50.653^(1/3)\n\nLet me calculate this:\n50.653^(1/3) \u2248 3.6998\n\nLet me verify:\n3.6998^3 \u2248 50.6533\n\nThat's very close to 50.653, so I'm confident that the cube root of 50.653 is approximately 3.6998.\n\nActually, let me compute this more precisely:\n50.653^(1/3) \u2248 3.69981\n\nLet me verify once more:\n3.69981^3 \u2248 50.652998\n\nThat's extremely close to 50.653, so I'll say that the cube root of 50.653 is approximately 3.69981.",
    "extras": {"signature": "ErUBCkYIBxgCIkB0UjV..."}
  },
  {
    "type": "text",
    "text": "The cube root of 50.653 is approximately 3.6998.\n\nTo verify: 3.6998\u00b3 = 50.6530, which is very close to our original number.",
  }
]
Claude Messages API 在 Claude Sonnet 3.7 和 Claude 4 模型之间处理思考的方式不同。有关更多信息,请参阅 Claude 文档

努力程度

某些 Claude 模型支持努力程度功能,该功能控制 Claude 响应时使用的令牌数量。这对于在响应质量与延迟和成本之间取得平衡非常有用。
模型支持努力程度通常在 Claude Opus 4.6 和 Claude Opus 4.5 上可用。max 努力级别仅在 Claude Opus 4.6 上受支持。xhigh 努力级别在 Claude Opus 4.7 上受支持。Anthropic 可能会随着时间的推移添加或调整模型支持——请使用 Claude 努力程度文档 作为真实来源。
from langchain_anthropic import ChatAnthropic

model = ChatAnthropic(
    model="claude-opus-4-5-20251101",
    effort="medium",  # Options: "max", "xhigh", "high", "medium", "low"
)

response = model.invoke("Analyze the trade-offs between microservices and monolithic architectures")
effort 设置为 "high" 会产生与完全省略该参数完全相同的行为。
有关何时使用不同努力级别以及查看支持模型的详细信息,请参阅 Claude 文档

任务预算

Claude Opus 4.7 支持任务预算,这是智能体循环(思考、工具调用、工具结果和最终输出)的咨询令牌目标。模型会看到一个运行倒计时,并使用它来优先处理工作并优雅地完成。与 max_tokens 不同,任务预算不是硬性限制。
任务预算需要 langchain-anthropic>=1.4.1,目前处于测试阶段。
from langchain_anthropic import ChatAnthropic

model = ChatAnthropic(
    model="claude-opus-4-7",
    output_config={
        "effort": "high",
        "task_budget": {"type": "tokens", "total": 128_000},
    },
)

引用

Anthropic 支持引用功能,允许 Claude 根据用户提供的源文档为其答案附加上下文。 当查询中包含带有 "citations": {"enabled": True}文档search_result 内容块时,Claude 可能会在其响应中生成引用。

简单示例

在此示例中,我们传递一个纯文本文档。在后台,Claude 会自动分块输入文本为句子,这些句子在生成引用时使用。
from langchain_anthropic import ChatAnthropic

model = ChatAnthropic(model="claude-haiku-4-5-20251001")

messages = [
    {
        "role": "user",
        "content": [
            {
                "type": "document",
                "source": {
                    "type": "text",
                    "media_type": "text/plain",
                    "data": "The grass is green. The sky is blue.",
                },
                "title": "My Document",
                "context": "This is a trustworthy document.",
                "citations": {"enabled": True},
            },
            {"type": "text", "text": "What color is the grass and sky?"},
        ],
    }
]
response = model.invoke(messages)
response.content
[{'text': 'Based on the document, ', 'type': 'text'},
 {'text': 'the grass is green',
  'type': 'text',
  'citations': [{'type': 'char_location',
    'cited_text': 'The grass is green. ',
    'document_index': 0,
    'document_title': 'My Document',
    'start_char_index': 0,
    'end_char_index': 20}]},
 {'text': ', and ', 'type': 'text'},
 {'text': 'the sky is blue',
  'type': 'text',
  'citations': [{'type': 'char_location',
    'cited_text': 'The sky is blue.',
    'document_index': 0,
    'document_title': 'My Document',
    'start_char_index': 20,
    'end_char_index': 36}]},
 {'text': '.', 'type': 'text'}]

在工具结果中(智能体 RAG)

Claude 支持一个 search_result 内容块,表示来自知识库或其他自定义源的可引用查询结果。这些内容块可以传递给 Claude,既可以作为顶级内容(如上例所示),也可以在工具结果中。这允许 Claude 使用工具调用的结果来引用其响应的元素。 要传递工具调用的搜索结果,请定义一个工具,该工具以 Anthropic 的原生格式返回 search_result 内容块列表。例如:
def retrieval_tool(query: str) -> list[dict]:
    """Access my knowledge base."""

    # Run a search (e.g., with a LangChain vector store)
    results = vector_store.similarity_search(query=query, k=2)

    # Package results into search_result blocks
    return [
        {
            "type": "search_result",
            # Customize fields as desired, using document metadata or otherwise
            "title": "My Document Title",
            "source": "Source description or provenance",
            "citations": {"enabled": True},
            "content": [{"type": "text", "text": doc.page_content}],
        }
        for doc in results
    ]
这里我们演示一个端到端示例,其中我们使用示例文档填充 LangChain 向量存储,并为 Claude 配备一个查询这些文档的工具。此处的工具接受搜索查询和 category 字符串字面量,但可以使用任何有效的工具签名。此示例需要安装 langchain-openainumpy
pip install langchain-openai numpy
from typing import Literal

from langchain.chat_models import init_chat_model
from langchain.embeddings import init_embeddings
from langchain_core.documents import Document
from langchain_core.vectorstores import InMemoryVectorStore
from langgraph.checkpoint.memory import InMemorySaver
from langchain.agents import create_agent


# Set up vector store
# Ensure you set your OPENAI_API_KEY environment variable
embeddings = init_embeddings("openai:text-embedding-3-small")
vector_store = InMemoryVectorStore(embeddings)

document_1 = Document(
    id="1",
    page_content=(
        "To request vacation days, submit a leave request form through the "
        "HR portal. Approval will be sent by email."
    ),
    metadata={
        "category": "HR Policy",
        "doc_title": "Leave Policy",
        "provenance": "Leave Policy - page 1",
    },
)
document_2 = Document(
    id="2",
    page_content="Managers will review vacation requests within 3 business days.",
    metadata={
        "category": "HR Policy",
        "doc_title": "Leave Policy",
        "provenance": "Leave Policy - page 2",
    },
)
document_3 = Document(
    id="3",
    page_content=(
        "Employees with over 6 months tenure are eligible for 20 paid vacation days "
        "per year."
    ),
    metadata={
        "category": "Benefits Policy",
        "doc_title": "Benefits Guide 2025",
        "provenance": "Benefits Policy - page 1",
    },
)

documents = [document_1, document_2, document_3]
vector_store.add_documents(documents=documents)


# Define tool
async def retrieval_tool(
    query: str, category: Literal["HR Policy", "Benefits Policy"]
) -> list[dict]:
    """Access my knowledge base."""

    def _filter_function(doc: Document) -> bool:
        return doc.metadata.get("category") == category

    results = vector_store.similarity_search(
        query=query, k=2, filter=_filter_function
    )

    return [
        {
            "type": "search_result",
            "title": doc.metadata["doc_title"],
            "source": doc.metadata["provenance"],
            "citations": {"enabled": True},
            "content": [{"type": "text", "text": doc.page_content}],
        }
        for doc in results
    ]



# Create agent
model = init_chat_model("claude-haiku-4-5-20251001")

checkpointer = InMemorySaver()
agent = create_agent(model, [retrieval_tool], checkpointer=checkpointer)


# Invoke on a query
config = {"configurable": {"thread_id": "session_1"}}

input_message = {
    "role": "user",
    "content": "How do I request vacation days?",
}
async for step in agent.astream(
    {"messages": [input_message]},
    config,
    stream_mode="values",
):
    step["messages"][-1].pretty_print()

与文本分割器一起使用

Anthropic 还允许您使用自定义文档类型指定自己的分割。LangChain 文本分割器可用于生成有意义的分割。请参阅下面的示例,其中我们分割 LangChain README.md(一个 markdown 文档)并将其作为上下文传递给 Claude: 此示例需要安装 langchain-text-splitters
pip install langchain-text-splitters
import requests
from langchain_anthropic import ChatAnthropic
from langchain_text_splitters import MarkdownTextSplitter


def format_to_anthropic_documents(documents: list[str]):
    return {
        "type": "document",
        "source": {
            "type": "content",
            "content": [{"type": "text", "text": document} for document in documents],
        },
        "citations": {"enabled": True},
    }


# Pull readme
get_response = requests.get(
    "https://raw.githubusercontent.com/langchain-ai/langchain/master/README.md"
)
readme = get_response.text

# Split into chunks
splitter = MarkdownTextSplitter(
    chunk_overlap=0,
    chunk_size=50,
)
documents = splitter.split_text(readme)

# Construct message
message = {
    "role": "user",
    "content": [
        format_to_anthropic_documents(documents),
        {"type": "text", "text": "Give me a link to LangChain's tutorials."},
    ],
}

# Query model
model = ChatAnthropic(model="claude-haiku-4-5-20251001")
response = model.invoke([message])

提示缓存

Anthropic 支持缓存提示的元素,包括消息、工具定义、工具结果、图像和文档。这允许您重用大型文档、指令、少样本文档和其他数据,以减少延迟和成本。 有两种方法可以启用提示缓存:
  • 自动缓存:在调用时传递 cache_control。系统会自动将缓存断点应用于最后一个可缓存块,并随着对话增长将其向前移动。最适合多轮对话。
  • 显式缓存断点:将 cache_control 直接放在各个内容块上,以对缓存内容进行细粒度控制。
只有某些 Claude 模型支持提示缓存。有关详细信息,请参阅 Claude 文档

自动缓存

自动缓存需要 langchain-anthropic>=1.4.0
cache_control 作为调用参数传递,以自动缓存所有内容,直到并包括最后一个可缓存块。在具有相同前缀的后续请求中,缓存内容会自动重用。缓存断点会随着对话增长而向前移动,因此您无需管理单个 cache_control 标记。
from langchain_anthropic import ChatAnthropic
import requests

model = ChatAnthropic(model="claude-sonnet-4-5")

# Pull LangChain readme
get_response = requests.get(
    "https://raw.githubusercontent.com/langchain-ai/langchain/master/README.md"
)
readme = get_response.text

messages = [
    {
        "role": "system",
        "content": [
            {
                "type": "text",
                "text": "You are a technology expert.",
            },
            {
                "type": "text",
                "text": f"{readme}"
            },
        ],
    },
    {
        "role": "user",
        "content": "What's LangChain, according to its README?",
    },
]

response = model.invoke(
    messages,
    cache_control={"type": "ephemeral"},
)

usage = response.usage_metadata["input_token_details"]
print(f"Usage:\n{usage}")

对于 1 小时缓存,请指定 ttl 字段:
response = model.invoke(
    messages,
    cache_control={"type": "ephemeral", "ttl": "1h"},
)

显式缓存断点

为了进行细粒度控制,请使用 cache_control 标记各个内容块。当您需要缓存以不同频率更改的不同部分时,这非常有用。

消息

import requests
from langchain_anthropic import ChatAnthropic


model = ChatAnthropic(model="claude-sonnet-4-5")

# Pull LangChain readme
get_response = requests.get(
    "https://raw.githubusercontent.com/langchain-ai/langchain/master/README.md"
)
readme = get_response.text

messages = [
    {
        "role": "system",
        "content": [
            {
                "type": "text",
                "text": "You are a technology expert.",
            },
            {
                "type": "text",
                "text": f"{readme}",
                "cache_control": {"type": "ephemeral"},
            },
        ],
    },
    {
        "role": "user",
        "content": "What's LangChain, according to its README?",
    },
]

response_1 = model.invoke(messages)
response_2 = model.invoke(messages)

usage_1 = response_1.usage_metadata["input_token_details"]
usage_2 = response_2.usage_metadata["input_token_details"]

print(f"First invocation:\n{usage_1}")
print(f"\nSecond:\n{usage_2}")
First invocation:
{'cache_read': 0, 'cache_creation': 0, 'ephemeral_5m_input_tokens': 1569, 'ephemeral_1h_input_tokens': 0}

Second:
{'cache_read': 1569, 'cache_creation': 0, 'ephemeral_5m_input_tokens': 0, 'ephemeral_1h_input_tokens': 0}
1 小时缓存缓存生存时间默认为 5 分钟。要进行更长时间的缓存,请在 cache_control 字段中指定 "ttl": "1h"。1 小时缓存写入的成本是基本输入令牌价格的 2 倍(而 5 分钟是 1.25 倍)。
model = ChatAnthropic(model="claude-sonnet-4-6")

messages = [
    {
        "role": "user",
        "content": [
            {
                "type": "text",
                "text": f"{long_text}",
                "cache_control": {"type": "ephemeral", "ttl": "1h"},
            },
        ],
    }
]
缓存的令牌计数详细信息将包含在响应的 usage_metadataInputTokenDetails 上:
response = model.invoke(messages)
response.usage_metadata
{
    "input_tokens": 1500,
    "output_tokens": 200,
    "total_tokens": 1700,
    "input_token_details": {
        "cache_read": 0,
        "cache_creation": 1000,
        "ephemeral_1h_input_tokens": 750,
        "ephemeral_5m_input_tokens": 250,
    }
}

缓存工具

import requests

from langchain_anthropic import ChatAnthropic
from langchain.tools import tool


# For demonstration purposes, we artificially expand the
# tool description using the LangChain README text.
get_response = requests.get(
    "https://raw.githubusercontent.com/langchain-ai/langchain/master/README.md"
)
readme = get_response.text
description = (
    "Get the weather at a location. "
    f"By the way, check out this readme: {readme}"
)


@tool(description=description, extras={"cache_control": {"type": "ephemeral"}})
def get_weather(location: str) -> str:
    return "It's sunny."


model = ChatAnthropic(model="claude-sonnet-4-6")
model_with_tools = model.bind_tools([get_weather])
query = "What's the weather in San Francisco?"

response_1 = model_with_tools.invoke(query)
response_2 = model_with_tools.invoke(query)

usage_1 = response_1.usage_metadata["input_token_details"]
usage_2 = response_2.usage_metadata["input_token_details"]

print(f"First invocation:\n{usage_1}")
print(f"\nSecond:\n{usage_2}")
First invocation:
{'cache_read': 0, 'cache_creation': 1809}

Second:
{'cache_read': 1809, 'cache_creation': 0}

对话应用程序中的增量缓存

提示缓存可用于多轮对话,以维护早期消息的上下文,而无需冗余处理。 我们可以通过用 cache_control 标记最终消息来启用增量缓存。Claude 将自动使用先前缓存的最长前缀进行后续消息。 下面,我们实现一个简单的聊天机器人,该机器人结合了此功能。我们遵循 LangChain 聊天机器人教程,但添加了一个自定义归约器,该归约器自动用 cache_control 标记每个用户消息的最后一个内容块:

令牌计数

您可以使用 get_num_tokens_from_messages() 在将消息发送到模型之前计算消息中的令牌。这使用 Anthropic 的官方令牌计数 API
from langchain_anthropic import ChatAnthropic
from langchain.messages import HumanMessage, SystemMessage

model = ChatAnthropic(model="claude-sonnet-4-6")

messages = [
    SystemMessage(content="You are a scientist"),
    HumanMessage(content="Hello, Claude"),
]

token_count = model.get_num_tokens_from_messages(messages)
print(token_count)
14
您也可以在使用工具时计算令牌:
from langchain.tools import tool

@tool(parse_docstring=True)
def get_weather(location: str) -> str:
    """Get the current weather in a given location

    Args:
        location: The city and state, e.g. San Francisco, CA
    """
    return "Sunny"

messages = [
    HumanMessage(content="What's the weather like in San Francisco?"),
]

token_count = model.get_num_tokens_from_messages(messages, tools=[get_weather])
print(token_count)
586

上下文管理

Anthropic 支持上下文管理功能,可自动管理模型的上下文窗口以优化性能和成本。 有关更多详细信息和配置选项,请参阅 Claude 文档

清除工具使用

清除上下文中的工具结果以减少令牌使用,同时保留对话流程。
上下文管理自 langchain-anthropic>=0.3.21 起受支持您必须指定 context-management-2025-06-27 beta 标头才能将上下文管理应用于您的模型调用。
from langchain_anthropic import ChatAnthropic

model = ChatAnthropic(
    model="claude-sonnet-4-6",
    betas=["context-management-2025-06-27"],
    context_management={"edits": [{"type": "clear_tool_uses_20250919"}]},
)
model_with_tools = model.bind_tools([{"type": "web_search_20250305", "name": "web_search"}])
response = model_with_tools.invoke("Search for recent developments in AI")

自动压缩

Claude Opus 4.6 支持自动服务器端压缩,当上下文窗口接近其限制时,它会智能地压缩对话历史记录。这允许进行更长的对话,而无需手动管理上下文。
自动压缩要求:
  • Claude Opus 4.6
  • langchain-anthropic>=1.3.0
  • compact-2026-01-12 beta 标头
from langchain_anthropic import ChatAnthropic

model = ChatAnthropic(
    model="claude-opus-4-6",
    betas=["compact-2026-01-12"],
    max_tokens=4096,
    context_management={
        "edits": [
            {
                "type": "compact_20260112",
                "trigger": {"type": "input_tokens", "value": 50000},
            }
        ]
    },
)
有关触发器配置的详细信息,请参阅 Anthropic 的文档。 当压缩事件触发时,ChatAnthropic 将返回表示提示状态的压缩块。这些应保留在多轮应用程序中传递回模型的消息历史中。

结构化输出

结构化输出需要 langchain-anthropic>=1.1.0。有关支持的模型,请参阅 Claude 文档
Anthropic 支持原生结构化输出功能,保证其响应遵循给定模式。 您可以在单个模型调用中访问此功能,也可以通过指定 LangChain 智能体响应格式来访问。请参阅下面的示例。
使用 with_structured_output 方法生成结构化模型响应。指定 method="json_schema" 以启用 Anthropic 的原生结构化输出功能;否则该方法默认使用函数调用。
from langchain_anthropic import ChatAnthropic
from pydantic import BaseModel, Field

model = ChatAnthropic(model="claude-sonnet-4-6")

class Movie(BaseModel):
    """A movie with details."""
    title: str = Field(description="The title of the movie")
    year: int = Field(description="The year the movie was released")
    director: str = Field(description="The director of the movie")
    rating: float = Field(description="The movie's rating out of 10")

model_with_structure = model.with_structured_output(Movie, method="json_schema")
response = model_with_structure.invoke("Provide details about the movie Inception")
response
Movie(title='Inception', year=2010, director='Christopher Nolan', rating=8.8)
使用 ProviderStrategy 指定 response_format,以在生成最终响应时启用 Anthropic 的结构化输出功能。
from langchain.agents import create_agent
from langchain.agents.structured_output import ProviderStrategy
from pydantic import BaseModel

class Weather(BaseModel):
    temperature: float
    condition: str

def weather_tool(location: str) -> str:
    """Get the weather at a location."""
    return "Sunny and 75 degrees F."

agent = create_agent(
    model="anthropic:claude-sonnet-4-5",
    tools=[weather_tool],
    response_format=ProviderStrategy(Weather),
)

result = agent.invoke({
    "messages": [{"role": "user", "content": "What's the weather in SF?"}]
})

result["structured_response"]
Weather(temperature=75.0, condition='Sunny')

内置工具

Anthropic 支持各种内置客户端和服务器端工具 服务器端工具(例如Web 搜索)被传递给模型并由 Anthropic 执行。客户端工具(例如bash 工具)要求您在应用程序中实现回调执行逻辑并将结果返回给模型。 无论哪种情况,您都可以通过使用模型实例上的 bind_tools 使工具可供聊天模型使用。 重要的是,客户端工具需要您实现执行逻辑。有关示例,请参阅下面的相关部分。
中间件 vs 工具对于客户端工具(例如 bash文本编辑器内存),您可以选择使用中间件,它提供生产就绪的实现,包含内置执行、状态管理和安全策略。当您想要一个交钥匙解决方案时,请使用中间件;当您需要自定义执行逻辑或想要直接使用 bind_tools 时,请使用下面记录的工具。
Beta 工具如果将 beta 工具绑定到您的聊天模型,LangChain 将自动为您添加所需的 beta 标头。

Bash 工具

Claude 支持客户端bash 工具,允许它在持久的 bash 会话中执行 shell 命令。这使得系统操作、脚本执行和命令行自动化成为可能。
重要:您必须提供执行环境LangChain 处理 API 集成(发送/接收工具调用),但您负责
  • 设置沙盒计算环境(Docker、VM 等)
  • 实现命令执行和输出捕获
  • 在智能体循环中将结果传递回 Claude
有关实现指导,请参阅 Claude bash 工具文档
要求:
  • Claude 4 模型或 Claude Sonnet 3.7
import subprocess

from anthropic.types.beta import BetaToolBash20250124Param  
from langchain_anthropic import ChatAnthropic
from langchain.messages import HumanMessage, ToolMessage
from langchain.tools import tool

tool_spec = BetaToolBash20250124Param(
    name="bash",
    type="bash_20250124",
)


@tool(extras={"provider_tool_definition": tool_spec})
def bash(*, command: str, restart: bool = False, **kw):
    """Execute a bash command."""
    if restart:
        return "Bash session restarted"
    try:
        result = subprocess.run(
            command,
            shell=True,
            capture_output=True,
            text=True,
            timeout=30,
        )
        return result.stdout + result.stderr
    except Exception as e:
        return f"Error: {e}"


model = ChatAnthropic(model="claude-sonnet-4-6")
model_with_bash = model.bind_tools([bash])

# Initial request
messages = [HumanMessage("List all files in the current directory")]
response = model_with_bash.invoke(messages)
print(response.content_blocks)

# Tool execution loop
while response.tool_calls:
    # Execute each tool call
    tool_messages = []
    for tool_call in response.tool_calls:
        result = bash.invoke(tool_call)
        tool_messages.append(result)

    # Continue conversation with tool results
    messages = [*messages, response, *tool_messages]
    response = model_with_bash.invoke(messages)
    print(response.content_blocks)
bash 工具支持两个参数:
  • command (required): 要执行的 bash 命令
  • restart (optional): 设置为 true 以重新启动 bash 会话
对于“开箱即用”的实现,请考虑使用 ClaudeBashToolMiddleware,它提供持久会话、Docker 隔离、输出编辑以及启动/关闭命令。

代码执行

Claude 可以使用服务器端代码执行工具在沙盒环境中执行代码。
Anthropic 的 2025-08-25 代码执行工具自 langchain-anthropic>=1.0.3 起受支持。旧版 2025-05-22 工具自 langchain-anthropic>=0.3.14 起受支持。
代码沙盒没有互联网访问权限,因此您只能使用环境中预装的软件包。有关更多信息,请参阅 Claude 文档
from anthropic.types.beta import BetaCodeExecutionTool20250825Param 
from langchain_anthropic import ChatAnthropic

model = ChatAnthropic(
    model="claude-sonnet-4-6",
    # (Optional) Enable the param below to automatically
    # pass back in container IDs from previous response
    reuse_last_container=True,
)

code_tool = BetaCodeExecutionTool20250825Param(
    name="code_execution",
    type="code_execution_20250825",
)
model_with_tools = model.bind_tools([code_tool])

response = model_with_tools.invoke(
    "Calculate the mean and standard deviation of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]"
)
使用 Files API,Claude 可以编写代码来访问文件以进行数据分析和其他目的。请参阅下面的示例:
import anthropic
from anthropic.types.beta import BetaCodeExecutionTool20250825Param 
from langchain_anthropic import ChatAnthropic


client = anthropic.Anthropic()
file = client.beta.files.upload(
    file=open("/path/to/sample_data.csv", "rb")
)
file_id = file.id


# Run inference
model = ChatAnthropic(
    model="claude-sonnet-4-6",
)

code_tool = BetaCodeExecutionTool20250825Param(
    name="code_execution",
    type="code_execution_20250825",
)
model_with_tools = model.bind_tools([code_tool])

input_message = {
    "role": "user",
    "content": [
        {
            "type": "text",
            "text": "Please plot these data and tell me what you see.",
        },
        {
            "type": "container_upload",
            "file_id": file_id,
        },
    ]
}
response = model_with_tools.invoke([input_message])
请注意,Claude 可能会在其代码执行过程中生成文件。您可以使用 Files API 访问这些文件:
# Take all file outputs for demonstration purposes
file_ids = []
for block in response.content:
    if block["type"] == "bash_code_execution_tool_result":
        file_ids.extend(
            content["file_id"]
            for content in block.get("content", {}).get("content", [])
            if "file_id" in content
        )

for i, file_id in enumerate(file_ids):
    file_content = client.beta.files.download(file_id)
    file_content.write_to_file(f"/path/to/file_{i}.png")
可用工具版本:
  • code_execution_20250522 (legacy)
  • code_execution_20250825 (recommended)

计算机使用

Claude 支持客户端计算机使用功能,允许它通过屏幕截图、鼠标控制和键盘输入与桌面环境交互。
重要:您必须提供执行环境LangChain 处理 API 集成(发送/接收工具调用),但您负责
  • 设置沙盒计算环境(Linux VM、Docker 容器等)
  • 实现虚拟显示(例如 Xvfb)
  • 执行 Claude 的工具调用(屏幕截图、鼠标点击、键盘输入)
  • 在智能体循环中将结果传递回 Claude
Anthropic 提供了一个参考实现来帮助您入门。
要求:
  • Claude Opus 4.5、Claude 4 或 Claude Sonnet 3.7
import base64
from typing import Literal

from anthropic.types.beta import BetaToolComputerUse20250124Param 
from langchain_anthropic import ChatAnthropic
from langchain.messages import HumanMessage, ToolMessage
from langchain.tools import tool

DISPLAY_WIDTH = 1024
DISPLAY_HEIGHT = 768

tool_spec = BetaToolComputerUse20250124Param(
    name="computer",
    type="computer_20250124",
    display_width_px=DISPLAY_WIDTH,
    display_height_px=DISPLAY_HEIGHT,
    display_number=1,
)

@tool(extras={"provider_tool_definition": tool_spec})
def computer(
    *,
    action: Literal[
        "key", "type", "mouse_move", "left_click", "left_click_drag",
        "right_click", "middle_click", "double_click", "screenshot",
        "cursor_position", "scroll"
    ],
    coordinate: list[int] | None = None,
    text: str | None = None,
    **kw
):
    """Control the computer display."""
    if action == "screenshot":
        # Take screenshot and return base64-encoded image
        # Implementation depends on your display setup (e.g., Xvfb, pyautogui)
        return {"type": "image", "data": "base64_screenshot_data..."}
    elif action == "left_click" and coordinate:
        # Execute click at coordinate
        return f"Clicked at {coordinate}"
    elif action == "type" and text:
        # Type text
        return f"Typed: {text}"
    # ... implement other actions
    return f"Executed {action}"

model = ChatAnthropic(model="claude-sonnet-4-6")
model_with_computer = model.bind_tools([computer])

# Initial request
messages = [HumanMessage("Take a screenshot to see what's on the screen")]
response = model_with_computer.invoke(messages)
print(response.content_blocks)

# Tool execution loop
while response.tool_calls:
    tool_messages = []
    for tool_call in response.tool_calls:
        result = computer.invoke(tool_call)
        tool_messages.append(
            ToolMessage(content=str(result), tool_call_id=tool_call["id"])
        )

    messages = [*messages, response, *tool_messages]
    response = model_with_computer.invoke(messages)
    print(response.content_blocks)
可用工具版本:
  • computer_20250124 (for Claude 4 and Claude Sonnet 3.7)
  • computer_20251124 (for Claude Opus 4.5)

远程 MCP

Claude 可以使用服务器端 MCP 连接器工具 进行模型生成的远程 MCP 服务器调用。
远程 MCP 自 langchain-anthropic>=0.3.14 起受支持
from anthropic.types.beta import BetaMCPToolsetParam 
from langchain_anthropic import ChatAnthropic

mcp_servers = [
    {
        "type": "url",
        "url": "https://docs.langchain.com/mcp",
        "name": "LangChain Docs",
    }
]

model = ChatAnthropic(
    model="claude-sonnet-4-6",
    mcp_servers=mcp_servers,
)

mcp_tool = BetaMCPToolsetParam(
    type="mcp_toolset",
    mcp_server_name="LangChain Docs",
)

response = model.invoke(
    "What are LangChain content blocks?",
    tools=[mcp_tool],
)

文本编辑器

Claude 支持客户端文本编辑器工具,可用于查看和修改本地文本文件。有关详细信息,请参阅文本编辑器工具文档
from typing import Literal

from anthropic.types.beta import BetaToolTextEditor20250728Param 
from langchain_anthropic import ChatAnthropic
from langchain.messages import HumanMessage, ToolMessage
from langchain.tools import tool

tool_spec = BetaToolTextEditor20250728Param(
    name="str_replace_based_edit_tool",
    type="text_editor_20250728",
)

# Simple in-memory file storage for demonstration
files: dict[str, str] = {
    "/workspace/primes.py": "def is_prime(n):\n    if n < 2\n        return False\n    return True"
}

@tool(extras={"provider_tool_definition": tool_spec})
def str_replace_based_edit_tool(
    *,
    command: Literal["view", "create", "str_replace", "insert", "undo_edit"],
    path: str,
    file_text: str | None = None,
    old_str: str | None = None,
    new_str: str | None = None,
    insert_line: int | None = None,
    view_range: list[int] | None = None,
    **kw
):
    """View and edit text files."""
    if command == "view":
        if path not in files:
            return f"Error: File {path} not found"
        content = files[path]
        if view_range:
            lines = content.splitlines()
            start, end = view_range[0] - 1, view_range[1]
            return "\n".join(lines[start:end])
        return content
    elif command == "create":
        files[path] = file_text or ""
        return f"Created {path}"
    elif command == "str_replace" and old_str is not None:
        if path not in files:
            return f"Error: File {path} not found"
        files[path] = files[path].replace(old_str, new_str or "", 1)
        return f"Replaced in {path}"
    # ... implement other commands
    return f"Executed {command} on {path}"

model = ChatAnthropic(model="claude-sonnet-4-6")
model_with_tools = model.bind_tools([str_replace_based_edit_tool])

# Initial request
messages = [HumanMessage("There's a syntax error in my primes.py file. Can you fix it?")]
response = model_with_tools.invoke(messages)
print(response.content_blocks)

# Tool execution loop
while response.tool_calls:
    tool_messages = []
    for tool_call in response.tool_calls:
        result = str_replace_based_edit_tool.invoke(tool_call)
        tool_messages.append(
            ToolMessage(content=result, tool_call_id=tool_call["id"])
        )

    messages = [*messages, response, *tool_messages]
    response = model_with_tools.invoke(messages)
    print(response.content_blocks)
可用工具版本:
  • text_editor_20250124 (legacy)
  • text_editor_20250728 (recommended)
对于“开箱即用”的实现,请考虑使用 StateClaudeTextEditorMiddlewareFilesystemClaudeTextEditorMiddleware,它们提供 LangGraph 状态集成或文件系统持久化、路径验证和其他功能。

Web 获取

Claude 可以使用服务器端 Web 获取工具 从指定的网页和 PDF 文档检索完整内容,并通过引用为其响应提供依据。
from anthropic.types.beta import BetaWebFetchTool20250910Param 
from langchain_anthropic import ChatAnthropic

model = ChatAnthropic(model="claude-haiku-4-5-20251001")

fetch_tool = BetaWebFetchTool20250910Param(
    name="web_fetch",
    type="web_fetch_20250910",
    max_uses=3,
)

model_with_tools = model.bind_tools([fetch_tool])

response = model_with_tools.invoke(
    "Please analyze the content at https://docs.langchain.com/"
)

Web 搜索

Claude 可以使用服务器端 Web 搜索工具 运行搜索并通过引用为其响应提供依据。
Web 搜索工具自 langchain-anthropic>=0.3.13 起受支持
from anthropic.types.beta import BetaWebSearchTool20250305Param 
from langchain_anthropic import ChatAnthropic

model = ChatAnthropic(model="claude-sonnet-4-6")

search_tool = BetaWebSearchTool20250305Param(
    name="web_search",
    type="web_search_20250305",
    max_uses=3,
)

model_with_tools = model.bind_tools([search_tool])

response = model_with_tools.invoke("How do I update a web app to TypeScript 5.5?")

内存工具

Claude 支持内存工具,用于跨对话线程的客户端存储和检索上下文。有关详细信息,请参阅内存工具文档
Anthropic 的内置内存工具自 langchain-anthropic>=0.3.21 起受支持
from typing import Literal

from anthropic.types.beta import BetaMemoryTool20250818Param  
from langchain_anthropic import ChatAnthropic
from langchain.messages import HumanMessage, ToolMessage
from langchain.tools import tool

tool_spec = BetaMemoryTool20250818Param(
    name="memory",
    type="memory_20250818",
)

# Simple in-memory storage for demonstration purposes
memory_store: dict[str, str] = {
    "/memories/interests": "User enjoys Python programming and hiking"
}


@tool(extras={"provider_tool_definition": tool_spec})
def memory(
    *,
    command: Literal["view", "create", "str_replace", "insert", "delete", "rename"],
    path: str,
    content: str | None = None,
    old_str: str | None = None,
    new_str: str | None = None,
    insert_line: int | None = None,
    new_path: str | None = None,
    **kw,
):
    """Manage persistent memory across conversations."""
    if command == "view":
        if path == "/memories":
            # List all memories
            return "\n".join(memory_store.keys()) or "No memories stored"
        return memory_store.get(path, f"No memory at {path}")
    elif command == "create":
        memory_store[path] = content or ""
        return f"Created memory at {path}"
    elif command == "str_replace" and old_str is not None:
        if path in memory_store:
            memory_store[path] = memory_store[path].replace(old_str, new_str or "", 1)
        return f"Updated {path}"
    elif command == "delete":
        memory_store.pop(path, None)
        return f"Deleted {path}"
    # ... implement other commands
    return f"Executed {command} on {path}"


model = ChatAnthropic(model="claude-sonnet-4-6")
model_with_tools = model.bind_tools([memory])

# Initial request
messages = [HumanMessage("What are my interests?")]
response = model_with_tools.invoke(messages)
print(response.content_blocks)

# Tool execution loop
while response.tool_calls:
    tool_messages = []
    for tool_call in response.tool_calls:
        result = memory.invoke(tool_call)
        tool_messages.append(ToolMessage(content=result, tool_call_id=tool_call["id"]))

    messages = [*messages, response, *tool_messages]
    response = model_with_tools.invoke(messages)
    print(response.content_blocks)
[{'type': 'text',
'text': "I'll check my memory to see what information I have about your interests."},
{'type': 'tool_call',
'name': 'memory',
'args': {'command': 'view', 'path': '/memories'},
'id': 'toolu_01XeP9sxx44rcZHFNqXSaKqh'}]
对于“开箱即用”的实现,请考虑使用 StateClaudeMemoryMiddlewareFilesystemClaudeMemoryMiddleware,它们提供 LangGraph 状态集成或文件系统持久化、自动系统提示注入和其他功能。

工具搜索

Claude 支持服务器端工具搜索功能,实现动态工具发现和加载。Claude 不是将所有工具定义预先加载到上下文窗口中,而是可以搜索您的工具目录并仅加载其需要的工具。 这在以下情况下非常有用:
  • 您的系统中有 10 多个可用工具
  • 工具定义消耗大量令牌
  • 您在大型工具集中遇到工具选择准确性问题
有两种工具搜索变体:
  • Regex (tool_search_tool_regex_20251119):Claude 构造正则表达式模式来搜索工具
  • BM25 (tool_search_tool_bm25_20251119):Claude 使用自然语言查询来搜索工具
使用 extras 参数在 LangChain 工具上指定 defer_loading
from anthropic.types.beta import BetaToolSearchToolRegex20251119Param 
from langchain_anthropic import ChatAnthropic
from langchain.tools import tool

@tool(extras={"defer_loading": True})
def get_weather(location: str, unit: str = "fahrenheit") -> str:
    """Get the current weather for a location.

    Args:
        location: City name
        unit: Temperature unit (celsius or fahrenheit)
    """
    return f"Weather in {location}: Sunny"

@tool(extras={"defer_loading": True})
def search_files(query: str) -> str:
    """Search through files in the workspace.

    Args:
        query: Search query
    """
    return f"Found files matching '{query}'"

model = ChatAnthropic(model="claude-sonnet-4-6")

tool_search = BetaToolSearchToolRegex20251119Param(
    name="tool_search_tool_regex",
    type="tool_search_tool_regex_20251119",
)

model_with_tools = model.bind_tools([
    tool_search,
    get_weather,
    search_files,
])
response = model_with_tools.invoke("What's the weather in San Francisco?")
关键点:
  • 具有 defer_loading: True 的工具仅在 Claude 通过搜索发现它们时才加载
  • 将您最常用的 3-5 个工具保持为非延迟状态以获得最佳性能
  • 两种变体都搜索工具名称、描述、参数名称和参数描述
有关工具搜索的更多详细信息,包括与 MCP 服务器和客户端实现一起使用,请参阅 Claude 文档

响应元数据

ai_msg = model.invoke(messages)
ai_msg.response_metadata
{
    "id": "msg_013xU6FHEGEq76aP4RgFerVT",
    "model": "claude-sonnet-4-6",
    "stop_reason": "end_turn",
    "stop_sequence": None,
    "usage": {"input_tokens": 25, "output_tokens": 11},
}

令牌使用元数据

ai_msg = model.invoke(messages)
ai_msg.usage_metadata
{"input_tokens": 25, "output_tokens": 11, "total_tokens": 36}
包含令牌使用情况的消息块将在流式传输期间默认包含:
stream = model.stream(messages)
full = next(stream)
for chunk in stream:
    full += chunk
full.usage_metadata
{"input_tokens": 25, "output_tokens": 11, "total_tokens": 36}
可以通过在流方法或初始化 ChatAnthropic 时设置 stream_usage=False 来禁用这些。

API 参考

有关所有功能和配置选项的详细文档,请前往 ChatAnthropic API 参考。