Amazon bedrockのSample serverless-pdf-chatを日本リージョンで動かしてみた

## はじめに
部内のナレッジをRAGで活用しようと思い、まずはRAGの理解深耕とBedrockがGAされたこともありaws sampleから試してみました。
今回は下記を用いて実施しています。
https://github.com/aws-samples/serverless-pdf-chat

FrontendはClientPCで動作させるので下記のようなイメージになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922657/dd716d4a-7f82-30be-85e0-e90789a7d84f.png)

## リージョンをap-northeast-1にする
GitのREADMEに以下のように記載があるので、従って修正します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922657/552f96db-75f0-76ff-389f-fe9d345aca84.png)

東京リージョンでもClaude-v2はGAされていますが、利用開始には企業情報入れたりと面倒だったので、、、今回はTitan Text G1 - Expressを利用します。

SourceをGitから持ってきます。
※pythonをインストールする関係上、CloudShellの容量(1GB)では足りなくなるため、`/tmp`にて実施しています。
```bash
cd /tmp
git clone https://github.com/aws-samples/serverless-pdf-chat.git
```

下記のように書き換えています。

- backend/src/generate_embeddings/main.py
```diff_python
    bedrock_runtime = boto3.client(
        service_name="bedrock-runtime",
-       region_name="us-east-1",
+       region_name="ap-northeast-1",
    )

    embeddings = BedrockEmbeddings(
        model_id="amazon.titan-embed-text-v1",
        client=bedrock_runtime,
-       region_name="us-east-1",
+       region_name="ap-northeast-1",
    )
```
- backend/src/generate_response/main.py
```diff_python
    bedrock_runtime = boto3.client(
        service_name="bedrock-runtime",
-       region_name="us-east-1",
+       region_name="ap-northeast-1",
    )

    embeddings, llm = BedrockEmbeddings(
        model_id="amazon.titan-embed-text-v1",
        client=bedrock_runtime,
-       region_name="us-east-1",
+       region_name="ap-northeast-1",
    ), Bedrock(
-       model_id="anthropic.claude-v2", client=bedrock_runtime, region_name="us-east-1"
+       model_id="amazon.titan-text-express-v1", client=bedrock_runtime, region_name="ap-northeast-1"
    )
```
- backend/template.yaml
```diff_yaml
  GenerateResponseFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: src/generate_response/
      Timeout: 30
      MemorySize: 2048
      Policies:
        - DynamoDBCrudPolicy:
            TableName: !Ref MemoryTable
        - S3CrudPolicy:
            BucketName: !Ref DocumentBucket
        - Statement:
            - Sid: "BedrockScopedAccess"
              Effect: "Allow"
              Action: "bedrock:InvokeModel"
              Resource:
-               - "arn:aws:bedrock:*::foundation-model/anthropic.claude-v2"
+               - "arn:aws:bedrock:*::foundation-model/amazon.titan-text-express-v1"
                - "arn:aws:bedrock:*::foundation-model/amazon.titan-embed-text-v1"
```

## AWS Serverless Application Model(SAM) CLI
FrontendはClientPCから実行していますが、SAM CLIについてはCloudShellにて実行しています。

### python 3.11準備
SAM CLIでBuildが必要で、BuildのためにはCloudShell環境にPython 3.11が必要になるため、以下を実施します。

```bash
sudo dnf install gcc zlib-devel bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel xz-devel
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
source ~/.bashrc
pyenv install 3.11.6
```

インストールされたことを以下で確認します。
```bash
pyenv global 3.11.6
pyenv rehash
pyenv versions
python -V
```

### SAM CLI実行
Gitに記載の手順に従い、まずはBuildします。
```bash
cd serverless-pdf-chat/backend
sam build
```

Buildが完了次第、デプロイしていきます。
```bash
sam deploy --guided
```
下記のように入力項目に対応していきます。
```bash
        Setting default arguments for 'sam deploy'
        =========================================
        Stack Name [sam-app]: serverless-pdf-chat
        AWS Region [ap-northeast-1]: 
        Parameter Frontend [local]: 
        Parameter Repository []: 
        #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
        Confirm changes before deploy [y/N]: y
        #SAM needs permission to be able to create roles to connect to the resources in your template
        Allow SAM CLI IAM role creation [Y/n]: 
        #Preserves the state of previously provisioned resources when an operation fails
        Disable rollback [y/N]: 
        Save arguments to configuration file [Y/n]: 
        SAM configuration file [samconfig.toml]: 
        SAM configuration environment [default]: 
```

デプロイが成功すれば、以下のようになります。

```bash
CloudFormation outputs from deployed stack
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Outputs                                                                                                                                                                               
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Key                 CognitoUserPool                                                                                                                                                   
Description         -                                                                                                                                                                 
Value               ap-northeast-1_***********                                                                                                                                          
 
Key                 CognitoUserPoolClient                                                                                                                                             
Description         -                                                                                                                                                                 
Value               *************************                                                                                                                                        
 
Key                 ApiGatewayBaseUrl                                                                                                                                                 
Description         -                                                                                                                                                                 
Value               https://*********.execute-api.ap-northeast-1.amazonaws.com/dev/                                                                                                  
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
```

## Frontendの実行
ClientPC側でもGitをcloneします。
```bash
git clone https://github.com/aws-samples/serverless-pdf-chat.git
cd serverless-pdf-chat/frontend
```

Gitに記載の手順に従い、Frontendを起動していきます。
まずは`.env.development`ファイルをfrontendディレクトリ内で作成します。

```
VITE_REGION=ap-northeast-1
VITE_API_ENDPOINT=https://*********.execute-api.ap-northeast-1.amazonaws.com/dev/
VITE_USER_POOL_ID=ap-northeast-1_***********
VITE_USER_POOL_CLIENT_ID=*************************
```

依存関係をインストールしていきます。
```bash
npm ci
```

完了したらFrontendを起動します。
```bash
npm run dev
```

起動が完了すると、以下が表示されます。
```bash

> frontend@0.0.0 dev
> vite


  VITE v4.5.2  ready in 1069 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h to show help
```
アクセスすると以下のように表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922657/5cba9f87-a49d-3f4a-a654-556ee4fd807b.png)

## serverless-pdf-chatのお試し
ユーザ認証のため、Cognitoでユーザを作成します。
SAMで作成したユーザプールが存在しているため、そのユーザプールに対してユーザを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922657/926788b3-54f0-d804-0b69-c77b925891a2.png)

ログインすると、以下のように表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922657/9371a3b4-b598-0b18-c6ad-a99ef994b507.png)

ドキュメントをアップロードしていくと、My　documents以下にアップロードしたドキュメントが一覧で表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922657/6158d2a5-f8f2-9c82-1809-6fb0ab8ee567.png)

ドキュメントにアクセスすることで、ドキュメントに対してChatしていくことができます。
お試しなので、このぐらいで。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922657/d62b6ac2-a306-8788-675e-9d899a12efd0.png)

## おわりに
今回はSampleを利用してRAGってどんな感じ？Bedrockってどんな感じ？を触って確かめてみました。
今後は下記を参考にチューニングパラメータ触ってみたり、ドキュメント1つをFAISSでVector化しているので、複数ドキュメントを1つに纏めてRAG構成したりを試してみようと思っています。
https://docs.aws.amazon.com/ja_jp/bedrock/latest/userguide/model-parameters-titan.html

## (おまけ)AWS側を簡単に確認
### DynamoDB
ユーザIDとドキュメントIDに紐づいたセッション情報(`conversationid`)をドキュメントテーブルとして保持している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922657/0c4bea8b-e01e-e1b2-f64f-165f4f9672bb.png)
セッション情報(`conversationid`)を元にChat履歴を保持している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922657/de993619-7870-0258-52c5-898020164954.png)

### Lambda
SAMで作成された関数が確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922657/9ae6ae5d-f997-141e-3ba7-862a1a82256f.png)
デフォルトだとEmbeddingのタイムアウトも3秒のため、ファイルサイズによっては失敗する。そのため、タイムアウト時間を3秒から3分に変更している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922657/ab5a0081-ac07-af52-6766-5abd12f152ef.png)

### API Gateway
SAMで指定した通りに作成されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922657/b94b337a-4840-14cc-90af-aa33bfc1b042.png)

### CloudWatch
Lamdbaで実行された関数の情報が見れる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922657/61673866-861b-b1e2-51c2-f6b20b858ef3.png)