-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
langchain-aws[major]: LangChain AWS package #5907
Changes from 14 commits
d83bbe9
8c217cd
2a5a483
abdde50
7ff710c
562f208
35c13c1
acbcc5c
3d84e48
b103443
49fe576
67c74ca
7ceef7d
0ed8583
2dd506e
16df692
3b46883
60dccf7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
--- | ||
sidebar_label: Bedrock Converse | ||
--- | ||
|
||
# ChatBedrockConverse | ||
|
||
> [Amazon Bedrock Converse](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_Converse.html) is a fully managed service that makes Foundation Models (FMs) | ||
> from leading AI startups and Amazon available via an API. You can choose from a wide range of FMs to find the model that is best suited for your use case. | ||
|
||
## Setup | ||
|
||
You'll need to install the `@langchain/aws` package: | ||
|
||
import IntegrationInstallTooltip from "@mdx_components/integration_install_tooltip.mdx"; | ||
|
||
<IntegrationInstallTooltip></IntegrationInstallTooltip> | ||
|
||
```bash npm2yarn | ||
npm install @langchain/aws | ||
``` | ||
|
||
## Usage | ||
|
||
import UnifiedModelParamsTooltip from "@mdx_components/unified_model_params_tooltip.mdx"; | ||
|
||
<UnifiedModelParamsTooltip></UnifiedModelParamsTooltip> | ||
|
||
import CodeBlock from "@theme/CodeBlock"; | ||
import BedrockConverseExample from "@examples/models/chat/integration_bedrock_converse.ts"; | ||
|
||
<CodeBlock language="typescript">{BedrockConverseExample}</CodeBlock> | ||
|
||
:::tip | ||
See the LangSmith traces for the above example [here](https://smith.langchain.com/public/7aeb0c56-9afa-441d-8659-4d52c007eae0/r), and [here for steaming](https://smith.langchain.com/public/74606291-45cd-478c-a874-568b2905427f/r). | ||
::: | ||
|
||
## Multimodal inputs | ||
|
||
:::tip | ||
Multimodal inputs are currently only supported by Anthropic Claude-3 models. | ||
::: | ||
|
||
Anthropic Claude-3 models hosted on Bedrock have multimodal capabilities and can reason about images. Here's an example: | ||
|
||
import BedrockMultimodalExample from "@examples/models/chat/integration_bedrock_multimodal_converse.ts"; | ||
|
||
<CodeBlock language="typescript">{BedrockMultimodalExample}</CodeBlock> | ||
|
||
:::tip | ||
See the LangSmith trace [here](https://smith.langchain.com/public/c40f8d09-123a-4b3b-934a-625d5ee0f57a/r). | ||
::: | ||
|
||
### Tool calling | ||
|
||
The examples below demonstrate how to use tool calling, along with the `withStructuredOutput` method to easily compose structured output LLM calls. | ||
|
||
import ToolCalling from "@examples/models/chat/integration_bedrock_tools_converse.ts"; | ||
|
||
<CodeBlock language="typescript">{ToolCalling}</CodeBlock> | ||
|
||
Check out the output of this tool call! We can see here it's using chain-of-thought before calling the tool, where it describes what it's going to do in plain text before calling the tool: `Okay, let's get the weather for New York City.`. | ||
|
||
:::tip | ||
See the LangSmith trace [here](https://smith.langchain.com/public/d34e378d-5044-4b5b-9ed7-3d2486fe5d47/r) | ||
::: | ||
|
||
#### `.withStructuredOutput({ ... })` | ||
|
||
Using the `.withStructuredOutput` method, you can easily make the LLM return structured output, given only a Zod or JSON schema: | ||
|
||
import WSOExample from "@examples/models/chat/integration_bedrock_wso_converse.ts"; | ||
|
||
<CodeBlock language="typescript">{WSOExample}</CodeBlock> | ||
|
||
:::tip | ||
See the LangSmith trace [here](https://smith.langchain.com/public/982940c4-5f96-4168-80c9-99102c3e073a/r) | ||
::: |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { ChatBedrockConverse } from "@langchain/aws"; | ||
import { HumanMessage } from "@langchain/core/messages"; | ||
|
||
const model = new ChatBedrockConverse({ | ||
model: "anthropic.claude-3-sonnet-20240229-v1:0", | ||
region: "us-east-1", | ||
credentials: { | ||
accessKeyId: process.env.BEDROCK_AWS_ACCESS_KEY_ID!, | ||
secretAccessKey: process.env.BEDROCK_AWS_SECRET_ACCESS_KEY!, | ||
}, | ||
}); | ||
|
||
const res = await model.invoke([ | ||
new HumanMessage({ content: "Tell me a joke" }), | ||
]); | ||
console.log(res); | ||
|
||
/* | ||
AIMessage { | ||
content: "Here's a joke for you:\n" + | ||
'\n' + | ||
"Why can't a bicycle stand up by itself? Because it's two-tired!", | ||
response_metadata: { ... }, | ||
id: '08afa4fb-c212-4c1e-853a-d854972bec78', | ||
usage_metadata: { input_tokens: 11, output_tokens: 28, total_tokens: 39 } | ||
} | ||
*/ | ||
|
||
const stream = await model.stream([ | ||
new HumanMessage({ content: "Tell me a joke" }), | ||
]); | ||
|
||
for await (const chunk of stream) { | ||
console.log(chunk.content); | ||
} | ||
|
||
/* | ||
Here | ||
's | ||
a | ||
silly | ||
joke | ||
for | ||
you | ||
: | ||
|
||
|
||
Why | ||
di | ||
d the | ||
tom | ||
ato | ||
turn | ||
re | ||
d? | ||
Because | ||
it | ||
saw | ||
the | ||
sal | ||
a | ||
d | ||
dressing | ||
! | ||
*/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import * as fs from "node:fs/promises"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hey there! I've reviewed the code and noticed that the recent changes explicitly access environment variables via |
||
|
||
import { ChatBedrockConverse } from "@langchain/aws"; | ||
import { HumanMessage } from "@langchain/core/messages"; | ||
|
||
const model = new ChatBedrockConverse({ | ||
model: "anthropic.claude-3-sonnet-20240229-v1:0", | ||
region: "us-east-1", | ||
credentials: { | ||
accessKeyId: process.env.BEDROCK_AWS_ACCESS_KEY_ID!, | ||
secretAccessKey: process.env.BEDROCK_AWS_SECRET_ACCESS_KEY!, | ||
}, | ||
}); | ||
|
||
const imageData = await fs.readFile("./hotdog.jpg"); | ||
|
||
const res = await model.invoke([ | ||
new HumanMessage({ | ||
content: [ | ||
{ | ||
type: "text", | ||
text: "What's in this image?", | ||
}, | ||
{ | ||
type: "image_url", | ||
image_url: { | ||
url: `data:image/jpeg;base64,${imageData.toString("base64")}`, | ||
}, | ||
}, | ||
], | ||
}), | ||
]); | ||
console.log(res); | ||
|
||
/* | ||
AIMessage { | ||
content: 'The image shows a hot dog or frankfurter. It has a reddish-pink sausage inside a light tan-colored bread bun. The hot dog bun is split open, allowing the sausage filling to be visible. The image appears to be focused solely on depicting this classic American fast food item against a plain white background.', | ||
response_metadata: { ... }, | ||
id: '1608d043-575a-450e-8eac-2fef6297cfe2', | ||
usage_metadata: { input_tokens: 276, output_tokens: 75, total_tokens: 351 } | ||
} | ||
*/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { ChatBedrockConverse } from "@langchain/aws"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hey there! 👋 I've reviewed the code and noticed that the addition explicitly accesses environment variables using |
||
import { tool } from "@langchain/core/tools"; | ||
import { z } from "zod"; | ||
|
||
const model = new ChatBedrockConverse({ | ||
model: "anthropic.claude-3-sonnet-20240229-v1:0", | ||
region: "us-east-1", | ||
credentials: { | ||
accessKeyId: process.env.BEDROCK_AWS_ACCESS_KEY_ID!, | ||
secretAccessKey: process.env.BEDROCK_AWS_SECRET_ACCESS_KEY!, | ||
}, | ||
}); | ||
|
||
const weatherTool = tool( | ||
({ city, state }) => `The weather in ${city}, ${state} is 72°F and sunny`, | ||
{ | ||
name: "weather_tool", | ||
description: "Get the weather for a city", | ||
schema: z.object({ | ||
city: z.string().describe("The city to get the weather for"), | ||
state: z.string().describe("The state to get the weather for").optional(), | ||
}), | ||
} | ||
); | ||
|
||
const modelWithTools = model.bindTools([weatherTool]); | ||
// Optionally, you can bind tools via the `.bind` method: | ||
// const modelWithTools = model.bind({ | ||
// tools: [weatherTool] | ||
// }); | ||
|
||
const res = await modelWithTools.invoke("What's the weather in New York?"); | ||
console.log(res); | ||
|
||
/* | ||
AIMessage { | ||
content: [ | ||
{ | ||
type: 'text', | ||
text: "Okay, let's get the weather for New York City." | ||
} | ||
], | ||
response_metadata: { ... }, | ||
id: '49a97da0-e971-4d7f-9f04-2495e068c15e', | ||
tool_calls: [ | ||
{ | ||
id: 'tooluse_O6Q1Ghm7SmKA9mn2ZKmBzg', | ||
name: 'weather_tool', | ||
args: { | ||
'city': 'New York', | ||
}, | ||
], | ||
usage_metadata: { input_tokens: 289, output_tokens: 68, total_tokens: 357 } | ||
} | ||
*/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { ChatBedrockConverse } from "@langchain/aws"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hey there! 👋 I've noticed that the recent change in the PR explicitly accesses environment variables via |
||
import { z } from "zod"; | ||
|
||
const model = new ChatBedrockConverse({ | ||
model: "anthropic.claude-3-sonnet-20240229-v1:0", | ||
region: "us-east-1", | ||
credentials: { | ||
accessKeyId: process.env.BEDROCK_AWS_ACCESS_KEY_ID!, | ||
secretAccessKey: process.env.BEDROCK_AWS_SECRET_ACCESS_KEY!, | ||
}, | ||
}); | ||
|
||
const weatherSchema = z | ||
.object({ | ||
city: z.string().describe("The city to get the weather for"), | ||
state: z.string().describe("The state to get the weather for").optional(), | ||
}) | ||
.describe("Get the weather for a city"); | ||
|
||
const modelWithStructuredOutput = model.withStructuredOutput(weatherSchema, { | ||
name: "weather_tool", // Optional, defaults to 'extract' | ||
}); | ||
|
||
const res = await modelWithStructuredOutput.invoke( | ||
"What's the weather in New York?" | ||
); | ||
console.log(res); | ||
|
||
/* | ||
{ city: 'New York', state: 'NY' } | ||
*/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
module.exports = { | ||
extends: [ | ||
"airbnb-base", | ||
"eslint:recommended", | ||
"prettier", | ||
"plugin:@typescript-eslint/recommended", | ||
], | ||
parserOptions: { | ||
ecmaVersion: 12, | ||
parser: "@typescript-eslint/parser", | ||
project: "./tsconfig.json", | ||
sourceType: "module", | ||
}, | ||
plugins: ["@typescript-eslint", "no-instanceof"], | ||
ignorePatterns: [ | ||
".eslintrc.cjs", | ||
"scripts", | ||
"node_modules", | ||
"dist", | ||
"dist-cjs", | ||
"*.js", | ||
"*.cjs", | ||
"*.d.ts", | ||
], | ||
rules: { | ||
"no-process-env": 2, | ||
"no-instanceof/no-instanceof": 2, | ||
"@typescript-eslint/explicit-module-boundary-types": 0, | ||
"@typescript-eslint/no-empty-function": 0, | ||
"@typescript-eslint/no-shadow": 0, | ||
"@typescript-eslint/no-empty-interface": 0, | ||
"@typescript-eslint/no-use-before-define": ["error", "nofunc"], | ||
"@typescript-eslint/no-unused-vars": ["warn", { args: "none" }], | ||
"@typescript-eslint/no-floating-promises": "error", | ||
"@typescript-eslint/no-misused-promises": "error", | ||
camelcase: 0, | ||
"class-methods-use-this": 0, | ||
"import/extensions": [2, "ignorePackages"], | ||
"import/no-extraneous-dependencies": [ | ||
"error", | ||
{ devDependencies: ["**/*.test.ts"] }, | ||
], | ||
"import/no-unresolved": 0, | ||
"import/prefer-default-export": 0, | ||
"keyword-spacing": "error", | ||
"max-classes-per-file": 0, | ||
"max-len": 0, | ||
"no-await-in-loop": 0, | ||
"no-bitwise": 0, | ||
"no-console": 0, | ||
"no-restricted-syntax": 0, | ||
"no-shadow": 0, | ||
"no-continue": 0, | ||
"no-void": 0, | ||
"no-underscore-dangle": 0, | ||
"no-use-before-define": 0, | ||
"no-useless-constructor": 0, | ||
"no-return-await": 0, | ||
"consistent-return": 0, | ||
"no-else-return": 0, | ||
"func-names": 0, | ||
"no-lonely-if": 0, | ||
"prefer-rest-params": 0, | ||
"new-cap": ["error", { properties: false, capIsNew: false }], | ||
}, | ||
overrides: [ | ||
{ | ||
files: ["**/*.test.ts"], | ||
rules: { | ||
"@typescript-eslint/no-unused-vars": "off", | ||
}, | ||
}, | ||
], | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
index.cjs | ||
index.js | ||
index.d.ts | ||
index.d.cts | ||
node_modules | ||
dist | ||
.yarn |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"$schema": "https://json.schemastore.org/prettierrc", | ||
"printWidth": 80, | ||
"tabWidth": 2, | ||
"useTabs": false, | ||
"semi": true, | ||
"singleQuote": false, | ||
"quoteProps": "as-needed", | ||
"jsxSingleQuote": false, | ||
"trailingComma": "es5", | ||
"bracketSpacing": true, | ||
"arrowParens": "always", | ||
"requirePragma": false, | ||
"insertPragma": false, | ||
"proseWrap": "preserve", | ||
"htmlWhitespaceSensitivity": "css", | ||
"vueIndentScriptAndStyle": false, | ||
"endOfLine": "lf" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey there! 👋 I've reviewed the code and noticed that the recent changes explicitly access environment variables using
process.env
. I've flagged this for your review to ensure it aligns with our security and best practices. Let me know if you have any questions!