Lambda Web Adapter#
Let create a lambda function with web adatper enabled. Please pay attention to the permissions so this function can call Bedrock
import { Stack, StackProps, aws_iam, aws_lambda } from "aws-cdk-lib";import { Effect } from "aws-cdk-lib/aws-iam";import { Construct } from "constructs";import path = require("path");export class LambdaWebAdapter extends Stack {constructor(scope: Construct, id: string, props: StackProps) {super(scope, id, props);const func = new aws_lambda.Function(this, "FlaskWebAdapter", {functionName: "FlaskWebAdatper",code: aws_lambda.EcrImageCode.fromAssetImage(path.join(__dirname, "./../../flask/app/")),runtime: aws_lambda.Runtime.FROM_IMAGE,handler: aws_lambda.Handler.FROM_IMAGE,memorySize: 1024,});func.addToRolePolicy(new aws_iam.PolicyStatement({effect: Effect.ALLOW,resources: ["arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-v2",],actions: ["bedrock:InvokeModel","bedrock:InvokeModelWithResponseStream",],}));}}
Bedrock API#
Let call batch response
def bedrock_batch(topic='chicken soup'):"""demo"""if request.method == 'POST':topic = request.json.get('topic')print(request.json.get('topic'))else:print('get')# promptinstruction = f"""You are a world class writer. Please write a sweet bedtime story about {topic}."""# bodybody = json.dumps({'prompt': f'Human:{instruction}\n\nAssistant:','max_tokens_to_sample': 1028,'temperature': 1,'top_k': 250,'top_p': 0.999,'stop_sequences': ['\n\nHuman:']})# bedrock requestresponse = bedrock_client.invoke_model(body=body,contentType="application/json",accept="*/*",modelId="anthropic.claude-v2",)# bedrock responseresponse_body = json.loads(response.get('body').read())print(response_body)# resposnereturn response_body
Let call stream response
def bedrock_stream(topic:str ='chicken soup'):"""demo"""instruction = f'You are a world class writer. Please write a sweet bedtime story about {topic}'# request bodybody = json.dumps({'prompt': f'Human:{instruction}\n\nAssistant:','max_tokens_to_sample': 1028,'temperature': 1,'top_k': 250,'top_p': 0.999,'stop_sequences': ['\n\nHuman:']})# responseresponse = bedrock_client.invoke_model_with_response_stream(body=body,contentType="application/json",accept="*/*",modelId="anthropic.claude-v2",)# parse streamstream = response.get('body')if stream:for event in stream:chunk = event.get('chunk')if chunk:yield json.loads(chunk.get('bytes').decode())['completion']
FrontEnd#
Let create a simple javascript client to handle
onst callBedrock = async () => {const topic = document.getElementById("topic").value;storyOutput.innerText = "thinking ...";console.log("call bedrock request", topic);if (topic) {try {const response = await fetch("/bedrock", {method: "POST",headers: {"Content-Type": "application/json",},body: JSON.stringify({ topic: topic }),});const body = await response.json();console.log(body);storyOutput.innerText = body.completion;} catch (error) {console.log(error);}}};
Client which handle stream response from Bedrock
const callBedrockStream = async () => {console.log("call bedrock request");try {const response = await fetch("/bedrock-stream", {method: "POST",headers: {"Content-Type": "application/json",},body: JSON.stringify({ topic: "chicken soup" }),});console.log(response);const reader = response.body.getReader();const decoder = new TextDecoder();while (true) {const { done, value } = await reader.read();if (done) {break;}const text = decoder.decode(value);console.log(text);storyOutput.innerText += text;}} catch (error) {console.log(error);}};