【第7回】AI記事作成 イベント駆動型マルチエージェントへ発展させる

スポンサーリンク
この記事は約44分で読めます。

第7回では、これまで順番に実行していたAI記事作成フローを、イベント駆動型の考え方で整理します。
Reviewer AIのJSON判定やPython側HTMLチェックの結果を status として扱い、
article.revision_required、validation.failed、article.approved などのイベントに変換します。
これにより、AIエージェント同士の処理を追跡しやすくなり、将来的なDispatcher実装や正式なイベント駆動システムへ発展させやすくなります。

第6回AI記事作成まででできたこと

第6回AI記事作成では、Planner AI、Writer AI、Reviewer AIに加えて、Researcher AI を追加しました。

Researcher AIは、記事を書く前に検索クエリを作成し、Brave Search APIを使ったWeb検索MCP風ツールから検索結果を受け取り、Writer AIへ渡す調査メモを作成しました。

これにより、ローカルLLMだけでは不足しやすい最新情報を、記事作成フローに取り込めるようになりました。

第6回AI記事作成までの流れは、次のような順番実行型です。

Planner AI
↓
Researcher AI
↓
Writer AI
↓
Reviewer AI
↓
Python側HTMLチェック
↓
保存

この形は分かりやすく、学習にも向いています。
ただし、エージェントが増えるほど、main.py が大きくなりやすいという問題があります。
そこで第7回AI記事作成では、処理を イベント駆動型 の考え方で整理します。

イベント駆動型とは

イベント駆動型とは、簡単にいうと、何かが起きたら、それに応じて次の処理を実行する仕組みです。

これまでの処理では、main.py が順番に各処理を呼んでいました。

main.pyが順番に呼ぶ
↓
Planner AI
↓
Researcher AI
↓
Writer AI
↓
Reviewer AI
↓
Validator
↓
保存

イベント駆動型では、処理結果をイベントとして扱います。

イベント駆動型マルチエージェント処理の流れ
plan.created
↓
research.completed
↓
draft.created
↓
review.completed
↓
validation.completed
↓
article.approved
↓
article.saved

つまり、処理を単なる順番ではなく、状態の変化として見る考え方です。

イベント駆動型にする理由

イベント駆動型にする理由は、マルチエージェント構成が大きくなったときに管理しやすくするためです。

第6回までの構成では、main.py が多くの判断を持っています。

・次にどのAIを呼ぶか
・レビュー結果がOKか
・修正が必要か
・HTMLチェックが通ったか
・保存するか
・最大レビュー回数に達したか

この判断が増えると、main.py が複雑になります。

イベント駆動型では、次のように整理します。

何が起きたか
↓
どのeventか
↓
statusは何か
↓
次に実行する処理を決める

たとえば、Reviewer AIがOKを出した場合は、次のように考えます。

review.completed
↓
status = OK
↓
Validatorへ進む

一方で、Reviewer AIが修正必要と判断した場合は、次のようになります。

review.completed
↓
status = REVISION_REQUIRED
↓
Writer AIへ戻して修正

第5回AI記事作成のJSON判定の利用

第7回AI記事作成で重要になるのが、第5回で実装したReviewer AIのJSON判定です。

第5回では、Reviewer AIの自然文レビューとは別に、次のようなJSONを出力させました。

この status と next_action は、イベント駆動型にそのまま使えます。

status: OK
↓
article.approved

status: REVISION_REQUIRED
↓
article.revision_required

status: UNKNOWN
↓
review.failed

つまり、第5回でJSON化したことは、第7回でイベント駆動型へ進むための準備だったといえます。

第7回AI記事作成で使うイベント例

第7回では、まず次のようなイベントを使います。

plan.created
research.completed
draft.created
draft.revised
review.completed
article.revision_required
validation.completed
validation.failed
article.approved
article.saved

それぞれの意味は次の通りです。

イベント名意味
plan.createdPlanner AIが記事設計を作成した
research.completedResearcher AIが調査メモを作成した
draft.createdWriter AIが初稿を作成した
draft.revisedWriter AIが修正版を作成した
review.completedReviewer AIがレビューを完了した
article.revision_requiredReviewer AIにより修正が必要と判断された
validation.completedPython側チェックが完了した
validation.failedPython側チェックで問題が見つかった
article.approved記事が公開可能と判断された
article.saved最終記事が保存された

このようにイベント名を決めておくと、あとから処理を追加しやすくなります。

修正ループは2種類ある

第7回AI記事作成では、修正ループを2種類に分けて考えます。

2種類の修正ループを表すフロー

1つ目は、Reviewer AI起点の修正ループです。

Writer AI
↓
Reviewer AI
↓
修正必要
↓
Writer AIへ戻す

Reviewer AIは、主に次のような観点を見ます。

・記事構成
・読みやすさ
・SEO観点
・トーン
・内容の不足
・検索意図とのズレ

2つ目は、Validator起点の修正ループです。

Writer AI
↓
Reviewer AI
↓
OK
↓
Validator
↓
問題あり
↓
Writer AIへ戻す

Validatorは、主に次のような機械的・形式的な問題を見ます。

・HTML断片として正しいか
・styleタグやscriptタグがないか
・Markdown記法が残っていないか
・pタグやh2タグがあるか
・プレースホルダーが残っていないか
・不自然なHTMLタグがないか

つまり、第7回では次のように整理できます。

Reviewer AI
→ 内容の改善点を返す

Validator
→ 形式・構造の改善点を返す

Writer AI
→ 両方の指摘を受けて修正する

処理の流れをイベントで置き換える

イベント駆動型マルチエージェントに向けて、第6回AI記事作成までの流れをイベントを使って置き換えます。

処理の流れをイベントで置き換える

第6回AI記事作成までの流れは、次のような順番実行型でした。

1. Planner AIが記事設計を作る
2. Researcher AIが調査メモを作る
3. Writer AIが記事を書く
4. Reviewer AIがレビューする
5. Python側HTMLチェックをする
6. OKなら保存する

第7回AI記事作成では、これをイベントとして実行します。

plan.created
↓
research.completed
↓
draft.created
↓
review.completed
↓
validation.completed
↓
article.approved
↓
article.saved

修正が必要な場合は、次のようになります。

draft.created
↓
review.completed
↓
article.revision_required
↓
draft.revised
↓
review.completed
↓
validation.completed
↓
article.approved
↓
article.saved

Validatorで問題が出た場合は、次の流れです。

review.completed
↓
status = OK
↓
validation.completed
↓
validation.failed
↓
draft.revised
↓
review.completed
↓
validation.completed
↓
article.approved
↓
article.saved

このようにイベントとして整理すると、記事作成の流れを「状態遷移」として追跡できます。

第7回AI記事作成 ファイル構成と追加・変更ファイル

第7回AI記事作成のファイル構成

第7回AI記事作成で追加するファイル

event_types.py

イベント名をまとめるためのファイルです。

役割:
・イベント名を定数として管理する
・plan.created などの文字列のタイプミスを防ぐ
・main.py からイベント名を呼び出しやすくする

主なイベント名は以下です。

PLAN_CREATED
RESEARCH_COMPLETED
DRAFT_CREATED
DRAFT_REVISED
REVIEW_COMPLETED
ARTICLE_REVISION_REQUIRED
VALIDATION_COMPLETED
VALIDATION_FAILED
ARTICLE_APPROVED
ARTICLE_SAVED

event_types.py

イベント名を定義するファイル。

event_bus.py

イベントを記録するためのファイルです。

役割:
・処理の節目で event を発行する
・event / status / payload を記録する
・最後に event_log.json として保存できる形にする

第7回AI記事作成では、正式なイベントキューや非同期処理をつくりません。

event_bus.pyをイベント履歴を記録する簡易EventBus として使います。

event_bus.py

イベントを記録するファイル。

第7回AI記事作成で変更するファイル

main.py

第7回で最も大きく変更するファイルです。

変更内容:
・EventBusを読み込む
・event_types.py のイベント名を読み込む
・Planner完了時に plan.created を記録する
・Researcher完了時に research.completed を記録する
・Writer初稿作成時に draft.created を記録する
・Writer修正時に draft.revised を記録する
・Reviewer完了時に review.completed を記録する
・Reviewerが修正必要なら article.revision_required を記録する
・Validatorチェック完了時に validation.completed を記録する
・Validatorで問題があれば validation.failed を記録する
・記事がOKなら article.approved を記録する
・保存完了時に article.saved を記録する
・event_log.json を保存する

第7回では、main.py が ディスパッチャー相当 の役割も持ちます。

event_bus.py
→ イベントを記録する

main.py
→ event / status を見て次の処理を決める

main.py

第6回AI記事作成の処理に、event_bus.py と event_types.py を追加して、各処理の節目で event_log.json にイベントを記録する構成です。

agents/researcher.py

出力が日本語以外になる場合のを修正。

agents/researcher.py

第7回AI記事作成で追加される出力ファイル

第7回では、実行結果フォルダに以下が追加されます。

第7回AI記事作成の実行結果

ターミナル出力

(UTF-8)

(SHIFT-JIS)

出力記事

(UTF-8)

(SHIFT-JIS)

event_log.json

(UTF-8)

(SHIFT-JIS)

イベント駆動型マルチエージェント実装範囲

第7回のイベント駆動型マルチエージェントでは、正式なDispatcherや非同期イベントキューまで実装しません。

第7回のイベント駆動型マルチエージェントでの実装範囲は以下の様になります。

実装する機能:
・イベント名を定義する
・イベントを記録する
・event_log.json に保存する
・main.py の分岐をディスパッチャー相当として扱う

実装しない機能:
・dispatcher.py の分離
・本格的なEvent Queue
・非同期処理
・ワーカー実行
・リトライ制御

つまり、第7回の追加・変更は最小限で、イベント駆動型の考え方を現在のマルチエージェント記事作成システムに導入する回です。

まとめ:イベント化するとAIエージェントの流れが見える

第7回AI記事作成では、これまで順番に実行していたAI記事作成フローを、イベント駆動型の考え方で整理しました。

第5回でReviewer AIの判定をJSON化し、第6回でResearcher AIとWeb検索MCP風ツールを追加しました。

第7回では、その結果を event と status で扱います。

Reviewer AIがOK
↓
review.completed
↓
validation.completed

Reviewer AIが修正必要
↓
article.revision_required
↓
Writer AIへ戻す

Validatorが問題を検出
↓
validation.failed
↓
Writer AIへ戻す

このように、処理の節目をイベントとして記録することで、どこで何が起きたかを追いやすくなります。

第7回は、ローカルAIマルチエージェント記事作成システムを、状態を持つエージェントシステムへ変更する回でした。

今回のイベント駆動型では、ディスパッチャー部分は main.py 内の status 判定と分岐処理になります。

今後、本格的にイベント駆動型にする場合は、ディスパッチャー部分をmain.pyから分離してDispatcherでイベント振り分けをする必要があります。

Dispatcherを実装したイベント駆動型マルチエージェント

Dispatcherを実装したイベント駆動型マルチエージェントの処理フロー図