AI Agent同士が連携するためのオープンプロトコルとして、A2A(Agent2Agent Protocol があります。
今回、RailsアプリをA2A対応Agentとして公開しやすくするRuby Gem、
a2a-rails
を作成し、v0.1.0を公開しました。
GitHub:
RubyGems:
a2a-railsとは
一言でいうと、
RailsアプリをA2A対応Agentとして公開するためのRails Integration Gem
です。
既存のRailsアプリにA2Aの入口を追加し、Rails側のビジネスロジックをAgentのSkillとして公開できます。
イメージは次のようになります。
A2A Client / Agent
↓
A2A Protocol
↓
a2a-rails
↓
Rails Application
↓
Business Logic
なぜ作ったのか
A2Aには各言語向けのSDKや実装があります。
一方、Railsアプリ側から見ると、
- Agent Cardをどう公開するか
- A2AのHTTP endpointをどうRailsに組み込むか
- A2AのTaskをRailsの処理へどうつなぐか
- Protocol固有のデータ構造をアプリケーションコードからどう分離するか
といったRails固有のIntegration部分が必要になります。
a2a-railsでは、この部分をRailsらしい形で扱うことを目指しています。
インストール
既存のRailsアプリに追加できます。
bundle add a2a-rails
セットアップ用のgeneratorを実行します。
bin/rails generate a2a:rails:install
bin/rails generate a2a:rails:agent echo
Rails側で明示的にEngineをmountしたり、config/routes.rbを書き換えたりする必要はありません。
Agentを定義する
例えば、受け取ったメッセージをそのまま返すEcho Agentは次のように定義できます。
class EchoAgent < A2A::Rails::Agent
name "Echo Agent"
description "Echo messages"
version "1.0"
skill :reply,
description: "Echo a message",
tags: %w[echo],
handler: Echo::Reply
end
Railsアプリ側では、通常のRubyクラスとして処理を書きます。
class Echo::Reply
def self.call(message:, context:)
text = message[:parts]
.filter_map { |part| part[:text] }
.join("\n")
"Echo: #{text}"
end
end
ポイントは、Handler側がA2A SDK固有のrequest / responseオブジェクトに直接依存しないことです。
Agent Cardを自動公開
a2a-railsを導入すると、Railsアプリから次のendpointが公開されます。
GET /.well-known/agent-card.json
POST /a2a
Agent Cardは、Agent / Skillの定義から生成されます。
例えば、
curl http://localhost:3000/.well-known/agent-card.json \
-H "A2A-Version: 1.0"
でAgent情報を取得できます。
A2A経由でメッセージを送る
A2A ClientからSendMessageを送ると、
A2A Client
↓
POST /a2a
↓
a2a-rails
↓
EchoAgent
↓
Echo::Reply
という流れでRailsの処理が呼ばれます。
正常終了するとTaskは、
TASK_STATE_COMPLETED
になり、Handlerの戻り値がArtifactとして返されます。
例えば、
Hello
を送ると、
Echo: Hello
が返ります。
v0.1.0で対応しているもの
現在のv0.1.0では、Server側を中心に実装しています。
主な対応内容は、
- Rails-native Agent / Skill DSL
- Agent Card生成
- A2A HTTP endpoint
SendMessageGetTaskListTasksCancelTask- synchronous Task execution
- Rails generator
- process-local Task Store
です。
A2A Protocol v1.0を対象にしています。
現時点で対応していないもの
v0.1では意図的にスコープを絞っています。
例えば次の機能はまだありません。
- Streaming / SSE
- Push Notifications
- gRPC
- ActiveJobによる非同期実行
- ActiveRecord Task Store
- A2A Client
- OAuth
- Human-in-the-loop
- Agent Registry
まずは、
RailsアプリをA2A Server Agentとして簡単に公開できる
ところを最初のゴールにしています。
動作確認
v0.1.0はRubyGemsへ公開したGemを使い、クリーンなRails 8.1アプリでも実HTTP確認しています。
確認した流れは、
Agent Card HTTP: 200
Agent name: Echo Agent
Skill: reply
SendMessage HTTP: 200
Task state: TASK_STATE_COMPLETED
Artifact: Echo: Hello
です。
今後
今後は、利用者のフィードバックを見ながら、
- Streaming
- 永続Task Store
- 非同期Task execution
- Client側機能
- 認証・認可
などを検討していきたいと思っています。
A2AとRailsの組み合わせに興味がある方は、ぜひ試してみてください。
GitHub:
Issueやフィードバックも歓迎しています。