Edison Watch
Desenvolvedores

Integrando Agentes Externos

Integre agentes de IA personalizados com o Edison Watch usando o SDK Python ou a API HTTP para rastreamento, controle e monitoramento da atividade do agente.

O Edison Watch fornece APIs e SDKs para integrar agentes de IA externos, permitindo que você rastreie chamadas de ferramentas, imponha políticas de segurança e monitore a atividade do agente em tempo real.

Pré-requisitos

Antes de integrar seu agente:

  1. Servidor Edison Watch deve estar em execução e acessível
  2. Chave de API do painel (Configurações → Chaves de API)
  3. Python 3.8+ (para SDK Python) ou cliente HTTP (para API direta)

Obtenha sua chave de API no painel do Edison Watch em Settings → API Keys. A chave de API autentica seu agente e associa a atividade à sua conta de usuário.

Localização do Servidor: Defina a variável de ambiente EDISON_WATCH_API_BASE para a URL do seu servidor Edison Watch (ex: https://dashboard.edison.watch). O SDK lê esse valor para se conectar ao seu servidor.

Início Rápido (Python/LangGraph)

A maneira mais rápida de integrar é usando o SDK Python edison-watch com o decorador @edison.track().

Instalação

pip install edison-watch langgraph langchain-openai

Variáveis de Ambiente

Defina essas variáveis de ambiente (ou passe-as para o construtor Edison):

export EDISON_WATCH_API_BASE="https://dashboard.edison.watch"  # Sua URL do servidor Edison Watch
export EDISON_WATCH_API_KEY="your_api_key_here"
export OPENAI_API_KEY="your_openai_key"  # para exemplos do LangChain

Obrigatório: Você deve definir EDISON_WATCH_API_BASE para a URL do seu servidor Edison Watch (ex: https://dashboard.edison.watch).

Integração Mínima

Adicione apenas 4 linhas para rastrear as chamadas de ferramentas do seu agente:

from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
from edison_watch import Edison
 
# Inicializar Edison (lê EDISON_WATCH_API_KEY do ambiente)
edison = Edison()
 
@tool
@edison.track()  # nomeia automaticamente: 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()  # nomeia automaticamente: 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)

O decorador @edison.track() automaticamente:

  • Envia metadados de chamada de ferramenta para o Edison Watch antes da execução
  • Aguarda aprovação se a chamada acionar políticas de segurança
  • Registra duração e resultado após a execução
  • Aparece na linha do tempo do painel

Registrando Agentes (Opcional)

Você pode opcionalmente registrar agentes nomeados no Edison Watch para melhor organização e rastreamento. Isso é útil ao gerenciar vários tipos de agentes ou funções.

Criar um Agente

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"
  }'

Resposta:

{
  "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"
  }
}

O agent_id é gerado automaticamente no formato agent:HEX (32 caracteres hexadecimais).

Listar Agentes

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

Resposta:

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

Excluir um Agente

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

Resposta:

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

O registro de agentes é opcional. Você pode usar a API de rastreamento diretamente sem registrar agentes. O registro é útil principalmente para organização administrativa e relatórios.

Referência do SDK Edison

A classe Edison fornece um SDK Python para rastrear a atividade do agente.

Construtor

from edison_watch import Edison
 
edison = Edison(
    api_base: str | None = None,           # Lê da env var EDISON_WATCH_API_BASE se não fornecido
    api_key: str | None = None,             # Lê da env var EDISON_WATCH_API_KEY se não fornecido
    timeout_s: float = 30.0,                 # Tempo limite de espera de aprovação
    healthcheck: bool = True,                # Verificações de saúde em segundo plano
    healthcheck_timeout_s: float = 3.0,      # Tempo limite de verificação de saúde
    agent_name: str | None = None,          # Identidade do agente (ex: 'hr_assistant')
    agent_type: str | None = None,           # Tipo/função do agente (ex: 'hr', 'engineering')
    session_id: str | None = None            # ID de sessão fixo (gerado automaticamente se None)
)

Variáveis de Ambiente:

  • EDISON_WATCH_API_BASE: URL do servidor (obrigatório - defina para seu servidor Edison Watch)
  • EDISON_WATCH_API_KEY: Chave de API para autenticação (obrigatório)

Se não fornecidos como argumentos do construtor, esses valores são lidos de variáveis de ambiente.

Decorador de Rastreamento

O decorador @edison.track() envolve funções para rastrear sua execução:

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

Parâmetros:

  • session_id: Substituir o ID da sessão para esta chamada
  • name: Substituir o nome da ferramenta (o padrão é o nome da função)

Comportamento:

  • Chama /agent/begin antes da execução (controle + espera de aprovação)
  • Executa a função
  • Chama /agent/end após a execução com status, duração e resumo do resultado
  • Levanta PermissionError se bloqueado e não aprovado

Envolvendo Ferramentas LangChain

Para ferramentas LangChain, use 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)

Ou use bind_tools() para envolver e vincular em uma etapa:

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

Gerenciamento de Sessão

As sessões agrupam chamadas de ferramentas relacionadas. Por padrão, cada instância Edison cria um ID de sessão exclusivo, mas você pode compartilhar sessões:

# Compartilhar sessão entre várias instâncias Edison
shared_session = str(uuid.uuid4())
 
edison1 = Edison(session_id=shared_session, agent_name="agent1")
edison2 = Edison(session_id=shared_session, agent_name="agent2")

Você também pode substituir a sessão por chamada:

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

API HTTP Direta (Não-Python)

Se você não estiver usando Python, pode integrar diretamente via endpoints HTTP.

Iniciar Rastreamento de uma Chamada de Ferramenta

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"
  }'

Resposta:

{
  "ok": true,
  "session_id": "uuid-here",
  "call_id": "call-uuid-here",
  "approved": true,                         # false se bloqueado, null em caso de erro
  "error": null                             # Mensagem de erro se ok=false
}

Códigos de Status:

  • 200 OK: Solicitação processada (verifique o campo approved)
  • 400 Bad Request: Corpo da solicitação inválido
  • 401 Unauthorized: Chave de API ausente ou inválida

Importante: Se approved for false, a chamada da ferramenta foi bloqueada por políticas de segurança. Aguarde a aprovação manual no painel ou trate o erro adequadamente.

Concluir Rastreamento

Após executar a ferramenta, chame /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..."
  }'

Resposta:

{
  "ok": true
}

Normalização de Nome de Ferramenta

Os nomes das ferramentas são prefixados automaticamente com agent_ se ainda não começarem com builtin_ ou agent_:

  • web_searchagent_web_search
  • agent_my_toolagent_my_tool (sem alteração)
  • builtin_systembuiltin_system (sem alteração)

Exemplo: Integração Completa

async function trackToolCall(toolName, args, executeFn) {
  // EDISON_WATCH_API_BASE deve ser definido em seu ambiente
  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...';
  }
);

Configuração Multi-Agente

Ao executar vários agentes com diferentes funções ou permissões, crie instâncias Edison separadas com agent_name e agent_type distintos:

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
)
 
# Use diferentes instâncias para diferentes agentes
@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}"

A atividade de cada agente será rastreada separadamente no painel, e você pode configurar diferentes permissões por tipo de agente através das configurações de permissões do painel.

Configuração de Permissões

Ferramentas rastreadas são nomeadas com o prefixo agent_ no sistema de permissões. Configure-as através do painel do Edison Watch:

  1. Navegue para Servers no painel
  2. Encontre ou crie o servidor agent (ferramentas rastreadas via SDK aparecem sob este servidor)
  3. Clique em cada ferramenta para configurar suas permissões

Configurações de Permissão:

Para cada ferramenta, você pode configurar:

  • Enabled: Se a ferramenta tem permissão para rodar
  • Write Operation: Ferramenta pode modificar dados (ex: enviar e-mail, criar arquivo)
  • Read Private Data: Ferramenta acessa dados internos confidenciais
  • Read Untrusted Public Data: Ferramenta processa conteúdo externo/não confiável
  • ACL: Nível de controle de acesso (PUBLIC, PRIVATE, SECRET, TOP_SECRET)

Configuração de Exemplo:

Para uma ferramenta web_search rastreada como agent_web_search:

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

Para uma ferramenta send_email rastreada como agent_send_email:

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

Sinalizadores de Segurança:

  • write_operation: Ferramenta pode modificar dados (ex: enviar e-mail, criar arquivo)
  • read_private_data: Ferramenta acessa dados internos confidenciais
  • read_untrusted_public_data: Ferramenta processa conteúdo externo/não confiável

Lethal Trifecta: Se uma chamada de ferramenta combinar todos os três sinalizadores (dados privados + conteúdo não confiável + escrita), o Edison Watch pausará para aprovação manual.

Níveis ACL:

  • PUBLIC: Dados não confidenciais
  • PRIVATE: Dados confidenciais ou internos
  • SECRET: Dados altamente confidenciais

Aplicação: Os dados não podem fluir de um ACL mais alto para um mais baixo (ex: SECRET → PUBLIC).

Veja Configurando Permissões para orientação detalhada de configuração.

Tratamento de Erros

Chamadas de Ferramentas Bloqueadas

Se uma chamada de ferramenta for bloqueada por políticas de segurança:

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

Erros de Rede

O SDK lida com erros de rede graciosamente e os registra. Se o Edison Watch estiver inacessível:

  • A execução da ferramenta continua (rastreamento de melhor esforço)
  • Erros são registrados, mas não levantam exceções
  • Verificações de saúde são executadas em segundo plano para detectar conectividade

Tratamento de Tempo Limite

Se a aprovação manual exceder o tempo limite (padrão: 30 segundos):

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

O parâmetro timeout_s controla quanto tempo esperar pela aprovação antes de levantar PermissionError.

Melhores Práticas

  1. Use nomes de agentes descritivos: hr_assistant, eng_copilot, finance_analyst
  2. Defina tipos de agentes: Agrupe agentes por função para facilitar o gerenciamento
  3. Compartilhe sessões apropriadamente: Use o mesmo session_id para chamadas de ferramentas relacionadas em uma conversa
  4. Trate aprovações graciosamente: Chamadas bloqueadas devem esperar aprovação ou falhar graciosamente
  5. Configure permissões antecipadamente: Configure permissões de ferramentas no painel antes de implantar agentes
  6. Monitore o painel: Revise a atividade do agente e ajuste as permissões conforme necessário

Solução de Problemas

401 Unauthorized

  • Verifique se EDISON_WATCH_API_KEY está definida corretamente
  • Verifique se a chave de API está ativa no painel

Chamadas de ferramentas bloqueadas

  • Verifique as permissões da ferramenta no painel (Servers → agent → Tools)
  • Verifique se o nome da ferramenta corresponde (com prefixo agent_)
  • Aprove chamadas bloqueadas no painel, se necessário

Chamadas de ferramentas não aparecem no painel

  • Verifique se o servidor Edison Watch está em execução
  • Verifique a conectividade de rede com api_base
  • Revise os logs do servidor para erros

Falhas na verificação de saúde

  • Certifique-se de que o Edison Watch esteja acessível em api_base
  • Verifique as configurações de firewall/rede
  • Verifique se o servidor está em execução: curl https://dashboard.edison.watch/health

Precisa de ajuda? Confira o guia do Painel para monitorar a atividade do agente ou envie um e-mail para [email protected] para suporte.