Edison Watch
開発者向け

外部エージェントの統合

Python SDKまたはHTTP APIを使用してカスタムAIエージェントをEdison Watchと統合し、エージェントのアクティビティを追跡、制御、監視します。

Edison Watchは、外部AIエージェントを統合するためのAPIとSDKを提供し、ツール呼び出しの追跡、セキュリティポリシーの施行、およびエージェントアクティビティのリアルタイム監視を可能にします。

前提条件

エージェントを統合する前に:

  1. Edison Watchサーバーが実行中であり、アクセス可能であること
  2. ダッシュボードからのAPIキー(Settings → API Keys)
  3. Python 3.8以上(Python SDK用)またはHTTPクライアント(直接API用)

Settings → API Keysの下のEdison WatchダッシュボードからAPIキーを取得します。APIキーはエージェントを認証し、アクティビティをユーザーアカウントに関連付けます。

サーバーの場所: EDISON_WATCH_API_BASE環境変数をEdison WatchサーバーのURL(例: https://dashboard.edison.watch)に設定します。SDKはこの値を読み取ってサーバーに接続します。

クイックスタート (Python/LangGraph)

最も迅速に統合する方法は、@edison.track()デコレータを備えたedison-watch Python SDKを使用することです。

インストール

pip install edison-watch langgraph langchain-openai

環境変数

以下の環境変数を設定します(またはEdisonコンストラクターに渡します):

export EDISON_WATCH_API_BASE="https://dashboard.edison.watch"  # あなたのEdison WatchサーバーURL
export EDISON_WATCH_API_KEY="your_api_key_here"
export OPENAI_API_KEY="your_openai_key"  # LangChainの例用

必須: EDISON_WATCH_API_BASEをEdison WatchサーバーのURL(例: https://dashboard.edison.watch)に設定する必要があります。

最小限の統合

エージェントのツール呼び出しを追跡するために、わずか4行を追加します:

from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
from edison_watch import Edison
 
# Edisonを初期化(環境変数からEDISON_WATCH_API_KEYを読み取る)
edison = Edison()
 
@tool
@edison.track()  # 自動命名: agent_web_search
def web_search(query: str, max_results: int = 3) -> str:
    """Return up to N result URLs."""
    return "https://docs.python.org/3/"
 
@tool
@edison.track()  # 自動命名: agent_fetch_url
def fetch_url(url: str, max_chars: int = 1000) -> str:
    """Fetch and return the first max_chars of the page."""
    import httpx
    return httpx.get(url, follow_redirects=True, timeout=10).text[:max_chars]
 
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
agent = create_react_agent(model=llm, tools=[web_search, fetch_url])
 
result = agent.invoke({
    "messages": [("user", "Fetch the first 1000 chars of the CPython docs homepage.")]
})
print(result["messages"][-1].content)

@edison.track()デコレータは自動的に以下を行います:

  • 実行前にツール呼び出しのメタデータをEdison Watchに送信
  • 呼び出しがセキュリティポリシーをトリガーする場合、承認を待機
  • 実行後に期間と結果を記録
  • ダッシュボードのタイムラインに表示

エージェントの登録(オプション)

より良い整理と追跡のために、Edison Watchに名前付きエージェントを登録することができます。これは、複数のエージェントタイプや役割を管理する場合に便利です。

エージェントの作成

curl -X POST https://dashboard.edison.watch/api/agents \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your_api_key" \
  -d '{
    "name": "hr_assistant",
    "agent_type": "hr"
  }'

レスポンス:

{
  "ok": true,
  "agent": {
    "id": 1,
    "name": "hr_assistant",
    "agent_id": "agent:a1b2c3d4e5f6...",
    "agent_type": "hr",
    "user_id": "user-uuid",
    "created_at": "2025-01-15T10:30:00",
    "updated_at": "2025-01-15T10:30:00"
  }
}

agent_idagent:HEX(32文字の16進数)形式で自動的に生成されます。

エージェントの一覧表示

curl -X GET https://dashboard.edison.watch/api/agents \
  -H "Authorization: Bearer your_api_key"

レスポンス:

{
  "agents": [
    {
      "name": "hr_assistant",
      "agent_id": "agent:a1b2c3d4e5f6...",
      "agent_type": "hr",
      "created_at": "2025-01-15T10:30:00"
    }
  ]
}

エージェントの削除

curl -X DELETE https://dashboard.edison.watch/api/agents/hr_assistant \
  -H "Authorization: Bearer your_api_key"

レスポンス:

{
  "ok": true,
  "message": "Agent 'hr_assistant' deleted successfully"
}

エージェントの登録はオプションです。エージェントを登録せずに追跡APIを直接使用できます。登録は主に管理的な整理と報告に役立ちます。

Edison SDKリファレンス

Edisonクラスは、エージェントアクティビティを追跡するためのPython SDKを提供します。

コンストラクター

from edison_watch import Edison
 
edison = Edison(
    api_base: str | None = None,           # 指定されていない場合、EDISON_WATCH_API_BASE環境変数から読み取ります
    api_key: str | None = None,             # 指定されていない場合、EDISON_WATCH_API_KEY環境変数から読み取ります
    timeout_s: float = 30.0,                 # 承認待機タイムアウト
    healthcheck: bool = True,                # バックグラウンドヘルスチェック
    healthcheck_timeout_s: float = 3.0,      # ヘルスチェックタイムアウト
    agent_name: str | None = None,          # エージェントID(例: 'hr_assistant')
    agent_type: str | None = None,           # エージェントタイプ/役割(例: 'hr', 'engineering')
    session_id: str | None = None            # 固定セッションID(Noneの場合自動生成)
)

環境変数:

  • EDISON_WATCH_API_BASE: サーバーURL(必須 - Edison Watchサーバーに設定)
  • EDISON_WATCH_API_KEY: 認証用APIキー(必須)

コンストラクター引数として提供されない場合、これらの値は環境変数から読み取られます。

追跡デコレータ

@edison.track()デコレータは、実行を追跡するために関数をラップします:

@edison.track()
def my_tool(arg1: str, arg2: int) -> str:
    """Tool description."""
    return "result"

パラメーター:

  • session_id: この呼び出しのセッションIDを上書き
  • name: ツール名を上書き(デフォルトは関数名)

動作:

  • 実行前に/agent/beginを呼び出し(ゲーティング + 承認待機)
  • 関数を実行
  • 実行後にステータス、期間、結果サマリーとともに/agent/endを呼び出し
  • ブロックされ承認されない場合、PermissionErrorを発生

LangChainツールのラップ

LangChainツールの場合、wrap_tools()を使用します:

from langchain_core.tools import tool
 
@tool
def search_codebase(query: str) -> str:
    """Search the codebase."""
    return "results..."
 
tools = [search_codebase]
tracked_tools = edison.wrap_tools(tools)

またはbind_tools()を使用して1ステップでラップとバインドを行います:

llm = ChatOpenAI()
llm_with_tools = edison.bind_tools(llm, tools)

セッション管理

セッションは、関連するツール呼び出しをグループ化します。デフォルトでは、各Edisonインスタンスは一意のセッションIDを作成しますが、セッションを共有できます:

# 複数のEdisonインスタンス間でセッションを共有
shared_session = str(uuid.uuid4())
 
edison1 = Edison(session_id=shared_session, agent_name="agent1")
edison2 = Edison(session_id=shared_session, agent_name="agent2")

呼び出しごとにセッションを上書きすることもできます:

@edison.track(session_id="custom-session-id")
def my_tool():
    pass

直接HTTP API(非Python)

Pythonを使用していない場合、HTTPエンドポイントを介して直接統合できます。

ツール呼び出しの追跡開始

curl -X POST https://dashboard.edison.watch/agent/begin \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your_api_key" \
  -d '{
    "session_id": "optional-session-id",
    "name": "web_search",
    "args_summary": "query: '\''python docs'\''",
    "timeout_s": 30.0,
    "agent_name": "hr_assistant",
    "agent_type": "hr"
  }'

レスポンス:

{
  "ok": true,
  "session_id": "uuid-here",
  "call_id": "call-uuid-here",
  "approved": true,                         # falseの場合はブロック、エラーの場合はnull
  "error": null                             # ok=falseの場合のエラーメッセージ
}

ステータスコード:

  • 200 OK: リクエスト処理済み(approvedフィールドを確認)
  • 400 Bad Request: 無効なリクエストボディ
  • 401 Unauthorized: APIキーがないか無効

重要: approvedfalseの場合、ツール呼び出しはセキュリティポリシーによってブロックされました。ダッシュボードでの手動承認を待つか、エラーを適切に処理してください。

追跡完了

ツールを実行した後、/agent/endを呼び出します:

curl -X POST https://dashboard.edison.watch/agent/end \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your_api_key" \
  -d '{
    "session_id": "uuid-from-begin",
    "call_id": "call-uuid-from-begin",
    "status": "ok",
    "duration_ms": 125.5,
    "result_summary": "Found 3 results..."
  }'

レスポンス:

{
  "ok": true
}

ツール名の正規化

ツール名がまだbuiltin_またはagent_で始まっていない場合、自動的にagent_がプレフィックスとして付けられます:

  • web_searchagent_web_search
  • agent_my_toolagent_my_tool(変更なし)
  • builtin_systembuiltin_system(変更なし)

例: 完全な統合

async function trackToolCall(toolName, args, executeFn) {
  // EDISON_WATCH_API_BASEを環境変数に設定する必要があります
  const apiBase = process.env.EDISON_WATCH_API_BASE;
  if (!apiBase) {
    throw new Error('EDISON_WATCH_API_BASE environment variable is required');
  }
  const apiKey = process.env.EDISON_WATCH_API_KEY;
 
  // Begin tracking
  const beginResponse = await fetch(`${apiBase}/agent/begin`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${apiKey}`
    },
    body: JSON.stringify({
      name: toolName,
      args_summary: JSON.stringify(args),
      agent_name: 'my_agent',
      agent_type: 'custom'
    })
  });
 
  const beginData = await beginResponse.json();
 
  if (!beginData.ok || !beginData.approved) {
    throw new Error(`Tool call blocked: ${beginData.error}`);
  }
 
  const startTime = performance.now();
  let status = 'ok';
  let result;
 
  try {
    // Execute the tool
    result = await executeFn();
  } catch (error) {
    status = 'error';
    throw error;
  } finally {
    const duration = performance.now() - startTime;
 
    // End tracking
    await fetch(`${apiBase}/agent/end`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${apiKey}`
      },
      body: JSON.stringify({
        session_id: beginData.session_id,
        call_id: beginData.call_id,
        status: status,
        duration_ms: duration,
        result_summary: JSON.stringify(result).substring(0, 1000)
      })
    });
  }
 
  return result;
}
 
// Usage
const result = await trackToolCall(
  'web_search',
  { query: 'python docs' },
  async () => {
    // Your tool implementation
    return 'search results...';
  }
);

マルチエージェント設定

異なる役割や権限を持つ複数のエージェントを実行する場合、個別のagent_nameagent_typeを持つEdisonインスタンスを作成します:

from edison_watch import Edison
import uuid
 
# HR Assistant
edison_hr = Edison(
    agent_name="hr_assistant",
    agent_type="hr",
    session_id=str(uuid.uuid4()),
    api_key=api_key,
    api_base=api_base
)
 
# Engineering Copilot
edison_eng = Edison(
    agent_name="eng_copilot",
    agent_type="engineering",
    session_id=str(uuid.uuid4()),
    api_key=api_key,
    api_base=api_base
)
 
# 異なるエージェントに異なるインスタンスを使用
@edison_hr.track()
def hr_get_employee_profile(employee_id: str) -> str:
    """HR tool."""
    return f"Profile for {employee_id}"
 
@edison_eng.track()
def eng_search_codebase(query: str) -> str:
    """Engineering tool."""
    return f"Code search results for {query}"

各エージェントのアクティビティはダッシュボードで個別に追跡され、ダッシュボードの権限設定を通じてエージェントタイプごとに異なる権限を設定できます。

権限設定

追跡されたツールは、権限システムでagent_プレフィックス付きで名前が付けられます。Edison Watchダッシュボードでこれらを設定します:

  1. ダッシュボードのServersに移動します
  2. agentサーバーを見つけるか作成します(SDK経由で追跡されたツールはこのサーバーの下に表示されます)
  3. 各ツールをクリックして権限を設定します

権限設定:

各ツールについて以下を設定できます:

  • Enabled: ツールの実行が許可されているかどうか
  • Write Operation: ツールがデータを変更できる(例: メール送信、ファイル作成)
  • Read Private Data: ツールが機密内部データにアクセスする
  • Read Untrusted Public Data: ツールが外部/信頼できないコンテンツを処理する
  • ACL: アクセス制御レベル(PUBLIC, PRIVATE, SECRET, TOP_SECRET)

設定例:

agent_web_searchとして追跡されるweb_searchツールの場合:

  • Enabled: ✓
  • Write Operation: ✗
  • Read Private Data: ✗
  • Read Untrusted Public Data: ✓
  • ACL: PUBLIC

agent_send_emailとして追跡されるsend_emailツールの場合:

  • Enabled: ✓
  • Write Operation: ✓
  • Read Private Data: ✗
  • Read Untrusted Public Data: ✗
  • ACL: SECRET

セキュリティフラグ:

  • write_operation: ツールがデータを変更できる(例: メール送信、ファイル作成)
  • read_private_data: ツールが機密内部データにアクセスする
  • read_untrusted_public_data: ツールが外部/信頼できないコンテンツを処理する

Lethal Trifecta: ツール呼び出しが3つのフラグすべて(プライベートデータ + 信頼できないコンテンツ + 書き込み)を組み合わせる場合、Edison Watchは手動承認のために一時停止します。

ACLレベル:

  • PUBLIC: 機密でないデータ
  • PRIVATE: 機密または内部データ
  • SECRET: 高度な機密データ

施行: データは高いACLから低いACLに流れることはできません(例: SECRET → PUBLIC)。

詳細な設定ガイダンスについては、権限の設定を参照してください。

エラー処理

ブロックされたツール呼び出し

ツール呼び出しがセキュリティポリシーによってブロックされた場合:

try:
    result = my_tracked_tool()
except PermissionError as e:
    # Tool was blocked and not approved
    print(f"Blocked: {e}")
    # Wait for approval in dashboard, or handle gracefully

ネットワークエラー

SDKはネットワークエラーを適切に処理し、ログに記録します。Edison Watchに到達できない場合:

  • ツール実行は継続します(ベストエフォート追跡)
  • エラーはログに記録されますが、例外は発生しません
  • ヘルスチェックがバックグラウンドで実行され、接続性を検出します

タイムアウト処理

手動承認がタイムアウト(デフォルト: 30秒)を超えた場合:

edison = Edison(timeout_s=60.0)  # Increase timeout to 60 seconds

timeout_sパラメーターは、PermissionErrorを発生させる前に承認を待つ時間を制御します。

ベストプラクティス

  1. 説明的なエージェント名を使用する: hr_assistant, eng_copilot, finance_analyst
  2. エージェントタイプを設定する: 管理しやすいように役割ごとにエージェントをグループ化します
  3. セッションを適切に共有する: 会話内の関連するツール呼び出しに同じsession_idを使用します
  4. 承認を適切に処理する: ブロックされた呼び出しは承認を待つか、適切に失敗する必要があります
  5. 事前に権限を設定する: エージェントをデプロイする前にダッシュボードでツール権限を設定します
  6. ダッシュボードを監視する: エージェントのアクティビティを確認し、必要に応じて権限を調整します

トラブルシューティング

401 Unauthorized

  • EDISON_WATCH_API_KEYが正しく設定されていることを確認してください
  • ダッシュボードでAPIキーがアクティブであることを確認してください

ツール呼び出しがブロックされる

  • ダッシュボードでツール権限を確認してください(Servers → agent → Tools)
  • ツール名が一致していることを確認してください(agent_プレフィックス付き)
  • 必要に応じてダッシュボードでブロックされた呼び出しを承認してください

ツール呼び出しがダッシュボードに表示されない

  • Edison Watchサーバーが実行されていることを確認してください
  • api_baseへのネットワーク接続を確認してください
  • サーバーログのエラーを確認してください

ヘルスチェックの失敗

  • Edison Watchがapi_baseでアクセス可能であることを確認してください
  • ファイアウォール/ネットワーク設定を確認してください
  • サーバーが実行されていることを確認してください: curl https://dashboard.edison.watch/health

助けが必要ですか? エージェントアクティビティの監視についてはダッシュボードガイドを確認するか、[email protected]にメールでサポートを依頼してください。