Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(anthropic): langchain-anthropic support custom create anthropic client #6615

Merged
merged 5 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions docs/core_docs/docs/integrations/chat/anthropic.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -931,6 +931,36 @@
"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)."
]
},
{
"cell_type": "markdown",
"id": "f8dece4e",
"metadata": {},
"source": [
"## Custom clients\n",
"\n",
"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:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "00ec6d41",
"metadata": {},
"outputs": [],
"source": [
"import { AnthropicVertex } from \"@anthropic-ai/vertex-sdk\";\n",
"\n",
"const customClient = new AnthropicVertex();\n",
"\n",
"const modelWithCustomClient = new ChatAnthropic({\n",
" modelName: \"claude-3-sonnet-20240229\",\n",
" maxRetries: 0,\n",
" createClient: () => customClient,\n",
"});\n",
"\n",
"await modelWithCustomClient.invoke([{ role: \"user\", content: \"Hello!\" }]);"
]
},
{
"cell_type": "markdown",
"id": "3a5bb5ca-c3ae-4a58-be67-2cd18574b9a3",
Expand Down
1 change: 1 addition & 0 deletions docs/core_docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"validate": "yarn notebook_validate"
},
"dependencies": {
"@anthropic-ai/vertex-sdk": "^0.4.1",
"@docusaurus/core": "2.4.3",
"@docusaurus/preset-classic": "2.4.3",
"@docusaurus/remark-plugin-npm2yarn": "2.4.3",
Expand Down
1 change: 1 addition & 0 deletions libs/langchain-anthropic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"zod-to-json-schema": "^3.22.4"
},
"devDependencies": {
"@anthropic-ai/vertex-sdk": "^0.4.1",
"@jest/globals": "^29.5.0",
"@langchain/scripts": ">=0.1.0 <0.2.0",
"@langchain/standard-tests": "0.0.0",
Expand Down
23 changes: 21 additions & 2 deletions libs/langchain-anthropic/src/chat_models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,14 @@ export interface AnthropicInput {
* @default true
*/
streamUsage?: boolean;

/**
* Optional method that returns an initialized underlying Anthropic client.
* Useful for accessing Anthropic models hosted on other cloud services
* such as Google Vertex.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
createClient?: (options: ClientOptions) => any;
}

/**
Expand Down Expand Up @@ -611,6 +619,13 @@ export class ChatAnthropicMessages<

streamUsage = true;

/**
* Optional method that returns an initialized underlying Anthropic client.
* Useful for accessing Anthropic models hosted on other cloud services
* such as Google Vertex.
*/
createClient: (options: ClientOptions) => Anthropic;

constructor(fields?: AnthropicInput & BaseChatModelParams) {
super(fields ?? {});

Expand Down Expand Up @@ -644,6 +659,10 @@ export class ChatAnthropicMessages<

this.streaming = fields?.streaming ?? false;
this.streamUsage = fields?.streamUsage ?? this.streamUsage;

this.createClient =
fields?.createClient ??
((options: ClientOptions) => new Anthropic(options));
}

getLsParams(options: this["ParsedCallOptions"]): LangSmithParams {
Expand Down Expand Up @@ -908,7 +927,7 @@ export class ChatAnthropicMessages<
): Promise<Stream<AnthropicMessageStreamEvent>> {
if (!this.streamingClient) {
const options_ = this.apiUrl ? { baseURL: this.apiUrl } : undefined;
this.streamingClient = new Anthropic({
this.streamingClient = this.createClient({
...this.clientOptions,
...options_,
apiKey: this.apiKey,
Expand Down Expand Up @@ -938,7 +957,7 @@ export class ChatAnthropicMessages<
if (!this.apiKey) {
throw new Error("Missing Anthropic API key.");
}
this.batchClient = new Anthropic({
this.batchClient = this.createClient({
...this.clientOptions,
...options,
apiKey: this.apiKey,
Expand Down
14 changes: 14 additions & 0 deletions libs/langchain-anthropic/src/tests/chat_models.int.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
} from "@langchain/core/prompts";
import { CallbackManager } from "@langchain/core/callbacks/manager";
import { concat } from "@langchain/core/utils/stream";
import { AnthropicVertex } from "@anthropic-ai/vertex-sdk";
import { ChatAnthropic } from "../chat_models.js";

test("Test ChatAnthropic", async () => {
Expand Down Expand Up @@ -735,3 +736,16 @@ test.skip("tool caching", async () => {
0
);
});

test.skip("Test ChatAnthropic with custom client", async () => {
const client = new AnthropicVertex();
const chat = new ChatAnthropic({
modelName: "claude-3-sonnet-20240229",
maxRetries: 0,
createClient: () => client,
});
const message = new HumanMessage("Hello!");
const res = await chat.invoke([message]);
// console.log({ res });
expect(res.response_metadata.usage).toBeDefined();
});
41 changes: 41 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,21 @@ __metadata:
languageName: node
linkType: hard

"@anthropic-ai/sdk@npm:>=0.14 <1":
version: 0.27.0
resolution: "@anthropic-ai/sdk@npm:0.27.0"
dependencies:
"@types/node": ^18.11.18
"@types/node-fetch": ^2.6.4
abort-controller: ^3.0.0
agentkeepalive: ^4.2.1
form-data-encoder: 1.7.2
formdata-node: ^4.3.2
node-fetch: ^2.6.7
checksum: 5cb980769a38a660fa607d9985f4cdae7aabc49053b94fe892f6c3b30f2714c32c6e86c6cf94c8bce9ceea6eed2cd5bac2e1d9d58c9aad0da43681f0a060263d
languageName: node
linkType: hard

"@anthropic-ai/sdk@npm:^0.25.2":
version: 0.25.2
resolution: "@anthropic-ai/sdk@npm:0.25.2"
Expand All @@ -226,6 +241,16 @@ __metadata:
languageName: node
linkType: hard

"@anthropic-ai/vertex-sdk@npm:^0.4.1":
version: 0.4.1
resolution: "@anthropic-ai/vertex-sdk@npm:0.4.1"
dependencies:
"@anthropic-ai/sdk": ">=0.14 <1"
google-auth-library: ^9.4.2
checksum: 3983c6f1b0e0aa2ce6896a0269177d1374343ba86169a30ad6cc0d9beef40ddcf410159baaa3f0942afbf62930951d067a870aa5c5e0624fe2c47981dc8d8c55
languageName: node
linkType: hard

"@apache-arrow/ts@npm:^12.0.0":
version: 12.0.0
resolution: "@apache-arrow/ts@npm:12.0.0"
Expand Down Expand Up @@ -10852,6 +10877,7 @@ __metadata:
resolution: "@langchain/anthropic@workspace:libs/langchain-anthropic"
dependencies:
"@anthropic-ai/sdk": ^0.25.2
"@anthropic-ai/vertex-sdk": ^0.4.1
"@jest/globals": ^29.5.0
"@langchain/core": ">=0.2.21 <0.3.0"
"@langchain/scripts": ">=0.1.0 <0.2.0"
Expand Down Expand Up @@ -23262,6 +23288,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "core_docs@workspace:docs/core_docs"
dependencies:
"@anthropic-ai/vertex-sdk": ^0.4.1
"@babel/eslint-parser": ^7.18.2
"@docusaurus/core": 2.4.3
"@docusaurus/preset-classic": 2.4.3
Expand Down Expand Up @@ -28678,6 +28705,20 @@ __metadata:
languageName: node
linkType: hard

"google-auth-library@npm:^9.4.2":
version: 9.14.0
resolution: "google-auth-library@npm:9.14.0"
dependencies:
base64-js: ^1.3.0
ecdsa-sig-formatter: ^1.0.11
gaxios: ^6.1.1
gcp-metadata: ^6.1.0
gtoken: ^7.0.0
jws: ^4.0.0
checksum: ff2a66e84726b3a25711a64583d86cf9e0c0df857d538ce8127822d220e81e1e7d0defcedecb2be7fc407c104bb7d5ca26a4f201bde871c8d09ef72cc83603f8
languageName: node
linkType: hard

"google-gax@npm:^4.0.3":
version: 4.3.3
resolution: "google-gax@npm:4.3.3"
Expand Down
Loading