AI powered video summarizer with Amazon Bedrock and Anthropic’s Claude
Tags: bedrock, claude, generativeai, serverless
Published: 2024-01-03 10:55:25

![Photo by [Andy Benham](https://unsplash.com/@benham3160?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)](https://cdn-images-1.medium.com/max/6942/0*u1aoh6IkniSqBqg8)



At times, I find myself wanting to quickly get a summary of a video or capture the key points of a tech talk. Thanks to the capabilities of generative AI, achieving this is entirely possible with minimal effort.

In this article, I’ll walk you through the process of creating a service that summarizes YouTube videos based their transcripts and generates audio from these summaries.

![AI powered youtube video summarizer](https://cdn-images-1.medium.com/max/5244/1*o2c9LbDWn59VZaz-GfscIA.png)

We’ll leverage Anthropic’s Claude 2.1 foundation model through Amazon Bedrock for summary generation, and Amazon Polly to synthesize speech from these summaries.

## Solution overview

I will use a step functions to orchestrate the different steps involved in the summary and audio generation :

![AI powered youtube video summarizer architecture](https://cdn-images-1.medium.com/max/4494/1*vW39v-yN0WNZJoHiOVfHwA.png)

🔍 Let’s break this down:

* The **Get Video Transcript** function retrieves the transcript from a specified YouTube video URL. Upon successful retrieval, the transcript is stored in an S3 bucket, ready for processing in the next step.

* **Generate Model Parameters** function retrieves the transcript from the bucket and generates the prompt and inference parameters specific to Anthropic’s Claude v2 model. These parameters are then stored in the bucket for use by the Bedrock API in the subsequent step.

* Invoking the Bedrock API is achieved through the step functions’ AWS SDK integration, enabling the execution of the model inferences with inputs stored in the bucket. This step generates a structured JSON containing the summary.

* **Generate audio form summary** relies on Amazon Polly to perform speech synthesis from the summary produced in the previous step. This step returns the final output containing the video summary in text format, as well as a presigned URL for the generated audio file.

* The bucket serves as a state storage used across all the steps of the state machine. In fact, we don’t know the size of generated video transcript upfront; it might reach the Step Functions’ payload size limit of 256 KB in some lengthy videos.

### On using Anthoropic’s Claude 2.1

At the time of writing, Claude 2.1 model supports 200K tokens, an estimated word count of 150K. It provides also a good accuracy over long documents, making it well-suited for summarizing lengthy video transcripts.

## TL;DR

You will find the complete source code here 👇
[**GitHub - ziedbentahar/yt-video-summarizer-with-bedrock**](https://github.com/ziedbentahar/yt-video-summarizer-with-bedrock)

I will use NodeJs, typescript and CDK for IaC.

## Solution details

### 1- Enabling Anthropic’s Claude v2 in your account

Amazon Bedrock offers a range of foundational models, including Amazon Titan, Anthropic’s Claude, Meta Llama2, etc., which are accessible through Bedrock APIs. By default, these foundational models are not enabled; they must be enabled through the console before use.

We’ll request access to Anthropic’s Claude models. But first we’ll need to submit a use case details:

![Request Anthropic’s Claude access](https://cdn-images-1.medium.com/max/3200/1*WwRSrEGHnqbZ2CCOh-kLeA.png)

### 2- Getting transcripts from Youtube Videos

I will rely on [this lib](https://github.com/Kakulukian/youtube-transcript) for the video transcript extraction (It feels like a cheat code 😉) ; in fact, this library makes use of an unofficial YouTube API without relying on a headless Chrome solution. For now, it yields good results on several YouTube videos, but I might explore a more robust solutions in the future :

{% gist https://gist.github.com/ziedbentahar/9ecc91f8f6c6dbea0cb443b93d54e8e8.js %}

The extracted transcript is then stored on the s3 bucket using `${requestId}/transcript` as a key.

You can find the code for this lambda function [here](https://github.com/ziedbentahar/yt-video-summarizer-with-bedrock/blob/main/src/lambda-handlers/get-youtube-video-transcript.ts)

### 3- Finding the adequate prompt and generating model inference parameters

At the time of writing, Bedrock currently only supports Claude’s Text Completions API. Prompts must be wrapped in `\n\nHuman: and \n\nAssistant:` markers  to let Claude understand the conversation context.

 Here is the prompt; I find that it produces good results for our use case:

```
    You are a video transcript summarizer.
    Summarize this transcript in a third person point of view in 10 sentences.
    Identify the speakers and the main topics of the transcript and add them in the output as well.
    Do not add or invent speaker names if you not able to identify them.
    Please output the summary JSON format conforming to this JSON schema:
    {
      "type": "object",
      "properties": {
        "speakers": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "topics": {
          "type": "string"
        },
        "summary": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    }
   
    <transcript>{{transcript}}</transcript>
```
   

🤖 **Helping Claude producing  good results**:

* To clearly mark to the transcript to summarize, we use **<transcript/>** XML tags. [Claude will specifically focus](https://docs.anthropic.com/claude/docs/constructing-a-prompt#mark-different-parts-of-the-prompt) on the structure encapsulated by these XML tags. I will be substituting **`{{transcript}}`** string with the actual video transcript.

* To assist Claude in generating a reliable JSON output format, I include in the prompt the JSON schema that needs to be adhered to.

* Finally, I also need to inform Claude that I want to generate only a concise JSON response without unnecessary chattiness, meaning without including a preamble and postscript while returning the JSON payload:

```
\n\nHuman:{{prompt}}\n\nAssistant:{
```

Note that the full prompt ends with a trailing  **`{`**

As mentioned on the section above, we will store this generated prompt as well as the model parameters in the bucket so that It can be used as an input of Bedrock API:

```
      const modelParameters = {
        prompt,
        max_tokens_to_sample: MAX_TOKENS_TO_SAMPLE,
        top_k: 250,
        top_p: 1,
        temperature: 0.2,
        stop_sequences: ["Human:"],
        anthropic_version: "bedrock-2023-05-31",
      };
```

You can follow [this link](https://github.com/ziedbentahar/yt-video-summarizer-with-bedrock/blob/main/src/lambda-handlers/generate-model-parameters.ts) for the full code of the generate-model-parameters lambda function.

### 4-  Invoking Claude Model

In this step, we’ll avoid writing custom lambda function to invoke Bedrock API. Instead, we’ll use Step functions direct SDK integration. This state loads from the bucket the model inference parameters that were generated in the previous step:

{% gist https://gist.github.com/ziedbentahar/9bec10d5b0f77005e9785749e6723a30.js %}

**☝️ Note:** As we instructed Claude to generate the response in JSON format, the completion API response misses a leading **{** as Claude outputs the rest of the requested JSON schema.

We use [intrinsic functions](https://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-intrinsic-functions.html) on the state’s ResultSelector to add the missing opening curly brace and to format the state output in a well formed JSON payload :

```
    ResultSelector: {
      "id.$": "$$.Execution.Name",
      "summaryTaskResult.$":
        "States.StringToJson(States.Format('\\{{}', $.Body.completion))",
    }
```

I have to admit, it is not ideal but this helps get by without writing a custom Lambda function.

### 5-  Generating audio from video summary

This step is heavily inspired by this  [previous blog post](https://levelup.gitconnected.com/building-a-serverless-text-to-speech-application-with-amazon-polly-step-functions-and-websocket-56e9871730b7). Amazon Polly generates the audio from the video summary:

{% gist https://gist.github.com/ziedbentahar/3139fe3d7b4f42955fa8ec1183daed44.js %}

Here are the details of synthesize function:

{% gist https://gist.github.com/ziedbentahar/1502dd16a662c71e7496e371b24d3303.js %}

Once the audio generated, we store it on the S3 bucket and we generate a presigned Url so it can be downloaded afterwards.

☝️ **On language detection :** In this example, I am not performing language detection; by default, I am assuming that the video is in English. You can find in [my previous article](https://medium.com/gitconnected/building-a-serverless-text-to-speech-application-with-amazon-polly-step-functions-and-websocket-56e9871730b7) how to perform such a process in speech synthesis. Alternatively, We can also leverage Claude model capabilities to detect the language of the transcript.

### 6- Defining the state machine

Alright, let’s put it all together and let’s take a look at the CDK definition of the state machine:

{% gist https://gist.github.com/ziedbentahar/5129aee60bd39a79253c669da1b9222d.js %}

In order to be able to invoke Bedrock API, we’ll need to add this policy to the workflow’s role (And it’s important to remember granting the S3 bucket read & write permissions to the state machine):

{% gist https://gist.github.com/ziedbentahar/d113dd27b43f6d4e694e2ed240b6dc0b.js %}

## Wrapping up

I find creating generative AI based applications to be a fun exercise, I am always impressed by how quickly we can develop such applications by combining Serverless and Gen AI.

Certainly, there is room for improvement to make this solution production-grade. This workflow can be integrated into a larger process, allowing the video summary to be sent asynchronously to a client, and let’s not forget robust error handling.

Follow [this link](https://github.com/ziedbentahar/yt-video-summarizer-with-bedrock/tree/main) to get the source code for this article.

Thanks for reading and hope you enjoyed it !

## Further readings
[**Put words in Claude's mouth**](https://docs.anthropic.com/claude/docs/put-words-in-claudes-mouth)
[**Anthropic Claude models**](https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-claude.html)
[**What is Amazon Bedrock?**](https://docs.aws.amazon.com/bedrock/latest/userguide/what-is-bedrock.html)