跳转到主要内容

概览

智能体API提供无需LLM编排即可直接执行单一用途智能体(也称为”快速工具”)。每个智能体封装一个特定工具并返回结构化结果。 与任务API的主要区别:
  • 智能体API: 直接工具执行,无AI编排,同步结果
  • 任务API: 多步骤工作流,LLM规划,异步执行
所有智能体执行都是异步的(返回task_id),即使智能体执行单一操作。使用任务状态API检索结果。

基础URL

http://localhost:8080/api/v1/agents
生产环境: https://api-dev.shannon.run/api/v1/agents

认证

必需: 是 在请求头中包含API密钥:
X-API-Key: sk_your_api_key
开发默认: 当设置GATEWAY_SKIP_AUTH=1时禁用认证。

端点

列出智能体

GET /api/v1/agents 返回所有可用智能体及其模式和元数据。

请求

curl http://localhost:8080/api/v1/agents \
  -H "X-API-Key: sk_test_123456"

响应

{
  "agents": [
    {
      "id": "serp-ads",
      "name": "SERP广告提取",
      "description": "从Google搜索结果中提取指定关键词的付费广告",
      "category": "ads_research",
      "tool": "ads_serp_extract",
      "input_schema": {
        "required": ["keywords"],
        "properties": {
          "keywords": {
            "type": "string",
            "description": "要查找广告的搜索关键词"
          },
          "country": {
            "type": "string",
            "default": "us",
            "description": "国家代码(us、jp、uk等)"
          }
        }
      },
      "cost_per_call": 0.015
    }
  ],
  "count": 16
}

响应字段

字段类型描述
agentsarray智能体定义列表
countinteger智能体总数
智能体对象:
字段类型描述
idstring智能体标识符(用于执行端点)
namestring人类可读名称
descriptionstring智能体功能
categorystring智能体类别(ads_research、financial等)
toolstring底层工具名称
input_schemaobject输入验证的JSON模式
cost_per_callnumber每次执行的估计成本(USD)

获取智能体详情

GET /api/v1/agents/ 返回特定智能体的详情,包括其输入模式。

请求

curl http://localhost:8080/api/v1/agents/serp-ads \
  -H "X-API-Key: sk_test_123456"

响应

{
  "id": "serp-ads",
  "name": "SERP广告提取",
  "description": "从Google搜索结果中提取指定关键词的付费广告",
  "category": "ads_research",
  "tool": "ads_serp_extract",
  "input_schema": {
    "required": ["keywords"],
    "properties": {
      "keywords": {
        "type": "string",
        "description": "要查找广告的搜索关键词"
      },
      "country": {
        "type": "string",
        "default": "us"
      },
      "device": {
        "type": "string",
        "enum": ["desktop", "mobile", "tablet"],
        "default": "desktop"
      }
    }
  },
  "cost_per_call": 0.015
}

错误响应

404 Not Found - 智能体不存在:
{
  "error": "Agent not found: invalid-agent-id"
}

执行智能体

POST /api/v1/agents/ 使用提供的输入执行特定智能体。立即返回任务ID;智能体异步运行。

请求头

请求头必需描述
X-API-KeyAPI认证密钥
Content-Type必须是application/json

请求体

参数类型必需描述
inputobject智能体特定的输入参数(根据input_schema验证)
session_idstring用于跟踪的会话标识符(如省略则自动生成)
streamboolean启用流式传输(保留供未来使用)

示例: 执行SERP广告智能体

curl -X POST http://localhost:8080/api/v1/agents/serp-ads \
  -H "X-API-Key: sk_test_123456" \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": "user-session-123",
    "input": {
      "keywords": "信用卡推荐",
      "country": "cn",
      "device": "desktop"
    }
  }'

响应

状态: 202 Accepted 请求头:
  • X-Workflow-ID: Temporal工作流标识符
  • X-Session-ID: 会话标识符
响应体:
{
  "task_id": "task-abc123",
  "agent_id": "serp-ads",
  "status": "STATUS_CODE_OK",
  "created_at": "2026-02-15T10:30:00Z"
}

检索结果

使用返回的task_id调用获取任务状态端点:
curl http://localhost:8080/api/v1/tasks/task-abc123 \
  -H "X-API-Key: sk_test_123456"
完成时的响应:
{
  "task_id": "task-abc123",
  "status": "TASK_STATUS_COMPLETED",
  "result": "{\"keywords\":\"信用卡推荐\",\"total_ads\":5,\"ads\":[...]}",
  "response": {
    "keywords": "信用卡推荐",
    "total_ads": 5,
    "ads": [
      {
        "position": 1,
        "title": "2026年最佳信用卡",
        "description": "比较顶级信用卡...",
        "link": "https://example.com/cards",
        "domain": "example.com"
      }
    ],
    "cost_usd": 0.015,
    "timestamp": "2026-02-15T10:30:00Z"
  },
  "model_used": "claude-sonnet-4-20250514",
  "provider": "anthropic",
  "usage": {
    "total_tokens": 1250,
    "input_tokens": 800,
    "output_tokens": 450,
    "estimated_cost": 0.018
  }
}

错误响应

400 Bad Request - 输入无效:
{
  "error": "input validation failed: missing required field: keywords"
}
404 Not Found - 智能体不存在:
{
  "error": "Agent not found: invalid-agent"
}
429 Too Many Requests - 超过速率限制:
{
  "error": "Rate limit exceeded"
}

输入验证

所有智能体输入在执行前都会根据智能体的input_schema进行验证。 验证规则:
  1. 必需字段必须存在且非空
  2. 类型检查 - 字符串、整数、布尔值、数组、对象
  3. 枚举验证 - 值必须在允许列表中
  4. 未知字段 - 出于安全考虑被拒绝(不在模式中)
模式示例:
{
  "required": ["keywords"],
  "properties": {
    "keywords": {
      "type": "string",
      "description": "搜索关键词"
    },
    "device": {
      "type": "string",
      "enum": ["desktop", "mobile", "tablet"],
      "default": "desktop"
    },
    "max_results": {
      "type": "integer",
      "default": 10
    }
  }
}
有效输入:
{
  "keywords": "最佳跑鞋",
  "device": "mobile",
  "max_results": 5
}
无效输入(缺少必需字段):
{
  "device": "mobile"
}
错误: "input validation failed: missing required field: keywords" 无效输入(未知字段):
{
  "keywords": "跑鞋",
  "unknown_field": "value"
}
错误: "input validation failed: unknown field: unknown_field (not defined in agent schema)"

可用智能体

Shannon提供16+专用智能体,涵盖多个类别。 有关可用智能体的完整目录及详细模式和示例,请参阅:

按类别快速参考

广告研究(10个智能体):
  • serp-ads - 提取Google付费广告
  • yahoo-jp-ads - 提取Yahoo Japan赞助广告
  • meta-ad-library - 搜索Meta广告库(Facebook/Instagram)
  • competitor-discover - 发现竞争对手广告主
  • ads-transparency - 多平台广告透明度数据
  • lp-visual-analyze - 截图和分析落地页
  • lp-batch-analyze - 批量分析多个落地页
  • ad-creative-analyze - 分析广告文案模式
  • keyword-extract - 从文本提取搜索关键词
  • browser-screenshot - 捕获网页截图
金融工具(4个智能体):
  • sec-filings - SEC EDGAR文件查询
  • twitter-sentiment - 通过xAI进行X/Twitter情感分析
  • alpaca-news - Alpaca Markets股票新闻
  • news-aggregator - 多源新闻聚合

统一任务API替代方案

您也可以通过统一任务API使用context.agent参数执行智能体:
curl -X POST http://localhost:8080/api/v1/tasks \
  -H "X-API-Key: sk_test_123456" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "NVDA",
    "session_id": "user-session-123",
    "context": {
      "agent": "sec-filings",
      "agent_input": {
        "ticker": "NVDA",
        "days_back": 90
      }
    }
  }'
两种方法等效:
  • 专用端点: POST /api/v1/agents/{id}
  • 统一端点: POST /api/v1/tasks 配合context.agent

最佳实践

1. 提交前验证输入

使用GET端点检索智能体的模式,然后在客户端验证您的输入:
import httpx

# 获取模式
agent = httpx.get(
    "http://localhost:8080/api/v1/agents/serp-ads",
    headers={"X-API-Key": "sk_test_123456"}
).json()

# 验证必需字段
required = agent["input_schema"]["required"]
input_data = {"keywords": "跑鞋", "device": "mobile"}

for field in required:
    if field not in input_data:
        raise ValueError(f"Missing required field: {field}")

2. 处理异步结果

所有智能体立即返回任务ID。轮询结果:
import time

# 执行智能体
response = httpx.post(
    "http://localhost:8080/api/v1/agents/serp-ads",
    headers={"X-API-Key": "sk_test_123456"},
    json={"input": {"keywords": "跑鞋"}}
).json()

task_id = response["task_id"]

# 轮询完成
while True:
    status = httpx.get(
        f"http://localhost:8080/api/v1/tasks/{task_id}",
        headers={"X-API-Key": "sk_test_123456"}
    ).json()

    if status["status"] == "TASK_STATUS_COMPLETED":
        print(status["response"])
        break

    time.sleep(2)

3. 使用会话保持上下文

在相关的智能体调用中重用session_id:
session_id = "user-123-analysis"

# 第一次智能体调用
httpx.post(..., json={
    "session_id": session_id,
    "input": {"keywords": "跑鞋"}
})

# 第二次智能体调用(同一会话)
httpx.post(..., json={
    "session_id": session_id,
    "input": {"urls": ["https://example.com"]}
})

4. 检查成本估算

在执行昂贵的智能体之前,检查cost_per_call:
agent = httpx.get(
    "http://localhost:8080/api/v1/agents/twitter-sentiment",
    headers={"X-API-Key": "sk_test_123456"}
).json()

if agent["cost_per_call"] > 0.10:
    print(f"Warning: High cost agent (${agent['cost_per_call']})")

代码示例

Python with httpx

import httpx

# 列出所有智能体
agents = httpx.get(
    "http://localhost:8080/api/v1/agents",
    headers={"X-API-Key": "sk_test_123456"}
).json()

print(f"Found {agents['count']} agents")

# 执行特定智能体
response = httpx.post(
    "http://localhost:8080/api/v1/agents/serp-ads",
    headers={
        "X-API-Key": "sk_test_123456",
        "Content-Type": "application/json"
    },
    json={
        "session_id": "my-session",
        "input": {
            "keywords": "跑鞋",
            "country": "cn",
            "device": "mobile"
        }
    }
).json()

print(f"Task ID: {response['task_id']}")

JavaScript/Node.js

const axios = require('axios');

// 获取智能体详情
const agent = await axios.get(
  'http://localhost:8080/api/v1/agents/serp-ads',
  {
    headers: { 'X-API-Key': 'sk_test_123456' }
  }
);

console.log('Agent schema:', agent.data.input_schema);

// 执行智能体
const response = await axios.post(
  'http://localhost:8080/api/v1/agents/serp-ads',
  {
    session_id: 'my-session',
    input: {
      keywords: '跑鞋',
      country: 'cn'
    }
  },
  {
    headers: {
      'X-API-Key': 'sk_test_123456',
      'Content-Type': 'application/json'
    }
  }
);

console.log('Task ID:', response.data.task_id);

Go

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
)

type AgentExecuteRequest struct {
    SessionID string                 `json:"session_id,omitempty"`
    Input     map[string]interface{} `json:"input"`
}

func executeAgent(agentID string, input map[string]interface{}) (string, error) {
    req := AgentExecuteRequest{
        SessionID: "my-session",
        Input:     input,
    }

    body, _ := json.Marshal(req)

    httpReq, _ := http.NewRequest(
        "POST",
        fmt.Sprintf("http://localhost:8080/api/v1/agents/%s", agentID),
        bytes.NewBuffer(body),
    )

    httpReq.Header.Set("X-API-Key", "sk_test_123456")
    httpReq.Header.Set("Content-Type", "application/json")

    client := &http.Client{}
    resp, err := client.Do(httpReq)
    if err != nil {
        return "", err
    }
    defer resp.Body.Close()

    var result map[string]interface{}
    json.NewDecoder(resp.Body).Decode(&result)

    return result["task_id"].(string), nil
}

func main() {
    taskID, _ := executeAgent("serp-ads", map[string]interface{}{
        "keywords": "跑鞋",
        "country":  "cn",
    })

    fmt.Printf("Task ID: %s\n", taskID)
}

相关端点