作者:互联网 时间: 2026-07-15 18:40:51
品牌AI可见度监测需要从多个AI平台采集模型对特定问题的回答。不同平台的API协议、认证方式、限流策略和响应格式各不相同,直接拼接调用会导致代码耦合高、维护成本大、异常难以追踪。本文介绍一种基于适配器模式的多平台采集架构,统一调用接口、数据格式和错误处理,并给出关键实现片段和异常处理策略。

品牌团队需要定期观察主流AI平台(如豆包、文心一言、通义千问等)对品牌相关问题的回答表现。采集系统需要支持:
实际约束包括:
初期采用硬编码方式,为每个平台写一套独立的调用逻辑。问题很快暴露:
典型场景:某平台临时升级API版本,旧接口返回格式变化,采集任务大面积失败,但告警未及时触发,导致数据缺失。
核心原因在于调用层与业务层耦合过紧。每个平台的认证、请求构造、响应解析、错误处理都散落在业务代码中,缺乏统一抽象。
| 方案 | 优点 | 缺点 |
|---|---|---|
| 函数式封装 | 简单直接 | 异常处理不统一,扩展性差 |
| 适配器模式 | 接口统一,扩展方便 | 需要定义抽象接口 |
| 消息队列+Worker | 解耦彻底,适合高并发 | 架构复杂,运维成本高 |
选择适配器模式,平衡灵活性与实现成本。
from abc import ABC, abstractmethod
from dataclasses import dataclass
from typing import Optional
@dataclass
class AIResponse:
platform: str
question: str
raw_text: str
model: str
success: bool
error_code: Optional[str] = None
error_message: Optional[str] = None
class BaseCollector(ABC):
@abstractmethod
def collect(self, question: str) -> AIResponse:
pass
以豆包为例:
import requests
class DoubaoCollector(BaseCollector):
def __init__(self, api_key: str, endpoint: str):
self.api_key = api_key
self.endpoint = endpoint
def collect(self, question: str) -> AIResponse:
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
payload = {
"model": "doubao-pro-32k",
"messages": [{"role": "user", "content": question}]
}
try:
resp = requests.post(self.endpoint, json=payload, headers=headers, timeout=30)
resp.raise_for_status()
data = resp.json()
raw_text = data["choices"][0]["message"]["content"]
return AIResponse(
platform="doubao",
question=question,
raw_text=raw_text,
model="doubao-pro-32k",
success=True
)
except requests.exceptions.RequestException as e:
return AIResponse(
platform="doubao",
question=question,
raw_text="",
model="",
success=False,
error_code="HTTP_ERROR",
error_message=str(e)
)
其他平台类似,只需实现 collect 方法。
import time
from typing import List
class CollectorScheduler:
def __init__(self, collectors: List[BaseCollector], max_retries: int = 3, retry_delay: int = 5):
self.collectors = collectors
self.max_retries = max_retries
self.retry_delay = retry_delay
def collect_all(self, question: str) -> List[AIResponse]:
results = []
for collector in self.collectors:
for attempt in range(self.max_retries):
result = collector.collect(question)
if result.success:
break
time.sleep(self.retry_delay * (attempt + 1))
results.append(result)
return results
采集结果统一为 AIResponse 后,直接写入数据库:
import sqlite3
def save_responses(responses: List[AIResponse]):
conn = sqlite3.connect("ai_responses.db")
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS responses (
id INTEGER PRIMARY KEY AUTOINCREMENT,
platform TEXT,
question TEXT,
raw_text TEXT,
model TEXT,
success BOOLEAN,
error_code TEXT,
error_message TEXT,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
)
''')
for r in responses:
cursor.execute('''
INSERT INTO responses (platform, question, raw_text, model, success, error_code, error_message)
VALUES (?, ?, ?, ?, ?, ?, ?)
''', (r.platform, r.question, r.raw_text, r.model, r.success, r.error_code, r.error_message))
conn.commit()
conn.close()
在本地环境对三个平台(豆包、文心一言、通义千问)各执行10次调用,结果如下:
| 平台 | 平均响应时间(秒) | 成功率 | 超时次数 |
|---|---|---|---|
| 豆包 | 2.3 | 100% | 0 |
| 文心一言 | 3.1 | 90% | 1 |
| 通义千问 | 1.8 | 100% | 0 |
注意:以上数据仅为示例,实际表现受网络、模型负载等因素影响。
Retry-After 头等待。当前实现未处理该情况,可扩展为读取响应头。AIResponse 简化了后续处理和存储。该架构已在品牌AI可见度监测的采集模块中使用,支持快速接入新平台,并显著降低了异常排查时间。