Skip to content

Commit 42f2463

Browse files
rxliulijacoblee93
andauthored
feat(anthropic): langchain-anthropic support custom create anthropic client (#6615)
Co-authored-by: jacoblee93 <[email protected]>
1 parent 5fd5c45 commit 42f2463

File tree

6 files changed

+108
-2
lines changed

6 files changed

+108
-2
lines changed

docs/core_docs/docs/integrations/chat/anthropic.ipynb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,36 @@
931931
"For more on how prompt caching works, see [Anthropic's docs](https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching#how-prompt-caching-works)."
932932
]
933933
},
934+
{
935+
"cell_type": "markdown",
936+
"id": "f8dece4e",
937+
"metadata": {},
938+
"source": [
939+
"## Custom clients\n",
940+
"\n",
941+
"Anthropic models [may be hosted on cloud services such as Google Vertex](https://docs.anthropic.com/en/api/claude-on-vertex-ai) that rely on a different underlying client with the same interface as the primary Anthropic client. You can access these services by providing a `createClient` method that returns an initialized instance of an Anthropic client. Here's an example:"
942+
]
943+
},
944+
{
945+
"cell_type": "code",
946+
"execution_count": null,
947+
"id": "00ec6d41",
948+
"metadata": {},
949+
"outputs": [],
950+
"source": [
951+
"import { AnthropicVertex } from \"@anthropic-ai/vertex-sdk\";\n",
952+
"\n",
953+
"const customClient = new AnthropicVertex();\n",
954+
"\n",
955+
"const modelWithCustomClient = new ChatAnthropic({\n",
956+
" modelName: \"claude-3-sonnet-20240229\",\n",
957+
" maxRetries: 0,\n",
958+
" createClient: () => customClient,\n",
959+
"});\n",
960+
"\n",
961+
"await modelWithCustomClient.invoke([{ role: \"user\", content: \"Hello!\" }]);"
962+
]
963+
},
934964
{
935965
"cell_type": "markdown",
936966
"id": "3a5bb5ca-c3ae-4a58-be67-2cd18574b9a3",

docs/core_docs/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"validate": "yarn notebook_validate"
3131
},
3232
"dependencies": {
33+
"@anthropic-ai/vertex-sdk": "^0.4.1",
3334
"@docusaurus/core": "2.4.3",
3435
"@docusaurus/preset-classic": "2.4.3",
3536
"@docusaurus/remark-plugin-npm2yarn": "2.4.3",

libs/langchain-anthropic/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"zod-to-json-schema": "^3.22.4"
4343
},
4444
"devDependencies": {
45+
"@anthropic-ai/vertex-sdk": "^0.4.1",
4546
"@jest/globals": "^29.5.0",
4647
"@langchain/scripts": ">=0.1.0 <0.2.0",
4748
"@langchain/standard-tests": "0.0.0",

libs/langchain-anthropic/src/chat_models.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,14 @@ export interface AnthropicInput {
145145
* @default true
146146
*/
147147
streamUsage?: boolean;
148+
149+
/**
150+
* Optional method that returns an initialized underlying Anthropic client.
151+
* Useful for accessing Anthropic models hosted on other cloud services
152+
* such as Google Vertex.
153+
*/
154+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
155+
createClient?: (options: ClientOptions) => any;
148156
}
149157

150158
/**
@@ -611,6 +619,13 @@ export class ChatAnthropicMessages<
611619

612620
streamUsage = true;
613621

622+
/**
623+
* Optional method that returns an initialized underlying Anthropic client.
624+
* Useful for accessing Anthropic models hosted on other cloud services
625+
* such as Google Vertex.
626+
*/
627+
createClient: (options: ClientOptions) => Anthropic;
628+
614629
constructor(fields?: AnthropicInput & BaseChatModelParams) {
615630
super(fields ?? {});
616631

@@ -644,6 +659,10 @@ export class ChatAnthropicMessages<
644659

645660
this.streaming = fields?.streaming ?? false;
646661
this.streamUsage = fields?.streamUsage ?? this.streamUsage;
662+
663+
this.createClient =
664+
fields?.createClient ??
665+
((options: ClientOptions) => new Anthropic(options));
647666
}
648667

649668
getLsParams(options: this["ParsedCallOptions"]): LangSmithParams {
@@ -908,7 +927,7 @@ export class ChatAnthropicMessages<
908927
): Promise<Stream<AnthropicMessageStreamEvent>> {
909928
if (!this.streamingClient) {
910929
const options_ = this.apiUrl ? { baseURL: this.apiUrl } : undefined;
911-
this.streamingClient = new Anthropic({
930+
this.streamingClient = this.createClient({
912931
...this.clientOptions,
913932
...options_,
914933
apiKey: this.apiKey,
@@ -938,7 +957,7 @@ export class ChatAnthropicMessages<
938957
if (!this.apiKey) {
939958
throw new Error("Missing Anthropic API key.");
940959
}
941-
this.batchClient = new Anthropic({
960+
this.batchClient = this.createClient({
942961
...this.clientOptions,
943962
...options,
944963
apiKey: this.apiKey,

libs/langchain-anthropic/src/tests/chat_models.int.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
} from "@langchain/core/prompts";
1717
import { CallbackManager } from "@langchain/core/callbacks/manager";
1818
import { concat } from "@langchain/core/utils/stream";
19+
import { AnthropicVertex } from "@anthropic-ai/vertex-sdk";
1920
import { ChatAnthropic } from "../chat_models.js";
2021

2122
test("Test ChatAnthropic", async () => {
@@ -735,3 +736,16 @@ test.skip("tool caching", async () => {
735736
0
736737
);
737738
});
739+
740+
test.skip("Test ChatAnthropic with custom client", async () => {
741+
const client = new AnthropicVertex();
742+
const chat = new ChatAnthropic({
743+
modelName: "claude-3-sonnet-20240229",
744+
maxRetries: 0,
745+
createClient: () => client,
746+
});
747+
const message = new HumanMessage("Hello!");
748+
const res = await chat.invoke([message]);
749+
// console.log({ res });
750+
expect(res.response_metadata.usage).toBeDefined();
751+
});

yarn.lock

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,21 @@ __metadata:
211211
languageName: node
212212
linkType: hard
213213

214+
"@anthropic-ai/sdk@npm:>=0.14 <1":
215+
version: 0.27.0
216+
resolution: "@anthropic-ai/sdk@npm:0.27.0"
217+
dependencies:
218+
"@types/node": ^18.11.18
219+
"@types/node-fetch": ^2.6.4
220+
abort-controller: ^3.0.0
221+
agentkeepalive: ^4.2.1
222+
form-data-encoder: 1.7.2
223+
formdata-node: ^4.3.2
224+
node-fetch: ^2.6.7
225+
checksum: 5cb980769a38a660fa607d9985f4cdae7aabc49053b94fe892f6c3b30f2714c32c6e86c6cf94c8bce9ceea6eed2cd5bac2e1d9d58c9aad0da43681f0a060263d
226+
languageName: node
227+
linkType: hard
228+
214229
"@anthropic-ai/sdk@npm:^0.25.2":
215230
version: 0.25.2
216231
resolution: "@anthropic-ai/sdk@npm:0.25.2"
@@ -226,6 +241,16 @@ __metadata:
226241
languageName: node
227242
linkType: hard
228243

244+
"@anthropic-ai/vertex-sdk@npm:^0.4.1":
245+
version: 0.4.1
246+
resolution: "@anthropic-ai/vertex-sdk@npm:0.4.1"
247+
dependencies:
248+
"@anthropic-ai/sdk": ">=0.14 <1"
249+
google-auth-library: ^9.4.2
250+
checksum: 3983c6f1b0e0aa2ce6896a0269177d1374343ba86169a30ad6cc0d9beef40ddcf410159baaa3f0942afbf62930951d067a870aa5c5e0624fe2c47981dc8d8c55
251+
languageName: node
252+
linkType: hard
253+
229254
"@apache-arrow/ts@npm:^12.0.0":
230255
version: 12.0.0
231256
resolution: "@apache-arrow/ts@npm:12.0.0"
@@ -10852,6 +10877,7 @@ __metadata:
1085210877
resolution: "@langchain/anthropic@workspace:libs/langchain-anthropic"
1085310878
dependencies:
1085410879
"@anthropic-ai/sdk": ^0.25.2
10880+
"@anthropic-ai/vertex-sdk": ^0.4.1
1085510881
"@jest/globals": ^29.5.0
1085610882
"@langchain/core": ">=0.2.21 <0.3.0"
1085710883
"@langchain/scripts": ">=0.1.0 <0.2.0"
@@ -23262,6 +23288,7 @@ __metadata:
2326223288
version: 0.0.0-use.local
2326323289
resolution: "core_docs@workspace:docs/core_docs"
2326423290
dependencies:
23291+
"@anthropic-ai/vertex-sdk": ^0.4.1
2326523292
"@babel/eslint-parser": ^7.18.2
2326623293
"@docusaurus/core": 2.4.3
2326723294
"@docusaurus/preset-classic": 2.4.3
@@ -28678,6 +28705,20 @@ __metadata:
2867828705
languageName: node
2867928706
linkType: hard
2868028707

28708+
"google-auth-library@npm:^9.4.2":
28709+
version: 9.14.0
28710+
resolution: "google-auth-library@npm:9.14.0"
28711+
dependencies:
28712+
base64-js: ^1.3.0
28713+
ecdsa-sig-formatter: ^1.0.11
28714+
gaxios: ^6.1.1
28715+
gcp-metadata: ^6.1.0
28716+
gtoken: ^7.0.0
28717+
jws: ^4.0.0
28718+
checksum: ff2a66e84726b3a25711a64583d86cf9e0c0df857d538ce8127822d220e81e1e7d0defcedecb2be7fc407c104bb7d5ca26a4f201bde871c8d09ef72cc83603f8
28719+
languageName: node
28720+
linkType: hard
28721+
2868128722
"google-gax@npm:^4.0.3":
2868228723
version: 4.3.3
2868328724
resolution: "google-gax@npm:4.3.3"

0 commit comments

Comments
 (0)