Introduction みなさんこんにちは、私はMax Nechaevです - Snoonuのエンジニアリングマネージャー、創設者、AI愛好家です. 私はしばらくソフトウェア開発に携わってきました. 僕がiOSアプリを構築していたとき、そこには多くのアーキテクチャパターンがありました。 しかし、解決策に到達する前に、問題について話しましょう。 現在、AIは狂ったハイプサイクルを経ています。スタートアップは毎日出現し、死んでいます。ますます多くの人々はMake、n8n、その他のような低コードおよびノンコードツールに潜入しています。そしてあなたは何を知っていますか? 私はそれが素晴らしいと思います。 何百万人もの人々が新しい現実に踏み込んでいます。 インターネットの初期の日々のように感じます、ウェブサイトが静的からインタラクティブに移ったとき、突然何でも可能だと感じました。 より多くの人々がAIエージェントを構築しています。そして私はそれを愛しています。しかし、捕獲があります. 柔軟でスケーラブルなAIシステムを構築する方法についての共有された理解はまだありません. 実際のデザインパターンはありません. 広く採用された構造はありません. 振動だけです。 周りを見回すほど、n8nで作られたエージェントはスパゲッティのように見えます 読み取り、デバッグ、またはスケールすることは不可能です パイソンのビルディングエージェントに関するチュートリアル? 同じストーリー すべてが1つのファイルに投げ込まれ、懸念の分離はありません 確かに、経験豊富な開発者は、物事を分割するべきだと知っているかもしれませんが、初心者はそうではありません。 だから今日は、私が頼りにしたソリューションをシェアしたいです. これが私のAIシステムを構築する方法です. 責任を分離する方法. 物事を柔軟に、スケーラブルにし、実際に健全に保つ方法です. 私のフレームワーク、デザインパターン、またはアーキテクチャを紹介します - あなたが望むように呼んでください - エージェント・アクション・チェーン AAC Meet AAC (Agent Action Chains) もし、混沌が繰り返し繰り返し起こるなら、それは偶然ではないかもしれないし、それはシステムが欠けていることを意味するかもしれない。 そこで、私は実験を始めた。最初に、n8nの内部のブロックで、私は手動で論理を分離し始めました - ここで私は入力を処理する場所、ここで私は処理を行う場所、ここでコアの論理です。 そこでAAC(エージェント・アクション・チェーン)が生まれた。 それはドキュメントの1000ページを持つ別のフレームワークではありません。 AACは、成人したエンジニアのようにAIシステムを構築する方法であり、物事をまとめて最善を望むような人ではない。 コアアイデアは? 私はシステムを明確な役割を持つエージェントに分けました. 各エージェントは正確に一つのことをします. 彼らはすべてJSON契約を通じて話します - 推測なし,魔法なし,混乱なし. すべてが予測可能で、スケーラブルで、デバッグしやすくなります。 チームとして考えてみてください。 1 入力手順 他のデータ処理 3つ目は、次に何をすべきかを決めることです。 もう一人のエージェントが記憶に語りかける。 1 失敗を捕まえる もう一人は、すべてを監視し、記録する。 誰もが自分の仕事を知っているし、システムはスイスの時計のように動いている。 AACの美しさは、プラットフォームアゴニストであること、n8nで実装できます。 , in Python using FastAPI, even inside LangChain or LangGraph if you take the time to set up it properly. パイソンでは、FastAPIを使用して、LangChainやLangGraphの内部でさえ、適切に設定するのに時間がかかりました。 Make.com より Here’s How It Works (In Plain English) 混沌としたグループではなく、誰もがすべてを一度にやっているチームですが、それぞれが自分の仕事を知り、自分のスペースを所有し、明確な結果を提供するチームです。 それこそが、AACの働き方です。 入力がシステムに到達するとき - ユーザーからまたは外部サービスから - まず、ドアを開けてオフにするエージェントを通過します。その後、基本的な処理が来ます。 我々は結論に焦らない。 まず、我々は入力を構成し、騒音をきれいにし、それを正常化します。 それだけのステップは、道路のデバッグの時間を節約します。 クリーンな入力は、建築の半分です。 次に、オーケストラがやって来ます。それはシステムの脳です。それはタスクそのものを実行しません。代わりに、誰が何をすべきか、どの順序で、どのパラメータで行うべきかを計算します。 その後、専門家が担当します。これらのエージェントは集中しています。一人は分類し、もう一人は概要し、三人は外部データを取得します。それぞれは明確な目的を持っています。彼らは重複しません、彼らは責任を争いません、彼らは互いの出力を書き換えません。あなたはそれらを交換し、改善し、再利用することができます - 良いソフトウェアモジュールのように。 システムが何かを記憶する必要があるとき、メモリが役割を果たします. それは自身のエージェントです. それはすべてを盲目的に保存しません. 代わりに、それは正しいタイミングで正しいものを回収する方法を知っています - 以前の会話、ユーザーの文脈、内部の事実. これがあなたのシステムが金魚であることをやめ、本当のアシスタントのように行動し始める方法です。 エラー処理は同様に真剣に扱われます。AACには、そのための専用のエージェント - ガードが含まれています。それは失敗を監視し、例外を捕らえ、何かが壊れたときの行動を取ります。それはパッチではなく、ランダムなトライ・キャッチではありません。それはアーキテクチャの本当の部分です。そして抵抗性の責任があります。 これらすべてが起きている間、オブザーバーは静かに監視しています. それは各エージェントが何をしているか、どのくらいの時間がかかるか、どのような決定が行われているかを追跡しています. 楽しくだけでなく - これはあなたにシステムへの可視性を提供します。 効いたので、 どこで失敗したのか、どこで失敗したのか どう なぜ そして最後に、連鎖全体が仕事を終えたとき、結果はフォーマットされ、ユーザーに返され、API応答に戻り、あるいはどこへ行く必要があるかで送信されます。 それはAACであり、機能するだけでなく、進化し、拡大し、コントロールされているように構築されたシステムです。 All AAC Roles: Who Does What and Why It Matters AACは責任の明確な分離に基づいて構築されています。各エージェントは単なる技術的なブロックではなく、定義された役割とコミュニケーション契約を持つ論理的なユニットです。このセクションでは、これらの役割が何のためにあるのか、どのように相互作用するのか、そしてなぜそれらのうちの1つを飛び越えることが、しばしば後で建築的な痛みにつながるのかを解説します。 Ingress Agent: the Entry Point 入力する信号を処理する。 Purpose: これはウェブハック、フォーム提出、テレグラムメッセージ、カフカイベントかもしれません - それは本当に重要ではありません。 なぜか? 統合層と論理を組み合わせることは、モノリットを構築するための最初のステップだからです。 n8n では、これは通常単に Webhook ノードで、リクエストを受け取り、データをログし、クリーン JSON パイロードをシステムに送信します。 例(仮想コード): { "source": "user", "payload": { "message": "I’d like to return my order" } } Preprocessing Agent: the Filter and Normalizer 原材料を有用なものに変える。 Purpose: このエージェントは騒音を浄化します。それはキャッシングを修正し、奇妙なシンボルをストリップし、構造を検証し、キーフィールドを抽出します。 多くの人がプレプロセッサを省略します。大きな間違いです。それは単に「いいこと」ではありません - それは基礎です。 特にあなたがLLMを扱っているとき、文脈衛生はすべてです。 一つの混乱した入力と全体の推論チェーンは崩壊することができます。 n8n では、これは通常機能ノードです。 コードでは、ミドルウェア、トレーダー、または小さなユーティリティクラスかもしれません。 const cleanInput = input.message.trim().toLowerCase() Orchestrator Agent: the Brain of the System 何が起こるべきかを決める。 Purpose: オーケストラは仕事を自分で行うのではありません。その仕事は、計画し、委任し、監視することです。 掃除された入力を取り出し、ユーザーの意図を明らかにし、適切な専門エージェントをアクティベートします。 シンプルなケースでは、これは単に if/else ブロックかもしれません。より高度なセットアップでは、慎重に設計されたプロンプトで実行される完全な LLM です。例えば、GPT-4 は JSON で構造化された実行計画を返すことができます。 { "steps": [ {"agent": "Classifier", "input": {...}}, {"agent": "Memory", "input": {...}}, {"agent": "Responder", "input": {...}} ] } 利用可能なエージェントのリストを渡し、最善の道を選択することもできます。 主なアイデアは、オーケストラが問題を解決するのではなく、ルートを構築し、誰が何をすべきか、どの順序で決めるかである。 Specialist Agents: Focused Experts (TOOLS) 単一で明確な任務を果たすこと。 Purpose: これらのエージェントは、全体の問題を解決するためにここにいません - 単にその特定の部分を解決し、それをうまく行います。 リクエストの分類 生成回答 抽出団体 外部 API の呼び出し テキスト翻訳 それぞれが別々の機能、クリーンモジュール、またはn8nのサブフローです。それこそがシステムを柔軟かつスケーラブルにします。新しい機能を追加したいですか?新しい専門家を作成して登録するだけです。オーケストラは書き直す必要はありません - このツールが存在することを知るだけです。 オーケストラと専門家の間の契約の例: { "agent": "Classifier", "input": { "text": "My order never arrived" }, "output_expected": { "label": "delivery_problem" } } Memory Agent: the Interface to the Past 適切な文脈を提供する。 Purpose: このエージェントは、データベース、ベクトルストア、Redisキャッシュをクエリします - あなたが持っているものは何でも - そして、必要なものを正確に返します。 システムのメモリとして考えて、ユーザーの過去のオーダーを取得したり、知識ベースからベクトルインベーディングをマッチしたり、以前の相互作用をキャプチャしたりすることができます。 AAC では、メモリは常に独自のものなので、それをスケールしたり、キャッシュしたり、複数のシステムに接続したりすることができます。 SELECT * FROM orders WHERE user_id = "user_42" ORDER BY created_at DESC LIMIT 3 Guard Agent: Protection from Chaos 失敗を捕まえて対処する。 Purpose: 専門家が故障した場合、またはオーケストラが故障した場合、警備員はエラーをログし、警告を送信し、選択肢として、別のエージェントと再起動するか、安全なデフォルト応答を返すように、バックバックロジックを実行します。 生産においては、この役割は交渉不能です。エラーが発生します。GPTはゴミを返す可能性があります。APIはタイムアウトかもしれません。あなたは物事が横行するときに何をすべきかを知っている層が必要です。 例: GPT は無効な JSON を返します. ガードはそれを捕まえ、問題をログし、Slack に通知し、バックバックメッセージを送信します. { "error": "Invalid JSON from Summarizer", "fallback_response": "Sorry, I couldn’t process your request. Forwarding it to a human operator." } Observer Agent: the System’s Black Box ログし、分析し、実際に起こったことへの視界を提供します。 Purpose: このエージェントは干渉しません - それは単に時計だけです。 各エージェントが返信するのにどのくらい時間がかかったかを追跡したいですか? メモリエージェントがどのようなデータを引っ張ったか? 警備隊が落とし穴を引き起こす必要があった頻度はどれくらいですか? オブザーバーは、あなたが使用しているすべてのツール(Supabase、Amplitude、Segment、またはカスタマイズされたもの)にすべてをログします。 飛行機のブラックボックスのように考えて、それを必要としないことを願うが、何かが壊れたとき、それが何が間違ったのかを理解する唯一の方法だ。 観察者なしでは、あなたは盲目に飛んでいます。それで、あなたは完全なイメージを得ます。 Egress Agent: the Final Touch プロセスをきれいに整えましょう。 Purpose: このエージェントは、最終的な出力を取り、それをフォーマットし、どこへ行く必要があるか - ユーザ、API、Webhook、Slack、何であれ - 提供します。 最も一般的なミスの一つは、このステップを忘れることです。専用のエグレスエージェントがなければ、破損したデータ、原始ログ、または反応を間違った場所に送信するリスクがあります。 { "status": "success", "reply": "We’ve reviewed your case. Thank you for reaching out!" } これらのエージェントのそれぞれはビルドブロックです. あなたはそれらを並行して実行し、それらを独立して置き換え、チェーンを越えて再利用することができます。 What’s Next? How to Start Using AAC in Your Projects 次は何ですか? プロジェクトでAACを使用する方法 もしあなたがこれを読んでいるなら、あなたはすでに同じ問題に直面している可能性があります。 あなたのプロジェクトは成長を続けます 使用ケースは倍増します. 論理は広がります. エージェントは「スマート」になります - しかし、システムはより脆弱になります. 昨日のきれいなMVPは今、混乱した混乱に変わりました. 新しい支店を追加したいですか? それは困難です. GPTがなぜ奇妙なものを返したのかをデバッグしようとします? それはどこで起こったか分からない。 これがあなたが尋ね始める瞬間です - 別の方法はありますか? あるのです。 AACを実装することは、考え方を変えることを意味し、マジックからエンジニアリングへの移行です。 そして出発点はコードではありません。それはあなたのシステムを異なって見ています。明らかに、幻想なし。 独立した専門家の連鎖としてあなたの論理を想像してみてください。 1つは入力を取ります。もう1つはデータを準備します。 3つ目は何をすべきかを決定します。その後、執行官が来ます。その後 - メモリ。 その後、誰かが失敗をキャッチします。 最後に、誰かが何が起こったかをログします。 それはあなたの将来のエージェント、AACのスタイルです。 今、しかし、これらの役割はすべて暗示的または非常に混ざり合っているので、誰も何が何であるかを知りません。 最初の本当のステップは、これらの役割を明確にすることです。たとえ精神的にさえも。それらをスケッチしてください。彼らに名前を付けてください。正しい質問を始めてください:誰がここでオーケストラを担当していますか? メモリはどこですか? 物事が実際に機能したかどうかをどうやって知りますか? 1つのブロックが失敗したらどうなりますか? これを行うと、モジュラリティの価値が明らかになります。すべてが一箇所にバンドルされると、一つのエラーがシステム全体を破ります。しかし、物事が溶け込んだエージェントとして構造化されると、失敗は孤立されます - そしてシステムは動き続けます。AACでは、すべてのエージェントが孤立し、契約を通じてコミュニケーションをとり、他者に意識を持っていません。それは一つのパイプライン内のマイクロサービスのようなものです。 そして、その後、楽しみが始まる。 あなたは突然、あなたがシステムのパーツを再利用することができることに気付きます. あるフローを処理する同じ分類エージェントは別のフローで使用することができます. メモリブロックは複数のチェーンで共有することができます. あなたはオーケストラをよりスマートにすることもできます - それは何のエージェントを引き起こすかを選択するようにしてください. これはファンタジーではありません. これがベースライン成熟度のAACがもたらすものです. n8nのようなノーコードプラットフォームでは、これは真のスーパーパワーになります。 あなたはエージェントのライブラリを構築し始めます。それぞれは定義された契約を持つサブフローです。新しいボットを構築したいですか?必要なエージェントを呼び出すだけで、それらが必要な順序で。ブロックを置き換えたいですか? それを恐れずにします。パフォーマンスを監視したり、物事が最も失敗する場所を追跡したいですか? あなたはすでにそれを手に入れています - オブザーバーはすべてをログし、ガードはすべての失敗をキャプチャします。あなたはエンジニアのようにシステムを見始めます。 あなたは、GPTの呼び出しの連鎖をリアルなアーキテクチャに変えています - 生きているもの、スケール、ログ、進化します。 そして、あなたが今すぐにすべてを再構築する時間がない場合は、それは大丈夫です。 1 つのフローから始める。 1 つの入力ポイント。 1 つの正直な瞬間で、「OK、ここで新しいアプローチを試してみてください。 それは、AACで構築を始める瞬間です。 そしてチャンスはあります - あなたは戻りたくないでしょう。