1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【AWS】【できるのか?】AWS無料枠を使って議事録生成を構築してみた

1
Posted at

目的

・AWS構築をして無料枠でどのレベルまで作れるかっていうチャレンジ
・言うて初めてなのでAWS公式の動画を参考に構築してみる
・構築してみて自分なりにどう改善できそうか、アイデア応用までつなげられたらよし
・AWS無料枠があるらしい、お前は?トリコ?
・議事録作成の精度、はそこまで強度は求めない(無料枠なので)
・AWSの各種機能でどんな使い方ができるか、構築方法の基礎を理解するのが今回の主旨
・今回得られた問題点の洗い出しも行う(例えば、音声出力の精度を上げるなら…とか)

※Qiita に記事を書きすぎて画像制限に引っかかったので今回の記事はめちゃ簡素&画像なしになります。

(制限かかった後思い付きでローカルQiita アプリを作成しちまったよ…)

今回参照するシステム

AWSサービスで作る絶品システム
https://www.youtube.com/watch?v=sx9PlmMenmc

AWSのアカウント登録

AWSアカウント作成後、以下の設定を見直すこと

結論

・MFA有効化
・IAM管理者ユーザー作成
・ルートユーザーは普段使わない
・Billing Alert / Budget作成
・リージョンを東京 ap-northeast-1 に固定

セキュリティ(最優先)

① MFA(多要素認証)
ルートユーザーに設定

手順:

右上アカウント名 → セキュリティ認証情報
「MFA」→ 有効化
Google Authenticator などで登録

IAMユーザー作成

Identity and Access Management (IAM)
IAM ユーザーは
アカウント AWS を操作するために長期的な認証情報を持つアイデンティティ
→要はクラウドサーバーで権限をどの範囲まで使わせるか、
作成したユーザーごとに設定するやつ

課金防止

Budget設定
Billing → Budgets
「予算を作成」
月額:5ドル or 1000円
通知設定(80%)

請求アラート
Billing → Preferences
「請求アラート有効化」
CloudWatch連携ON

リージョン固定

ap-northeast-1(東京)

※無料枠で登録したがデフォルトで有効になってる

今回使うサービス有効化

S3
Lambda
Transcribe
Step Functions
Bedrock
SES

S3の追加

S3>パケット>パケットを作成

今回はテスト用なので
「アカウントのリージョナル名前空間」を使用
パケット名は「voicelog」
作成したら「アップロード」で音声ファイルがクラウドストレージに保存される。

Transcribeの追加

強み:文字起こしから話者識別する(これはAWSの強みかも)

音声ファイルをあらかじめ準備しておく
バケット>アップロードから音声ファイルをアップロードする
アップロードが完了>ファイルを選択
S3URLに記載のものがパスになる

今回は録音済み音声を扱うので「通話後分析」>ジョブ指定
言語は「日本語」
入力データ>S3URLを入力
IAMロール>作成
ジョブ設定>デフォで

※エラー
The AWS Access Key Id needs a subscription for the service
→Transcribeがまだ有効化されていない(サブスク登録されてない)
→「通話後分析」は有料でないと利用不可らしい

The AWS Access Key Id needs a subscription for the service
→AWS側で反映がまだ(数分~1時間くらい待機する必要あり?)

※無料プランだと
Transcribeほかでエラーになるのでプランをアプデする必要あり
(無料枠とは…)
こういうの作成に注意書きとかほしい

有料プランに入り替えたら
トランスクリプションジョブ → 作成

言語:ja-JP
入力:S3 URI
形式:mp3 or wav

▼エラー
The S3 URI that you provided points to the incorrect region. Make sure that the bucket is in the ap-northeast-1 region and try your request again.

※S3とリージョンが同じじゃないと上記のエラーになる
なぜかシドニーに自動で振られたらしい
バケットから切り替えとかできないので作り直す
(この辺り面倒)

トランスクリプションのレビュー

無事に作成されると録音が字幕化される
今回のテスト用録音内容↓

話者 0:
え2026年4月24日。え、今日の会議を始めていきたいと思います。えー今回の会議のえー司会進行はえー私Aになります。え会議の議題としては、プロジェクトAについての話し合いとなります。え皆さんよろしくお願いします。え早速Aについて話そうと思うんですが、えBさんどうでしょうか。はい、えーBです。えーBですが、えー今週の進捗としては、プロジェクトの方の進捗、えー予定としてまー無事えー全ての実装は完了した次第になってます。はい。えーテストの会議録音、以上になります。

わざと「あー」とか「えー」とか多用して録音しましたが、
無事に(?)読みにくい文字化ができました。

Lamda

役割:音声アップロード~Transcribeジョブ作成

関数の作成>一から作成

関数名は任意に
※今回は「transcribe-trigger」とした
ランタイム:Python 3.12
関数を作成

.py
import json
import boto3
import urllib.parse
import time

transcribe = boto3.client('transcribe')

def lambda_handler(event, context):
    record = event['Records'][0]
    bucket = record['s3']['bucket']['name']
    key = urllib.parse.unquote_plus(record['s3']['object']['key'])

    job_name = f"{key.replace('/', '-')}-{int(time.time())}"
    file_uri = f"s3://{bucket}/{key}"

    transcribe.start_transcription_job(
        TranscriptionJobName=job_name,
        Media={'MediaFileUri': file_uri},
        MediaFormat='mp3',
        LanguageCode='ja-JP',
        OutputBucketName=bucket
    )

    return {
        'statusCode': 200,
        'body': json.dumps(f"Started job: {job_name}")
    }

コードできたらデプロイ
作成した関数をクリック>設定>アクセス権限>ロール名(青文字リンク)

IAM画面へ遷移する>許可を追加
>ポリシーをアタッチ
AmazonTranscribeFullAccess
AmazonS3FullAccess
↑を追加

S3連携
S3開く
音声アップしてるバケットクリック
上タブ
イベント通知>作成

イベント名:transcribe-trigger
イベントタイプ:PUT
送信先:Lambda
関数:transcribe-trigger

※Lambdaは「IAM」と「S3連携」で動く

テスト
S3に音声ファイルをアップしてみる
※さっきとは別のやつでテストしてみる
(同じ内容だけどファイル名変えて議事録テスト1.m4aをアップ)

今回扱音声ファイルが.m4a形式なので、
S3のコードで音声ファイルの対応関数を修正する

Transcribeのジョブ名は、英数字・ドット・アンダースコア・ハイフンしか使えないので英数字で記入が良

議事録AI要約(Bedrock連携)

音声ファイルをアップ→自動までの字幕化までの連携ができた
JSONファイルのテキストを読み込んで要約させる

新しいLambda作成
名前:summarize-transcript
ランタイム:Python 3.12

.py
import json
import boto3

s3 = boto3.client('s3')
bedrock = boto3.client('bedrock-runtime')

def lambda_handler(event, context):
    record = event['Records'][0]
    bucket = record['s3']['bucket']['name']
    key = record['s3']['object']['key']

    # JSON読み込み
    obj = s3.get_object(Bucket=bucket, Key=key)
    data = json.loads(obj['Body'].read())

    # テキスト抽出
    transcript = data['results']['transcripts'][0]['transcript']

    # プロンプト
    prompt = f"""
以下の会話を議事録として整理してください:

{transcript}
"""

    response = bedrock.invoke_model(
        modelId="anthropic.claude-3-sonnet",
        body=json.dumps({
            "messages": [
                {"role": "user", "content": prompt}
            ]
        })
    )

    result = response['body'].read().decode()

    # 保存
    s3.put_object(
        Bucket=bucket,
        Key=f"summaries/{key}.txt",
        Body=result
    )

    return {"statusCode": 200}

IAM権限の追加
summarize-transcript>設定>アクセス権限
>ロール>IAM画面>許可を追加>ポリシーをアタッチ
AmazonBedrockFullAccess
AmazonS3FullAccess
↑を追加

▼エラー
API レスポンス Configuration is ambiguously defined. Cannot have overlapping suffixes in two rules if the prefixes are overlapping for the same event type.

原因
同じS3バケット内で イベント通知の条件が重複

既存のtranscribe-triggerが

イベント:すべてのオブジェクト作成イベント
プレフィックス:空欄
サフィックス:空欄

↑で設定していたのでサフィックス:.json追加しても対象が重なり拒否
既存の方を

プレフィックス:uploads/
サフィックス:.m4a

↑に修正

Bedrock未開通問題

ResourceNotFoundException (InvokeModel)

初期アカウントではどうやらトークン制限がありAIモデルを利用した会議録の要約機能は使用できなかった。

解決法としては
制限解除まで時間を置くか、リクエストを送り利用上限を上げるか、という方法があるもよう。

今回は、録音をアップ~文字化までは構築できたのでここまでとする。

感想

・結論から言うと、無料枠といっても実際には有料プランへのアップグレード、外部AIのトークン制限解除のために時間を置くなどの方法でないと要約や議事録作成までは構築できない。(タダより高いものはない……)
・録音ファイルのアップロードさえすればあとはAWSで要約からメールへ結果送信まで自動化が可能とわかった

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?