AIエージェント開発日誌 Vol.11 — SAKIに任せろ!エンゲージメント一本化作戦
AIエージェント開発日誌 Vol.11 — SAKIに任せろ!エンゲージメント一本化作戦
日付: 2026年3月5日
セッション: S110
テーマ: SAKI中心のエンゲージメント戦略 + X APIコスト最適化
やったこと
1. SAKI中心エンゲージメント戦略の実装
5つのAIペルソナがそれぞれ勝手にいいねやリツイートをしていたら、X APIの料金が大変なことになる。そこで「選択と集中」の方針で、SAKIを唯一の自動エンゲージメント担当に任命した。
具体的には:
– SAKI: 身内のツイートに自動いいね(100%)+ 引用RT(30%)+ 外部ターゲットへの自動リプライ
– 他4アカウント: 受動的(いいねを受けるだけ、手動運用に切り替え)
2. Cross-Shop エンゲージメントの実現
ここが一番ハマったポイント。SAKIのペルソナは「SAKI用のショップ」に紐づいているが、エンゲージしたいターゲット(占い系アカウント)は「MySpirits用のショップ」に登録されている。つまり、ショップを跨いでターゲットリストを参照する仕組みが必要だった。
解決策: 環境変数ENGAGEMENT_PERSONA_IDSの形式をpersona_id:target_shop_idに拡張。コロン区切りで「このペルソナは、あのショップのターゲットを使って」と指定できるようにした。
3. X API users/meキャッシュ
エンゲージメント処理で毎回GET /2/users/meを呼んでいたのを、メモリキャッシュで一度だけに。地味だが効果的なコスト削減。
やらかしたこと
バグ修正7連発
テスト実行→エラー→修正→デプロイ→テスト…を7回繰り返した。一つ直すと次のエラーが出る、いわゆる「玉ねぎ剥き」状態。
- 変数名ミス:
persona_idsをpersona_entriesに変更したのに、レスポンス生成部分で旧名を参照 → NameError - 存在しないカラム:
is_active、reply_restriction、interaction_countがtarget_accountsテーブルに実は存在しなかった - 存在しないテーブル:
engagement_followsテーブルのDDLが未実行だった(S107で設計だけして放置) - PostgREST NULLの罠:
.neq("column", "value")はNULL行を含めない。PostgreSQLの三値論理に毎回やられる - Cross-shop参照: ターゲット取得はMySpiritsのshop_idを使うが、内部関数に渡し忘れ
教訓
デプロイ前にローカルテストしろ。 毎回Cloud Runにデプロイして本番で確認するのは時間の無駄。ただし今回はローカルに環境変数がなくてSupabase接続できなかったので仕方ない面もある。テスト環境の整備が課題。
教訓
1. PostgRESTのNULL挙動は毎回確認しろ
PostgreSQLではcolumn != 'value'はNULLの行を返さない。これは何度目だ。PostgRESTフィルタを使う前に「NULLの行がどうなるか」を必ず考えること。安全策はPython側でフィルタリングすること。
2. DDLは設計と同時に実行確認しろ
S107で設計したengagement_followsテーブルが3セッション放置されていた。設計書にDDLを書くだけでは不十分。「実行済み」チェックボックスを設計書に入れるべき。
3. 「選択と集中」はコードにも適用される
5ペルソナ全員を自動化するより、1ペルソナに集中した方がデバッグもコスト管理も楽。人間のマーケティング戦略がそのままシステム設計に反映された好例。
エージェントとのやりとりで気づいたこと
今回はユーザー(サヨン)が「阿蘭自体のアカウントを動かすんじゃなくて、SAKIを使って阿蘭に集客する作戦」と明確に戦略を示してくれたおかげで、実装方針がブレなかった。
技術的には可能でも、ビジネス戦略を理解していないと正しい実装はできない。「全ペルソナ均等に自動化」と「1ペルソナに集中」では、コードの構造が全く違う。
Cloud Runへの7回連続デプロイは反省点。各デプロイに3-4分かかるので、合計30分近くがデプロイ待ちに消えた。次回からは可能な限りローカルテスト環境を整備したい。
数字で見るS110
| 指標 | 値 |
|---|---|
| コミット数 | 9(x-growth) |
| 修正バグ数 | 7 |
| Cloud Runデプロイ回数 | 8 |
| テスト成功 | mutual-boost ✓, 外部engagement ✓ |
| 生成されたリプライ | 「占い好きとしてはワクワクします」(by SAKI → @uranainoaika) |