技術スタック
全体の考え方
Jester は次の3つを基本方針として作られています。
| 方針 | 内容 |
|---|---|
| サーバーレス | 常時稼働するサーバーを持たず、必要なときだけプログラムが動く仕組みにすることで、コストと運用負荷を抑える |
| AWS 上に構築 | クラウドサービス(AWS)の機能を組み合わせて、自前でインフラを管理しなくて済むようにする |
| AI ファースト | 記事・ブログの執筆は Amazon Bedrock(AI サービス)に任せ、人手の作業を減らす |
加えて、生成 AI を使ううえでの重要な設計方針があります。
機械にできることは機械がやる
AI に数値の転記や突合をさせると取り違えが起きます。そこで 解釈・突合・転記は機械(コード)が行い、AI は日本語の表現だけを担うという分担にしています。 出走者名や払戻金額はプレースホルダーで公式データから差し込み、生成後も公式データと機械照合します。
AI を支える技術
Amazon Bedrock
AI(生成 AI モデル)が動いている場所です。用途ごとにモデルを使い分けています。
| 用途 | モデル | 理由 |
|---|---|---|
| レース動画・コース画像の解析 | Amazon Nova Pro | 動画入力に対応しているため |
| 記事・ブログの執筆 | Claude Sonnet(未設定時は Nova Pro にフォールバック) | 日本語のテキスト生成が中心のため |
| サムネイル位置の選定 | Amazon Nova Pro | レース動画を解析するため |
| 埋め込みベクトルの生成 | Titan Text Embeddings v2 | 関連ブログの類似検索に使うため |
LangGraph
AI を「エージェント」として組み立てるためのライブラリです。 エージェントとは、決められた手順を上から順に実行するのではなく、 AI 自身が「次に何をすべきか」を判断し、必要な道具(ツール。例: レース動画の解析)を 自律的に使いながらゴールまで進む仕組みです。
Jester では、レース総合解析(動画・コース画像・レース結果の統合)と サムネイル位置の選定の2つをエージェントとして構築しています。 記事・ブログの執筆はツールを使わないテキスト処理のため、エージェントではなく単発の構造化出力呼び出しです。
プログラムが動く場所
AWS Lambda
「必要なときだけ起動する小さなプログラム」を動かす AWS の仕組みです。 常時稼働のサーバーを用意しなくて済むため、使った分だけ料金がかかり、無駄がありません。
Jester には現在 7 種類の Lambda があります。
| Lambda | 言語 | 役割 |
|---|---|---|
App Lambda(odds_poc_app) |
Python | 管理画面からのリクエストを受け付ける Web API |
| article_generation | Python | レース結果10秒サマリーを AI で執筆する |
| article_builder | TypeScript | 生成された記事データを React コンポーネントで HTML 化してデータベースに保存する |
| blog_generation | Python | レース回顧・予想ブログを元記事なしで書き下ろす |
| blog_rewriter | Python | 過去のブログ記事を内容を変えずにリライトする |
| blog_builder | TypeScript | ブログ本文を記事テンプレートへ流し込んで HTML 化し、データベースに保存する |
| thumbnail_generation | Python | レース動画から AI が選んだ瞬間のフレームを切り出してサムネイルにする |
Amazon API Gateway
外部からの Web リクエストを受け付ける「玄関口」です。 ここで受けたリクエストを App Lambda に渡します。
データを保存する場所
Amazon DocumentDB
記事・ブログ・レース情報などを保存する データベースです。 MongoDB という有名なデータベースと互換性があり、JSON のような柔軟な形式でデータを扱えます。
Amazon S3
画像・動画・ファイルなどの 大きなデータを保存する倉庫です。 レース動画・コース画像・アップロードされたメディア・生成されたサムネイル画像はここに保存されます。
Amazon CloudFront
S3 バケットは非公開のため、ブラウザから画像を参照できるようにする 配信の窓口です。 サムネイル画像は CloudFront 経由の URL でブログ本文に埋め込まれます。
プログラム同士をつなぐ仕組み
Amazon SQS(メッセージキュー)
Lambda 同士が直接やり取りせず、「やってほしいこと」を一時的に置いておくポストのような役割を果たします。
たとえば App Lambda が「この記事を生成して」と SQS に依頼を入れると、article_generation Lambda が
それを受け取って処理します。生成が終わると、生成結果を別のポスト(article-builder キュー)に入れ、
article_builder Lambda がそれを受け取って記事 HTML を組み立て、データベースに保存します。
これにより、
- 一度に大量のリクエストが来ても、Lambda が順番に処理できる
- 何かのエラーで処理が失敗しても、自動で再試行できる
といったメリットがあります。
最終試行かどうかで挙動を変える
再試行にも上限があります。Jester では、その上限に達した「最終試行」で失敗したときだけ、
生成途中で止まったレコードを片付けます(記事は failed として理由を残し、ブログは削除する)。
1回目の失敗で片付けてしまうと、一時的なエラーからの自己復旧ができなくなるためです。
VPC(仮想プライベートネットワーク)
AWS 内に作る 「自分たちだけが使える専用エリア」です。 データベースや Lambda はこの中に配置されているため、外部から直接アクセスされず安全です。
プログラムを書くための言語
Python
バックエンドは基本的に Python(バージョン 3.12)で書かれています。 AI 開発・データ処理・Web API の分野で広く使われており、ライブラリも豊富なため採用しています。
TypeScript / Node.js(article_builder・blog_builder)
記事・ブログの HTML 組み立てには、React コンポーネントを使います。
とくに blog_builder は、デザイン側のリポジトリ(oddspark-static-pages)の
実コンポーネント・実 SCSS をそのままバンドルして描画します。
そのためこの2つの Lambda だけは TypeScript(Node.js 22)で実装します。
| 名前 | 役割(ざっくり) |
|---|---|
| React / react-dom | コンポーネントを HTML の文字列に変換する道具(renderToStaticMarkup) |
| zod | 受け取ったメッセージの形式が正しいか検査する道具 |
| esbuild / sass | デプロイ時にコンポーネント・スタイルを1つのファイルにまとめる道具 |
| mongodb | DocumentDB へデータを読み書きするための公式ドライバ |
使用している主な部品(ライブラリ)
| 名前 | 役割(ざっくり) |
|---|---|
| FastAPI | Web API を作るためのフレームワーク(App Lambda で使用) |
| Pydantic / pydantic-settings | データの形式(型)が正しいか自動でチェックする仕組み・環境変数の管理 |
| Beanie / Motor | DocumentDB へデータを読み書きするための道具(Python 側) |
| LangGraph / langchain-aws | AI をエージェントとして組み立てる道具 |
| boto3 | AWS の各サービス(S3 / SQS / Bedrock など)を Python から操作する道具 |
| Mangum | FastAPI を Lambda 上で動かすための変換アダプタ |
| pyahocorasick | NG ワードを高速に検査する道具 |
| ffmpeg / ffprobe | 動画の長さを調べ、指定した瞬間のフレームを切り出す道具 |
開発の品質を守る道具
ソースコードの品質を一定に保つため、自動チェック用のツールを使っています。
| ツール | 何をしてくれるか |
|---|---|
| ruff | コードの書き方(スタイル・改行・誤った書き方)を自動で検査・整形する |
| mypy | データの型(種類)の食い違いを事前に検出する |
| uv | プログラムが使う部品(ライブラリ)の管理・インストールを自動で行う。ワークスペースで複数アプリをまとめて管理する |
| mise | 開発者ごとに Python のバージョンが揃うように管理する |
| ESLint / tsc | TypeScript 側のコード検査・型チェック |
これらは「バグを未然に防ぐためのセーフティネット」として働き、開発者が気づかないミスを自動で見つけてくれます。
用語ミニ辞典
| 用語 | 意味 |
|---|---|
| サーバーレス | サーバーを自分で用意・管理せず、クラウドの仕組みに任せる方式 |
| Lambda | 必要なときだけ起動する小さなプログラムを動かす AWS の仕組み |
| キュー | やってほしい作業を順番待ちさせるための「ポスト」のような仕組み |
| DLQ | 何度試しても処理できなかったメッセージを退避させる専用のキュー |
| API | プログラム同士がやり取りするための窓口 |
| データベース | 構造化されたデータ(記事・レース情報等)を保存する仕組み |
| ストレージ | 画像・動画などの大きなファイルを保存する仕組み |
| ライブラリ | 既に作られた便利な機能を集めた「部品集」 |
| フレームワーク | アプリケーションの土台になる仕組み・骨組み |
| 埋め込みベクトル | 文章の意味を数値の並びで表したもの。近さを測ると「似た記事」が探せる |
| SSR | サーバー側でコンポーネントを HTML に変換すること |