Skip to main content

ChatAnthropic

Anthropic 是一家人工智能安全和研究公司,也是 Claude 的创建者。

这将帮助你快速开始使用 Anthropic 的聊天模型。如需关于所有 ChatAnthropic 功能和配置的详细文档,请前往 API 参考

概览

集成详情

类别本地支持可序列化Python 支持包下载量最新包版本
ChatAnthropic@langchain/anthropicNPM - 下载量NPM - 版本

模型功能

有关如何使用特定功能的指南,请参见下表标题中的链接。

工具调用结构化输出JSON 模式图像输入音频输入视频输入逐令牌流式传输令牌使用情况对数概率

安装准备

你需要注册并获取 Anthropic API 密钥,并安装 @langchain/anthropic 集成包。

凭证信息

前往 Anthropic 网站 注册 Anthropic 账号并生成 API 密钥。完成之后,请设置 ANTHROPIC_API_KEY 环境变量:

export ANTHROPIC_API_KEY="your-api-key"

如果你想获得模型调用的自动追踪功能,也可以取消以下代码的注释并设置你的 LangSmith API 密钥:

# export LANGSMITH_TRACING="true"
# export LANGSMITH_API_KEY="your-api-key"

安装

LangChain 的 ChatAnthropic 集成位于 @langchain/anthropic 包中:

:::提示 请参阅安装集成包的一般说明部分。 :::

yarn add @langchain/anthropic @langchain/core

实例化

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

import { ChatAnthropic } from "@langchain/anthropic";

const llm = new ChatAnthropic({
model: "claude-3-haiku-20240307",
temperature: 0,
maxTokens: undefined,
maxRetries: 2,
// other params...
});

调用

const aiMsg = await llm.invoke([
[
"system",
"You are a helpful assistant that translates English to French. Translate the user sentence.",
],
["human", "I love programming."],
]);
aiMsg;
AIMessage {
"id": "msg_013WBXXiggy6gMbAUY6NpsuU",
"content": "Voici la traduction en français :\n\nJ'adore la programmation.",
"additional_kwargs": {
"id": "msg_013WBXXiggy6gMbAUY6NpsuU",
"type": "message",
"role": "assistant",
"model": "claude-3-haiku-20240307",
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 29,
"output_tokens": 20
}
},
"response_metadata": {
"id": "msg_013WBXXiggy6gMbAUY6NpsuU",
"model": "claude-3-haiku-20240307",
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 29,
"output_tokens": 20
},
"type": "message",
"role": "assistant"
},
"tool_calls": [],
"invalid_tool_calls": [],
"usage_metadata": {
"input_tokens": 29,
"output_tokens": 20,
"total_tokens": 49
}
}
console.log(aiMsg.content);
Voici la traduction en français :

J'adore la programmation.

链式调用

我们可以像这样将模型与提示模板链式调用

import { ChatPromptTemplate } from "@langchain/core/prompts";

const prompt = ChatPromptTemplate.fromMessages([
[
"system",
"You are a helpful assistant that translates {input_language} to {output_language}.",
],
["human", "{input}"],
]);

const chain = prompt.pipe(llm);
await chain.invoke({
input_language: "English",
output_language: "German",
input: "I love programming.",
});
AIMessage {
"id": "msg_01Ca52fpd1mcGRhH4spzAWr4",
"content": "Ich liebe das Programmieren.",
"additional_kwargs": {
"id": "msg_01Ca52fpd1mcGRhH4spzAWr4",
"type": "message",
"role": "assistant",
"model": "claude-3-haiku-20240307",
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 23,
"output_tokens": 11
}
},
"response_metadata": {
"id": "msg_01Ca52fpd1mcGRhH4spzAWr4",
"model": "claude-3-haiku-20240307",
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 23,
"output_tokens": 11
},
"type": "message",
"role": "assistant"
},
"tool_calls": [],
"invalid_tool_calls": [],
"usage_metadata": {
"input_tokens": 23,
"output_tokens": 11,
"total_tokens": 34
}
}

内容块

Anthropic 模型与大多数其他模型之间的一个关键区别在于,单个 Anthropic AI 消息的内容可以是一个单独的字符串,也可以是 内容块列表。例如,当 Anthropic 模型调用工具时,该工具调用既是消息内容的一部分(同时也体现在标准化的 AIMessage.tool_calls 字段中):

import { ChatAnthropic } from "@langchain/anthropic";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { z } from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";

const calculatorSchema = z.object({
operation: z
.enum(["add", "subtract", "multiply", "divide"])
.describe("The type of operation to execute."),
number1: z.number().describe("The first number to operate on."),
number2: z.number().describe("The second number to operate on."),
});

const calculatorTool = {
name: "calculator",
description: "A simple calculator tool",
input_schema: zodToJsonSchema(calculatorSchema),
};

const toolCallingLlm = new ChatAnthropic({
model: "claude-3-haiku-20240307",
}).bindTools([calculatorTool]);

const toolPrompt = ChatPromptTemplate.fromMessages([
[
"system",
"You are a helpful assistant who always needs to use a calculator.",
],
["human", "{input}"],
]);

// Chain your prompt and model together
const toolCallChain = toolPrompt.pipe(toolCallingLlm);

await toolCallChain.invoke({
input: "What is 2 + 2?",
});
AIMessage {
"id": "msg_01DZGs9DyuashaYxJ4WWpWUP",
"content": [
{
"type": "text",
"text": "Here is the calculation for 2 + 2:"
},
{
"type": "tool_use",
"id": "toolu_01SQXBamkBr6K6NdHE7GWwF8",
"name": "calculator",
"input": {
"number1": 2,
"number2": 2,
"operation": "add"
}
}
],
"additional_kwargs": {
"id": "msg_01DZGs9DyuashaYxJ4WWpWUP",
"type": "message",
"role": "assistant",
"model": "claude-3-haiku-20240307",
"stop_reason": "tool_use",
"stop_sequence": null,
"usage": {
"input_tokens": 449,
"output_tokens": 100
}
},
"response_metadata": {
"id": "msg_01DZGs9DyuashaYxJ4WWpWUP",
"model": "claude-3-haiku-20240307",
"stop_reason": "tool_use",
"stop_sequence": null,
"usage": {
"input_tokens": 449,
"output_tokens": 100
},
"type": "message",
"role": "assistant"
},
"tool_calls": [
{
"name": "calculator",
"args": {
"number1": 2,
"number2": 2,
"operation": "add"
},
"id": "toolu_01SQXBamkBr6K6NdHE7GWwF8",
"type": "tool_call"
}
],
"invalid_tool_calls": [],
"usage_metadata": {
"input_tokens": 449,
"output_tokens": 100,
"total_tokens": 549
}
}

自定义请求头

你可以通过如下方式在请求中传递自定义请求头:

import { ChatAnthropic } from "@langchain/anthropic";

const llmWithCustomHeaders = new ChatAnthropic({
model: "claude-3-sonnet-20240229",
maxTokens: 1024,
clientOptions: {
defaultHeaders: {
"X-Api-Key": process.env.ANTHROPIC_API_KEY,
},
},
});

await llmWithCustomHeaders.invoke("Why is the sky blue?");
AIMessage {
"id": "msg_019z4nWpShzsrbSHTWXWQh6z",
"content": "The sky appears blue due to a phenomenon called Rayleigh scattering. Here's a brief explanation:\n\n1) Sunlight is made up of different wavelengths of visible light, including all the colors of the rainbow.\n\n2) As sunlight passes through the atmosphere, the gases (mostly nitrogen and oxygen) cause the shorter wavelengths of light, such as violet and blue, to be scattered more easily than the longer wavelengths like red and orange.\n\n3) This scattering of the shorter blue wavelengths occurs in all directions by the gas molecules in the atmosphere.\n\n4) Our eyes are more sensitive to the scattered blue light than the scattered violet light, so we perceive the sky as having a blue color.\n\n5) The scattering is more pronounced for light traveling over longer distances through the atmosphere. This is why the sky appears even darker blue when looking towards the horizon.\n\nSo in essence, the selective scattering of the shorter blue wavelengths of sunlight by the gases in the atmosphere is what causes the sky to appear blue to our eyes during the daytime.",
"additional_kwargs": {
"id": "msg_019z4nWpShzsrbSHTWXWQh6z",
"type": "message",
"role": "assistant",
"model": "claude-3-sonnet-20240229",
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 13,
"output_tokens": 236
}
},
"response_metadata": {
"id": "msg_019z4nWpShzsrbSHTWXWQh6z",
"model": "claude-3-sonnet-20240229",
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 13,
"output_tokens": 236
},
"type": "message",
"role": "assistant"
},
"tool_calls": [],
"invalid_tool_calls": [],
"usage_metadata": {
"input_tokens": 13,
"output_tokens": 236,
"total_tokens": 249
}
}

提示缓存

兼容性

此功能目前处于测试阶段。

Anthropic 支持缓存提示的部分内容,以降低需要长上下文场景的费用。您可以缓存工具,以及完整的消息和单独的区块。

在初始请求中包含一个或多个带有 "cache_control": { "type": "ephemeral" } 字段的区块或工具定义,将自动缓存提示的该部分。此初始缓存步骤将产生额外费用,但后续请求将以较低费率计费。缓存的生命周期为 5 分钟,但每次命中缓存时都会刷新此时间。

目前还存在可缓存提示的最小长度限制,具体取决于模型。您可以此处查看此信息。

当前您需要使用测试版头部信息初始化模型。以下是一个缓存系统消息部分内容的示例,该消息包含 LangChain 概念文档

let CACHED_TEXT = "...";
import { ChatAnthropic } from "@langchain/anthropic";

const modelWithCaching = new ChatAnthropic({
model: "claude-3-haiku-20240307",
clientOptions: {
defaultHeaders: {
"anthropic-beta": "prompt-caching-2024-07-31",
},
},
});

const LONG_TEXT = `You are a pirate. Always respond in pirate dialect.

Use the following as context when answering questions:

${CACHED_TEXT}`;

const messages = [
{
role: "system",
content: [
{
type: "text",
text: LONG_TEXT,
// Tell Anthropic to cache this block
cache_control: { type: "ephemeral" },
},
],
},
{
role: "user",
content: "What types of messages are supported in LangChain?",
},
];

const res = await modelWithCaching.invoke(messages);

console.log("USAGE:", res.response_metadata.usage);
USAGE: {
input_tokens: 19,
cache_creation_input_tokens: 2921,
cache_read_input_tokens: 0,
output_tokens: 355
}

我们可以看到,Anthropic 返回的原始使用情况字段中有一个名为cache_creation_input_tokens的新字段。

如果我们再次使用相同的消息,可以看到长文本的输入代币是从缓存中读取的:

const res2 = await modelWithCaching.invoke(messages);

console.log("USAGE:", res2.response_metadata.usage);
USAGE: {
input_tokens: 19,
cache_creation_input_tokens: 0,
cache_read_input_tokens: 2921,
output_tokens: 357
}

工具缓存

您还可以通过在工具定义中设置相同的 "cache_control": { "type": "ephemeral" } 来缓存工具。目前,您需要使用Anthropic 的原始工具格式绑定工具。以下是一个示例:

const SOME_LONG_DESCRIPTION = "...";

// Tool in Anthropic format
const anthropicTools = [
{
name: "get_weather",
description: SOME_LONG_DESCRIPTION,
input_schema: {
type: "object",
properties: {
location: {
type: "string",
description: "Location to get the weather for",
},
unit: {
type: "string",
description: "Temperature unit to return",
},
},
required: ["location"],
},
// Tell Anthropic to cache this tool
cache_control: { type: "ephemeral" },
},
];

const modelWithCachedTools = modelWithCaching.bindTools(anthropicTools);

await modelWithCachedTools.invoke("what is the weather in SF?");

关于提示缓存的工作原理详情,请参阅 Anthropic 的文档

自定义客户端

Anthropic 模型 可以托管在诸如 Google Vertex 等云服务上,这些服务依赖于与主 Anthropic 客户端具有相同接口的不同底层客户端。你可以通过提供一个 createClient 方法来访问这些服务,该方法返回一个已初始化的 Anthropic 客户端实例。以下是一个示例:

import { AnthropicVertex } from "@anthropic-ai/vertex-sdk";

const customClient = new AnthropicVertex();

const modelWithCustomClient = new ChatAnthropic({
modelName: "claude-3-sonnet@20240229",
maxRetries: 0,
createClient: () => customClient,
});

await modelWithCustomClient.invoke([{ role: "user", content: "Hello!" }]);

引用

Anthropic 支持 引用 功能,该功能允许 Claude 根据用户提供来源材料为其回答附加上下文信息。来源材料可以通过 文档内容块 的形式提供,用以描述完整文档,或者通过 搜索结果 的形式提供,用以描述检索系统返回的相关段落或片段。当在查询中包含 "citations": { "enabled": true } 时,Claude 可能在其响应中生成对所提供材料的直接引用。

文档示例

在此示例中,我们提供了一个 纯文本文档。在后台,Claude 会 自动将 输入文本拆分为句子,并在生成引用时使用这些句子。

import { ChatAnthropic } from "@langchain/anthropic";

const citationsModel = new ChatAnthropic({
model: "claude-3-5-haiku-latest",
});

const messagesWithCitations = [
{
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?",
},
],
},
];

const responseWithCitations = await citationsModel.invoke(
messagesWithCitations
);

console.log(JSON.stringify(responseWithCitations.content, null, 2));
[
{
"type": "text",
"text": "Based on the document, I can tell you that:\n\n- "
},
{
"type": "text",
"text": "The grass is green",
"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
}
]
},
{
"type": "text",
"text": "\n- "
},
{
"type": "text",
"text": "The sky is blue",
"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
}
]
}
]

搜索结果示例

在此示例中,我们将搜索结果作为消息内容的一部分传入。这允许 Claude 在其响应中引用您自己的检索系统中的特定段落或片段。

当您希望 Claude 引用来自特定知识集的信息,但又希望直接引入自己预先获取/缓存的内容,而不是让模型自动搜索或检索时,这种方法非常有用。

import { ChatAnthropic } from "@langchain/anthropic";

const citationsModel = new ChatAnthropic({
model: "claude-3-5-haiku-latest",
clientOptions: {
defaultHeaders: {
"anthropic-beta": "search-results-2025-06-09",
},
},
});

const messagesWithCitations = [
{
type: "user",
content: [
{
type: "search_result",
title: "History of France",
source: "https://some-uri.com",
citations: { enabled: true },
content: [
{
type: "text",
text: "The capital of France is Paris.",
},
{
type: "text",
text: "The old capital of France was Lyon.",
},
],
},
{
type: "text",
text: "What is the capital of France?",
},
],
},
];

const responseWithCitations = await citationsModel.invoke(
messagesWithCitations
);

console.log(JSON.stringify(responseWithCitations.content, null, 2));

来自工具的搜索结果

你还可以使用工具提供搜索结果,模型可以在其回答中引用这些结果。这对于 RAG(或检索增强生成)工作流程非常适用,因为 Claude 可以决定何时以及从何处检索信息。当以搜索结果的形式返回这些信息时,可以让 Claude 能够从工具返回的材料中创建引用。

以下是如何创建一个以 Anthropic 引用 API 所期望的格式返回搜索结果的工具:

import { ChatAnthropic } from "@langchain/anthropic";
import { tool } from "@langchain/core/tools";

// Create a tool that returns search results
const ragTool = tool(
() => [
{
type: "search_result",
title: "History of France",
source: "https://some-uri.com",
citations: { enabled: true },
content: [
{
type: "text",
text: "The capital of France is Paris.",
},
{
type: "text",
text: "The old capital of France was Lyon.",
},
],
},
{
type: "search_result",
title: "Geography of France",
source: "https://some-uri.com",
citations: { enabled: true },
content: [
{
type: "text",
text: "France is a country in Europe.",
},
{
type: "text",
text: "The capital of France is Paris.",
},
],
},
],
{
name: "my_rag_tool",
description: "Retrieval system that accesses my knowledge base.",
schema: z.object({
query: z.string().describe("query to search in the knowledge base"),
}),
}
);

// Create model with search results beta header
const model = new ChatAnthropic({
model: "claude-3-5-haiku-latest",
clientOptions: {
defaultHeaders: {
"anthropic-beta": "search-results-2025-06-09",
},
},
}).bindTools([ragTool]);

const result = await model.invoke([
{
role: "user",
content: "What is the capital of France?",
},
]);

console.log(JSON.stringify(result.content, null, 2));

在此处了解有关 RAG 在 LangChain 中如何工作的更多信息

在此处了解有关工具调用的更多信息

与文本拆分器一起使用

Anthropic 还允许您使用自定义文档类型指定自己的拆分方式。LangChain 的文本拆分器可用于为此生成有意义的拆分。请参见以下示例,我们将 LangChain.js 的 README(一个 Markdown 文档)进行拆分,并将其作为上下文传递给 Claude:

import { ChatAnthropic } from "@langchain/anthropic";
import { MarkdownTextSplitter } from "langchain/text_splitter";

function formatToAnthropicDocuments(documents: string[]) {
return {
type: "document",
source: {
type: "content",
content: documents.map((document) => ({ type: "text", text: document })),
},
citations: { enabled: true },
};
}

// Pull readme
const readmeResponse = await fetch(
"https://raw.githubusercontent.com/langchain-ai/langchainjs/master/README.md"
);

const readme = await readmeResponse.text();

// Split into chunks
const splitter = new MarkdownTextSplitter({
chunkOverlap: 0,
chunkSize: 50,
});
const documents = await splitter.splitText(readme);

// Construct message
const messageWithSplitDocuments = {
role: "user",
content: [
formatToAnthropicDocuments(documents),
{
type: "text",
text: "Give me a link to LangChain's tutorials. Cite your sources",
},
],
};

// Query LLM
const citationsModelWithSplits = new ChatAnthropic({
model: "claude-3-5-sonnet-latest",
});
const resWithSplits = await citationsModelWithSplits.invoke([
messageWithSplitDocuments,
]);

console.log(JSON.stringify(resWithSplits.content, null, 2));
[
{
"type": "text",
"text": "Based on the documentation, I can provide you with a link to LangChain's tutorials:\n\n"
},
{
"type": "text",
"text": "The tutorials can be found at: https://js.langchain.com/docs/tutorials/",
"citations": [
{
"type": "content_block_location",
"cited_text": "[Tutorial](https://js.langchain.com/docs/tutorials/)walkthroughs",
"document_index": 0,
"document_title": null,
"start_block_index": 191,
"end_block_index": 194
}
]
}
]

API 参考文档

如需了解 ChatAnthropic 所有功能和配置的详细文档,请访问 API 参考页面: https://api.js.langchain.com/classes/langchain_anthropic.ChatAnthropic.html


Was this page helpful?


You can also leave detailed feedback on GitHub.