ChatAnthropic 聊天模型。要了解所有 ChatAnthropic 功能和配置的详细文档,请访问 API 参考文档。
概述
集成详情
| 类 | 包 | 可序列化 | Python 支持 | 下载量 | 版本 |
|---|---|---|---|---|---|
ChatAnthropic | @langchain/anthropic | ✅ | ✅ |
模型功能
请参阅下表表头中的链接,了解如何使用特定功能的指南。设置
您需要注册并获取一个 Anthropic API 密钥,并安装@langchain/anthropic 集成包。
凭证
前往 Anthropic 官网 注册 Anthropic 并生成 API 密钥。完成后,设置ANTHROPIC_API_KEY 环境变量:
export ANTHROPIC_API_KEY="your-api-key"
# export LANGSMITH_TRACING="true"
# export LANGSMITH_API_KEY="your-api-key"
安装
LangChain 的ChatAnthropic 集成位于 @langchain/anthropic 包中:
npm install @langchain/anthropic @langchain/core
yarn add @langchain/anthropic @langchain/core
pnpm add @langchain/anthropic @langchain/core
实例化
现在我们可以实例化我们的模型对象并生成聊天补全:import { ChatAnthropic } from "@langchain/anthropic"
const llm = new ChatAnthropic({
model: "claude-haiku-4-5-20251001",
temperature: 0,
maxTokens: undefined,
maxRetries: 2,
// 其他参数...
});
调用
const aiMsg = await llm.invoke([
[
"system",
"你是一个将英语翻译成法语的有用助手。请翻译用户的句子。",
],
["human", "我爱编程。"],
])
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-haiku-4-5-20251001",
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 29,
"output_tokens": 20
}
},
"response_metadata": {
"id": "msg_013WBXXiggy6gMbAUY6NpsuU",
"model": "claude-haiku-4-5-20251001",
"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.
内容块
需要注意 Anthropic 模型与大多数其他模型的一个关键区别是,单个 AnthropicAIMessage 的内容可以是一个字符串,也可以是一个内容块列表。例如,当 Anthropic 模型 调用工具 时,工具调用是消息内容的一部分(同时也暴露在标准化的 AIMessage.tool_calls 字段中):
import { ChatAnthropic } from "@langchain/anthropic";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import * as z from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";
const calculatorSchema = z.object({
operation: z
.enum(["add", "subtract", "multiply", "divide"])
.describe("要执行的操作类型。"),
number1: z.number().describe("要操作的第一个数字。"),
number2: z.number().describe("要操作的第二个数字。"),
});
const calculatorTool = {
name: "calculator",
description: "一个简单的计算器工具",
input_schema: zodToJsonSchema(calculatorSchema),
};
const toolCallingLlm = new ChatAnthropic({
model: "claude-haiku-4-5-20251001",
}).bindTools([calculatorTool]);
const toolPrompt = ChatPromptTemplate.fromMessages([
[
"system",
"你是一个总是需要使用计算器的有用助手。",
],
["human", "{input}"],
]);
// 将提示词和模型链接在一起
const toolCallChain = toolPrompt.pipe(toolCallingLlm);
await toolCallChain.invoke({
input: "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-haiku-4-5-20251001",
"stop_reason": "tool_use",
"stop_sequence": null,
"usage": {
"input_tokens": 449,
"output_tokens": 100
}
},
"response_metadata": {
"id": "msg_01DZGs9DyuashaYxJ4WWpWUP",
"model": "claude-haiku-4-5-20251001",
"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-sonnet-4-6",
maxTokens: 1024,
clientOptions: {
defaultHeaders: {
"X-Api-Key": process.env.ANTHROPIC_API_KEY,
},
},
});
await llmWithCustomHeaders.invoke("为什么天空是蓝色的?");
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 分钟,但每次缓存被命中时,这个时间会被刷新。要获得更长的缓存时间,请在 cache_control 字段中指定 "ttl": "1h"。
存在一个最小可缓存提示词长度,该长度因模型而异。更多信息,请参阅 提示词缓存详情。
这是一个缓存包含 LangChain 概念文档 的系统消息部分的示例:
let CACHED_TEXT = "...";
// @lc-docs-hide-cell
CACHED_TEXT = `## 组件
LangChain 为使用 LLM 进行构建时需要的各种组件提供了标准、可扩展的接口和外部集成。
有些组件由 LangChain 实现,有些组件依赖第三方集成,还有一些是两者的混合。
### 聊天模型
<span data-heading-keywords="chat model,chat models"></span>
使用一系列消息作为输入并返回聊天消息作为输出的语言模型(与使用纯文本相反)。
这些通常是较新的模型(较旧的模型通常是 \`LLMs\`,见下文)。
聊天模型支持为对话消息分配不同的角色,有助于区分来自 AI、用户和指令(如系统消息)的消息。
虽然底层模型是消息输入、消息输出,但 LangChain 的包装器也允许这些模型将字符串作为输入。
这使得它们具有与 LLMs 相同的接口(并且更易于使用)。
当传入字符串作为输入时,它将在底层转换为 \`HumanMessage\`,然后再传递给底层模型。
LangChain 不托管任何聊天模型,而是依赖第三方集成。
我们在构建 ChatModels 时有一些标准化参数:
- \`model\`: 模型的名称
聊天模型还接受其他特定于该集成的参数。
<Warning>
**一些聊天模型已经针对**工具调用**进行了微调,并为其提供了专用的 API。**
通常,此类模型在工具调用方面优于未微调的模型,推荐用于需要工具调用的用例。
请参阅 [工具调用部分](/oss/javascript/langchain/tools) 了解更多信息。
</Warning>
有关如何使用聊天模型的具体信息,请参阅 [此处的相关指南](/oss/javascript/langchain/models)。
#### 多模态
一些聊天模型是多模态的,接受图像、音频甚至视频作为输入。
这些模型仍然不太常见,这意味着模型提供商尚未在定义 API 的“最佳”方式上达成标准。
多模态输出甚至更不常见。因此,我们保持了相当轻量级的多模态抽象,并计划随着领域的成熟进一步巩固多模态 API 和交互模式。
在 LangChain 中,大多数支持多模态输入的聊天模型也接受 OpenAI 内容块格式的输入值。
到目前为止,这仅限于图像输入。对于像 Gemini 这样支持视频和其他字节输入的模型,API 也支持原生的、特定于模型的表示形式。
有关如何使用多模态模型的具体信息,请参阅 [此处的相关指南](/oss/javascript/how-to/#multimodal)。
### LLMs
<span data-heading-keywords="llm,llms"></span>
<Warning>
**纯文本输入/输出的 LLMs 往往是较旧或较低级的。许多流行的模型最好用作 [聊天补全模型](/oss/javascript/langchain/models),**
即使是用于非聊天的用例。
您可能正在寻找 [上面的部分](/oss/javascript/langchain/models)。
</Warning>
以字符串作为输入并返回字符串的语言模型。
这些通常是较旧的模型(较新的模型通常是 [聊天模型](/oss/javascript/langchain/models),见上文)。
虽然底层模型是字符串输入、字符串输出,但 LangChain 的包装器也允许这些模型将消息作为输入。
这使得它们具有与 [聊天模型](/oss/javascript/langchain/models) 相同的接口。
当传入消息作为输入时,它们将在底层格式化为字符串,然后再传递给底层模型。
LangChain 不托管任何 LLMs,而是依赖第三方集成。
有关如何使用 LLMs 的具体信息,请参阅 [此处的相关指南](/oss/javascript/langchain/models)。
### 消息类型
一些语言模型以消息数组作为输入并返回一条消息。
有几种不同类型的消息。
所有消息都具有 \`role\`、\`content\` 和 \`response_metadata\` 属性。
\`role\` 描述了是谁在说这条消息。
LangChain 为不同的角色有不同的消息类。
\`content\` 属性描述了消息的内容。
这可以是几种不同的东西:
- 一个字符串(大多数模型处理这种类型的内容)
- 一个对象列表(用于多模态输入,其中对象包含有关该输入类型和输入位置的信息)
#### HumanMessage
这代表来自用户的消息。
#### AIMessage
这代表来自模型的消息。除了 \`content\` 属性外,这些消息还有:
**\`response_metadata\`**
\`response_metadata` 属性包含有关响应的附加元数据。这里的数据通常是每个模型提供者特定的。
这里可能会存储像对数概率和 token 使用量这样的信息。
**\`tool_calls\`**
这些代表了语言模型调用工具的决策。它们作为 \`AIMessage\` 输出的一部分包含在内。
它们可以通过 \`.tool_calls\` 属性从那里访问。
此属性返回一个 \`ToolCall\` 列表。\`ToolCall\` 是一个具有以下参数的对象:
- \`name\`: 应该调用的工具的名称。
- \`args\`: 该工具的参数。
- \`id\`: 该工具调用的 ID。
#### SystemMessage
这代表一条系统消息,告诉模型如何表现。并非每个模型提供者都支持此功能。
#### ToolMessage
这代表工具调用的结果。除了 \`role\` 和 \`content\` 外,此消息还有:
- 一个 \`tool_call_id\` 字段,用于传递被调用来产生此结果的工具的调用 ID。
- 一个 \`artifact\` 字段,可用于传递工具执行产生的任意工件,这些工件对于跟踪很有用,但不应发送给模型。
#### (遗留)FunctionMessage
这是一种遗留消息类型,对应于 OpenAI 的遗留函数调用 API。应使用 \`ToolMessage\` 来对应更新的工具调用 API。
这代表函数调用的结果。除了 \`role\` 和 \`content\` 外,此消息还有一个 \`name\` 参数,用于传递被调用来产生此结果的函数的名称。
### 提示词模板
<span data-heading-keywords="prompt,prompttemplate,chatprompttemplate"></span>
提示词模板有助于将用户输入和参数转换为语言模型的指令。
这可用于指导模型的响应,帮助它理解上下文并生成相关且连贯的基于语言的输出。
提示词模板接受一个对象作为输入,其中每个键代表提示词模板中要填充的一个变量。
提示词模板输出一个 PromptValue。这个 PromptValue 可以传递给 LLM 或 ChatModel,也可以转换为字符串或消息数组。
存在这个 PromptValue 是为了方便在字符串和消息之间切换。
有几种不同类型的提示词模板:
#### 字符串 PromptTemplates
这些提示词模板用于格式化单个字符串,通常用于更简单的输入。
例如,构造和使用 PromptTemplate 的常见方式如下:
\`\`\`typescript
import { PromptTemplate } from "@langchain/core/prompts";
const promptTemplate = PromptTemplate.fromTemplate(
"给我讲一个关于 {topic} 的笑话"
);
await promptTemplate.invoke({ topic: "猫" });
\`\`\`
#### ChatPromptTemplates
这些提示词模板用于格式化一个消息数组。这些“模板”本身由一个模板数组组成。
例如,构造和使用 ChatPromptTemplate 的常见方式如下:
\`\`\`typescript
import { ChatPromptTemplate } from "@langchain/core/prompts";
const promptTemplate = ChatPromptTemplate.fromMessages([
["system", "你是一个有用的助手"],
["user", "给我讲一个关于 {topic} 的笑话"],
]);
await promptTemplate.invoke({ topic: "猫" });
\`\`\`
在上面的例子中,这个 ChatPromptTemplate 在被调用时会构造两条消息。
第一条是系统消息,没有需要格式化的变量。
第二条是 HumanMessage,将由用户传入的 \`topic\` 变量格式化。
#### MessagesPlaceholder
<span data-heading-keywords="messagesplaceholder"></span>
这个提示词模板负责在特定位置添加一个消息数组。
在上面的 ChatPromptTemplate 中,我们看到了如何格式化两条消息,每条都是一个字符串。
但如果我们希望用户传入一个消息数组,并将其插入到特定位置呢?
这就是您使用 MessagesPlaceholder 的方式。
\`\`\`typescript
import {
ChatPromptTemplate,
MessagesPlaceholder,
} from "@langchain/core/prompts";
import { HumanMessage } from "@langchain/core/messages";
const promptTemplate = ChatPromptTemplate.fromMessages([
["system", "你是一个有用的助手"],
new MessagesPlaceholder("msgs"),
]);
promptTemplate.invoke({ msgs: [new HumanMessage({ content: "你好!" })] });
\`\`\`
这将生成一个包含两条消息的数组,第一条是系统消息,第二条是我们传入的 HumanMessage。
如果我们传入了 5 条消息,那么总共将生成 6 条消息(系统消息加上传入的 5 条消息)。
这对于让消息数组插入到特定位置非常有用。
不使用 \`MessagesPlaceholder\` 类显式实现同样功能的另一种方式是:
\`\`\`typescript
const promptTemplate = ChatPromptTemplate.fromMessages([
["system", "你是一个有用的助手"],
["placeholder", "{msgs}"], // <-- 这是改变的部分
]);
\`\`\`
有关如何使用提示词模板的具体信息,请参阅 [此处的相关指南](/oss/javascript/how-to/#prompt-templates)。
### 示例选择器
实现更好性能的一种常见提示技术是将示例作为提示的一部分包含进来。
这为语言模型提供了它应该如何表现的具体示例。
有时这些示例是硬编码在提示中的,但对于更高级的情况,可能需要动态选择它们。
示例选择器是负责选择并格式化示例到提示中的类。
有关如何使用示例选择器的具体信息,请参阅 [此处的相关指南](/oss/javascript/how-to/#example-selectors)。
### 输出解析器
<span data-heading-keywords="output parser"></span>
<Note>
**此处的信息指的是那些接收模型文本输出并尝试将其解析为更结构化表示的解析器。**
越来越多的模型支持函数(或工具)调用,这可以自动处理此问题。
建议使用函数/工具调用而非输出解析。
请参阅 [LangChain 工具文档](/oss/javascript/langchain/tools)。
</Note>
负责获取模型的输出并将其转换为更适合下游任务的格式。
当您使用 LLMs 生成结构化数据或规范化来自聊天模型和 LLMs 的输出时非常有用。
输出解析器必须实现两个主要方法:
- “获取格式说明”:返回一个字符串的方法,该字符串包含关于语言模型输出应如何格式化的说明。
- “解析”:接收一个字符串(假定为语言模型的响应)并将其解析为某种结构的方法。
然后还有一个可选的方法:
- “带提示解析”:接收一个字符串(假定为语言模型的响应)和一个提示(假定为生成该响应的提示)并将其解析为某种结构的方法。提示主要是为了在 OutputParser 想要重试或以某种方式修复输出时提供信息,需要来自提示的信息才能这样做。
输出解析器接受一个字符串或 \`BaseMessage\` 作为输入,并且可以返回任意类型。
LangChain 有许多不同类型的输出解析器。这是 LangChain 支持的输出解析器列表。下表包含各种信息:
**名称**: 输出解析器的名称
**支持流式传输**: 输出解析器是否支持流式传输。
**输入类型**: 预期的输入类型。大多数输出解析器对字符串和消息都有效,但有些(如 OpenAI Functions)需要具有特定参数的消息。
**输出类型**: 解析器返回的对象的输出类型。
**描述**: 我们对该输出解析器及其使用时机的评论。
当前日期为 ${new Date().toISOString()}`;
// 用于隐藏输出的空操作语句
void 0;
import { ChatAnthropic } from "@langchain/anthropic";
const modelWithCaching = new ChatAnthropic({
model: "claude-sonnet-4-6",
});
const LONG_TEXT = `你是一个海盗。始终用海盗方言回答。
回答问题时使用以下内容作为上下文:
${CACHED_TEXT}`;
const messages = [
{
role: "system",
content: [
{
type: "text",
text: LONG_TEXT,
// 告诉 Anthropic 缓存这个块
cache_control: { type: "ephemeral" },
},
],
},
{
role: "user",
content: "LangChain 支持哪些类型的消息?",
},
];
const res = await modelWithCaching.invoke(messages);
console.log("USAGE:", res.response_metadata.usage);
USAGE: {
input_tokens: 18,
cache_creation_input_tokens: 2960,
cache_read_input_tokens: 0,
cache_creation: { ephemeral_5m_input_tokens: 2960, ephemeral_1h_input_tokens: 0 },
output_tokens: 433,
service_tier: 'standard',
inference_geo: 'global'
}
cache_creation_input_tokens 的新字段。
如果我们再次使用相同的消息,我们可以看到长文本的输入 token 是从缓存中读取的:
const res2 = await modelWithCaching.invoke(messages);
console.log("USAGE:", res2.response_metadata.usage);
USAGE: {
input_tokens: 18,
cache_creation_input_tokens: 0,
cache_read_input_tokens: 2960,
cache_creation: { ephemeral_5m_input_tokens: 0, ephemeral_1h_input_tokens: 0 },
output_tokens: 393,
service_tier: 'standard',
inference_geo: 'global'
}
工具缓存
您还可以通过在工具定义中设置相同的"cache_control": { "type": "ephemeral" } 来缓存工具。目前这要求您以 Anthropic 的原始工具格式 绑定工具。这是一个例子:
const SOME_LONG_DESCRIPTION = "...";
// Anthropic 格式的工具
const anthropicTools = [{
name: "get_weather",
description: SOME_LONG_DESCRIPTION,
input_schema: {
type: "object",
properties: {
location: {
type: "string",
description: "要获取天气的位置",
},
unit: {
type: "string",
description: "要返回的温度单位",
},
},
required: ["location"],
},
// 告诉 Anthropic 缓存这个工具
cache_control: { type: "ephemeral" },
}]
const modelWithCachedTools = modelWithCaching.bindTools(anthropicTools);
await modelWithCachedTools.invoke("旧金山的天气怎么样?");
自定义客户端
Anthropic 模型 可能托管在 Google Vertex 等云服务上,这些服务依赖于具有与主 Anthropic 客户端相同接口的不同底层客户端。您可以通过提供一个createClient 方法来访问这些服务,该方法返回一个初始化的 Anthropic 客户端实例。这是一个例子:
import { AnthropicVertex } from "@anthropic-ai/vertex-sdk";
const customClient = new AnthropicVertex();
const modelWithCustomClient = new ChatAnthropic({
modelName: "claude-sonnet-4-6",
maxRetries: 0,
createClient: () => customClient,
});
await modelWithCustomClient.invoke([{ role: "user", content: "你好!" }]);
引用
Anthropic 支持 引用 功能,允许 Claude 根据用户提供的来源材料将其上下文附加到其答案中。这些来源材料可以作为 文档内容块(描述完整文档)或作为 搜索结果(描述从检索系统返回的相关段落或片段)提供。当在查询中包含"citations": { "enabled": true } 时,Claude 可能在其响应中生成对所提供材料的直接引用。
文档示例
在此示例中,我们传递一个 纯文本文档。在后台,Claude 自动分块 输入文本为句子,在生成引用时使用这些句子。import { ChatAnthropic } from "@langchain/anthropic";
const citationsModel = new ChatAnthropic({
model: "claude-haiku-4-5-20251001",
});
const messagesWithCitations = [
{
role: "user",
content: [
{
type: "document",
source: {
type: "text",
media_type: "text/plain",
data: "草是绿色的。天空是蓝色的。",
},
title: "我的文档",
context: "这是一个可信的文档。",
citations: {
enabled: true,
},
},
{
type: "text",
text: "草和天空是什么颜色?",
},
],
}
];
const responseWithCitations = await citationsModel.invoke(messagesWithCitations);
console.log(JSON.stringify(responseWithCitations.content, null, 2));
[
{
"type": "text",
"text": "根据文档,我可以告诉你:\n\n- "
},
{
"type": "text",
"text": "草是绿色的",
"citations": [
{
"type": "char_location",
"cited_text": "草是绿色的。 ",
"document_index": 0,
"document_title": "我的文档",
"start_char_index": 0,
"end_char_index": 20
}
]
},
{
"type": "text",
"text": "\n- "
},
{
"type": "text",
"text": "天空是蓝色的",
"citations": [
{
"type": "char_location",
"cited_text": "天空是蓝色的。",
"document_index": 0,
"document_title": "我的文档",
"start_char_index": 20,
"end_char_index": 36
}
]
}
]
搜索结果示例
在此示例中,我们将 搜索结果 作为消息内容的一部分传入。这允许 Claude 在其响应中引用您自己检索系统中的特定段落或片段。 当您希望 Claude 从特定知识集中引用信息,但您希望直接提供自己预取/缓存的内容,而不是让模型自动搜索或检索它们时,这种方法很有帮助。import { ChatAnthropic } from "@langchain/anthropic";
const citationsModel = new ChatAnthropic({
model: "claude-haiku-4-5-20251001",
});
const messagesWithCitations = [
{
type: "user",
content: [
{
type: "search_result",
title: "法国历史",
source: "https://some-uri.com",
citations: { enabled: true },
content: [
{
type: "text",
text: "法国的首都是巴黎。",
},
{
type: "text",
text: "法国的旧都是里昂。",
},
],
},
{
type: "text",
text: "法国的首都是哪里?",
},
],
},
];
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";
// 创建一个返回搜索结果的工具
const ragTool = tool(
() => [
{
type: "search_result",
title: "法国历史",
source: "https://some-uri.com",
citations: { enabled: true },
content: [
{
type: "text",
text: "法国的首都是巴黎。",
},
{
type: "text",
text: "法国的旧都是里昂。",
},
],
},
{
type: "search_result",
title: "法国地理",
source: "https://some-uri.com",
citations: { enabled: true },
content: [
{
type: "text",
text: "法国是欧洲的一个国家。",
},
{
type: "text",
text: "法国的首都是巴黎。",
},
],
},
],
{
name: "my_rag_tool",
description: "访问我的知识库的检索系统。",
schema: z.object({
query: z.string().describe("要在知识库中搜索的查询"),
}),
}
);
// 创建带有搜索结果 beta 头的模型
const model = new ChatAnthropic({
model: "claude-haiku-4-5-20251001",
}).bindTools([ragTool]);
const result = await model.invoke([
{
role: "user",
content: "法国的首都是哪里?",
},
]);
console.log(JSON.stringify(result.content, null, 2));
与文本分割器一起使用
Anthropic 还允许您使用 自定义文档 类型指定您自己的分割。LangChain 文本分割器可用于为此目的生成有意义的分割。请参见下面的示例,我们在其中分割 LangChain.js README(一个 Markdown 文档)并将其作为上下文传递给 Claude:import { ChatAnthropic } from "@langchain/anthropic";
import { MarkdownTextSplitter } from "@langchain/classic/text_splitter";
function formatToAnthropicDocuments(documents: string[]) {
return {
type: "document",
source: {
type: "content",
content: documents.map((document) => ({ type: "text", text: document })),
},
citations: { enabled: true },
};
}
// 获取 readme
const readmeResponse = await fetch(
"https://raw.githubusercontent.com/langchain-ai/langchainjs/master/README.md"
);
const readme = await readmeResponse.text();
// 分割成块
const splitter = new MarkdownTextSplitter({
chunkOverlap: 0,
chunkSize: 50,
});
const documents = await splitter.splitText(readme);
// 构造消息
const messageWithSplitDocuments = {
role: "user",
content: [
formatToAnthropicDocuments(documents),
{ type: "text", text: "给我一个 LangChain 教程的链接。请引用你的来源" },
],
};
// 查询 LLM
const citationsModelWithSplits = new ChatAnthropic({
model: "claude-sonnet-4-6",
});
const resWithSplits = await citationsModelWithSplits.invoke([messageWithSplitDocuments]);
console.log(JSON.stringify(resWithSplits.content, null, 2));
[
{
"type": "text",
"text": "根据文档,我可以为您提供 LangChain 教程的链接:\n\n"
},
{
"type": "text",
"text": "教程可以在以下网址找到: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
}
]
}
]
上下文管理
Anthropic 支持上下文编辑功能,可自动管理模型的上下文窗口(例如,通过清除工具结果)。 详情和配置选项请参见 Anthropic 文档。上下文管理自
@langchain/anthropic@0.3.29 起支持import { ChatAnthropic } from "@langchain/anthropic";
const llm = new ChatAnthropic({
model: "claude-sonnet-4-6",
clientOptions: {
defaultHeaders: {
"anthropic-beta": "context-management-2025-06-27",
},
},
contextManagement: { edits: [{ type: "clear_tool_uses_20250919" }] },
)
const llmWithTools = llm.bindTools([{ type: "web_search_20250305", name: "web_search" }]);
const response = await llmWithTools.invoke("搜索人工智能的最新进展");
API 参考文档
有关所有ChatAnthropic 功能和配置的详细文档,请访问 API 参考文档。
Connect these docs to Claude, VSCode, and more via MCP for real-time answers.

