geo/docs/3-技术设计/01-GEO平台技术详细设计-v1.0.md

33 KiB
Raw Blame History

GEO 平台技术详细设计文档

文档版本: v1.0 创建日期: 2026-05-01 状态: 待评审 依据文档:


目录

  1. 系统架构设计
  2. 核心模块设计
  3. 接口设计
  4. 数据模型设计
  5. 安全设计
  6. 部署架构
  7. 监控与运维

1. 系统架构设计

1.1 整体架构

┌─────────────────────────────────────────────────────────────────┐
│                         用户层 (Client)                          │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐            │
│  │   Web App   │  │  Mobile Web │  │    API      │            │
│  │  (Next.js)  │  │  (响应式)   │  │  (REST)     │            │
│  └─────────────┘  └─────────────┘  └─────────────┘            │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                         网关层 (Gateway)                         │
│  ┌─────────────────────────────────────────────────────────────┐ │
│  │                     Nginx / API Gateway                     │ │
│  │  - 负载均衡    - SSL终止    - 限流      - 认证            │ │
│  └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                         应用层 (Application)                     │
│  ┌──────────────────┐          ┌──────────────────┐            │
│  │   前端服务        │          │   后端服务        │            │
│  │   (Next.js)      │          │   (FastAPI)      │            │
│  │   Port: 3000     │          │   Port: 8000     │            │
│  └──────────────────┘          └──────────────────┘            │
│                                      │                          │
│                           ┌──────────┴──────────┐               │
│                           ▼                     ▼               │
│                    ┌──────────────┐      ┌──────────────┐       │
│                    │   Worker 1   │      │   Worker 2   │       │
│                    │  (Scheduler) │      │  (Scheduler) │       │
│                    └──────────────┘      └──────────────┘       │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                         数据层 (Data)                            │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐         │
│  │  PostgreSQL  │  │    Redis     │  │   MinIO      │         │
│  │   主数据库    │  │   缓存/队列   │  │   文件存储   │         │
│  └──────────────┘  └──────────────┘  └──────────────┘         │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                         外部服务 (External)                       │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐         │
│  │  LLM APIs    │  │  Email API   │  │  短信 API    │         │
│  │ (DeepSeek等) │  │   (SendGrid) │  │  (阿里云)    │         │
│  └──────────────┘  └──────────────┘  └──────────────┘         │
└─────────────────────────────────────────────────────────────────┘

1.2 技术栈总览

层级 技术选型 版本 说明
前端框架 Next.js 14.x App Router, React 18
UI组件 shadcn/ui latest Radix UI + TailwindCSS
图表库 Recharts 2.x 数据可视化
后端框架 FastAPI 0.109+ 异步高性能
ORM SQLAlchemy 2.0+ 异步ORM
数据库 PostgreSQL 15+ 主数据存储
缓存 Redis 7+ 缓存/队列
任务调度 APScheduler 3.10+ 定时任务
LLM SDK OpenAI SDK 1.x 统一LLM调用
文档 Alembic - 数据库迁移

1.3 模块架构

backend/
├── app/
│   ├── api/                    # API路由层
│   │   ├── v1/
│   │   │   ├── auth.py       # 认证接口
│   │   │   ├── brands.py     # 品牌接口
│   │   │   ├── competitors.py # 竞品接口
│   │   │   ├── citations.py   # 引用接口
│   │   │   ├── reports.py     # 报告接口
│   │   │   └── admin.py      # 管理接口
│   │   └── deps.py           # 依赖注入
│   │
│   ├── core/                  # 核心模块
│   │   ├── config.py         # 配置管理
│   │   ├── security.py       # 安全认证
│   │   └── exceptions.py     # 异常定义
│   │
│   ├── models/                # 数据模型
│   │   ├── user.py
│   │   ├── brand.py
│   │   ├── competitor.py
│   │   ├── citation.py
│   │   └── query_task.py
│   │
│   ├── schemas/               # Pydantic模型
│   │   ├── auth.py
│   │   ├── brand.py
│   │   ├── citation.py
│   │   └── report.py
│   │
│   ├── services/              # 业务逻辑层
│   │   ├── auth_service.py
│   │   ├── brand_service.py
│   │   ├── citation_service.py
│   │   ├── scoring_service.py # 评分计算
│   │   └── report_service.py
│   │
│   ├── workers/              # 后台任务
│   │   ├── scheduler.py      # 任务调度
│   │   ├── citation_engine.py # 引用检测引擎
│   │   ├── adapters/         # 平台适配器
│   │   │   ├── base.py      # 基类
│   │   │   ├── llm_adapter.py # LLM适配器
│   │   │   └── platforms/   # 各平台实现
│   │   └── cache.py         # 缓存管理
│   │
│   ├── db/                   # 数据库
│   │   ├── session.py
│   │   └── repositories/
│   │
│   └── main.py               # 应用入口
│
├── alembic/                  # 数据库迁移
│   └── versions/
│
├── tests/                    # 测试
│
└── requirements.txt

2. 核心模块设计

2.1 引用检测引擎 (CitationEngine)

模块职责: 统一管理品牌引用检测的核心业务逻辑

设计原则:

  • 单一职责: 仅负责引用检测流程编排
  • 开闭原则: 新增平台只需实现适配器
  • 依赖倒置: 通过抽象接口调用平台

核心类图:

# 伪代码描述,实际代码见实现文件
class CitationEngine:
    """引用检测引擎核心类"""

    def __init__(self):
        self.llm_adapter: LLMAdapter      # LLM调用适配器
        self.platform_adapters: dict      # 平台适配器映射
        self.cache: CacheService           # 缓存服务
        self.scoring_service: ScoringService # 评分服务

    async def query_brand(
        self,
        keyword: str,
        brand: Brand,
        platforms: list[str]
    ) -> QueryResult:
        """执行品牌查询"""
        pass

    async def calculate_score(
        self,
        citations: list[Citation]
    ) -> BrandScore:
        """计算品牌评分"""
        pass

核心流程:

query_brand 流程:
1. 检查缓存
   └── 命中 → 返回缓存结果
2. 构建查询任务
3. 遍历平台适配器
   ├── LLMAdapter.query()  # 主路径
   └── PlaywrightAdapter.query()  # 兜底
4. 解析响应
5. 品牌匹配检测
6. 竞品识别
7. 计算评分
8. 存储结果
9. 更新缓存
10. 返回结果

2.2 LLM适配器 (LLMAdapter)

模块职责: 统一封装LLM API调用

LLM API定价依据 (来源: DeepSeek官方API文档 [1], OpenAI官方 [2]):

LLM 输入价格 输出价格 单次成本估算
DeepSeek-V3 ¥0.002/千tokens ¥0.008/千tokens ¥0.006/次
GPT-4o-mini ¥0.001/千tokens ¥0.004/千tokens ¥0.003/次

单次成本计算依据:

  • 输入Prompt: ~1000 tokens (品牌名、别名、查询词)
  • 输出响应: ~500 tokens (JSON格式检测结果)
  • DeepSeek-V3: 1000×¥0.002 + 500×¥0.008 = ¥0.006
  • GPT-4o-mini: 1000×¥0.001 + 500×¥0.004 = ¥0.003

成本优化建议:

  • 使用DeepSeek-V3作为主LLM (成本最低)
  • 启用Prompt缓存进一步降低成本 (~50%节省)
  • 批量查询合并请求减少API调用次数

Prompt模板设计:

# 品牌引用检测Prompt
BRAND_CITATION_PROMPT = """
你是一个专业的品牌分析助手。请分析以下查询中是否提到了目标品牌。

查询关键词: {keyword}
目标品牌: {brand_name}
品牌别名: {brand_aliases}

请分析AI平台对上述品牌的提及情况并返回JSON格式的结果:
{{
    "cited": true/false,           // 是否被提及
    "position": 1,                  // 提及位置(1-based)
    "citation_text": "...",         // 引用文本片段(最多200字)
    "sentiment": "positive/neutral/negative",  // 情感倾向
    "confidence": 0.95              // 置信度
}}

请仅返回JSON不要有其他内容。
"""

错误处理策略:

错误类型 处理策略 重试次数
API超时 重试 3次
配额超限 切换LLM/排队 -
响应格式错误 使用备用Parser 1次
网络错误 重试 3次

2.3 平台适配器 (PlatformAdapter)

模块职责: 封装各AI平台的查询接口

适配器结构:

class BasePlatformAdapter(ABC):
    """平台适配器基类"""

    platform_name: str
    platform_code: str
    api_endpoint: str

    @abstractmethod
    async def query(
        self,
        keyword: str,
        context: QueryContext
    ) -> PlatformResponse:
        """执行平台查询"""
        pass

    def build_prompt(
        self,
        keyword: str,
        brand_name: str,
        brand_aliases: list[str]
    ) -> str:
        """构建查询Prompt"""
        return BRAND_CITATION_PROMPT.format(
            keyword=keyword,
            brand_name=brand_name,
            brand_aliases=", ".join(brand_aliases)
        )


class WenxinAdapter(BasePlatformAdapter):
    """文心一言适配器"""

    platform_name = "文心一言"
    platform_code = "wenxin"
    api_endpoint = "https://api.deepseek.com/v1/chat/completions"

    async def query(self, keyword, context):
        # 实现文心一言特定逻辑
        pass

支持的平台:

平台 代码 API类型 备注
文心一言 wenxin LLM API 优先
Kimi kimi LLM API 优先
通义千问 tongyi LLM API 优先
豆包 doubao LLM API 优先
讯飞星火 xinghuo LLM API 优先
天工 tiangong LLM API 优先
清言 qingyan LLM API 优先

2.4 评分服务 (ScoringService)

模块职责: 计算品牌AI曝光度评分

评分算法 (依据 Visibili.ai模型):

class ScoringService:
    """评分计算服务"""

    WEIGHTS = {
        "mention_rate": 0.30,    # 提及率权重
        "sov": 0.40,            # SOV权重
        "quality": 0.30,        # 引用质量权重
    }

    async def calculate_brand_score(
        self,
        brand_id: UUID,
        time_range: TimeRange
    ) -> BrandScore:
        """计算品牌综合评分"""

        # 1. 获取引用数据
        citations = await self.citation_repo.get_by_brand_and_time(
            brand_id, time_range
        )

        # 2. 计算提及率
        mention_rate = self._calc_mention_rate(citations)

        # 3. 计算SOV
        sov = await self._calc_sov(brand_id, citations)

        # 4. 计算引用质量
        quality = self._calc_quality(citations)

        # 5. 综合评分 (加权求和后取上限100)
        overall = min(100, (
            mention_rate * self.WEIGHTS["mention_rate"] +
            sov * self.WEIGHTS["sov"] +
            quality * self.WEIGHTS["quality"]
        ))

        return BrandScore(
            overall=round(overall, 1),
            mention_rate=mention_rate,
            sov=sov,
            quality=quality,
            platform_breakdown=...,  # 平台分别评分
            trend=...,               # 趋势变化
        )

    def _calc_mention_rate(self, citations: list[Citation]) -> float:
        """计算提及率 = 被引用次数 / 总查询次数"""
        if not citations:
            return 0.0
        cited_count = sum(1 for c in citations if c.cited)
        return (cited_count / len(citations)) * 100

    def _calc_sov(self, brand_id: UUID, citations: list[Citation]) -> float:
        """计算SOV = 品牌引用次数 / (品牌+竞品引用次数)"""
        # 获取竞品引用数据
        competitor_citations = await self._get_competitor_citations(brand_id)
        total_citations = len(citations) + len(competitor_citations)
        if total_citations == 0:
            return 0.0
        return (len(citations) / total_citations) * 100

    def _calc_quality(self, citations: list[Citation]) -> float:
        """计算引用质量"""
        if not citations:
            return 0.0

        total_quality = 0.0
        for c in citations:
            # 情感系数
            sentiment_score = {"positive": 1.0, "neutral": 0.6, "negative": 0.2}.get(c.sentiment, 0.5)
            # 位置系数
            position_score = self._get_position_score(c.position)
            # 长度系数
            length_score = self._get_length_score(c.citation_text)

            quality = sentiment_score * 0.4 + position_score * 0.3 + length_score * 0.3
            total_quality += quality

        return (total_quality / len(citations)) * 100

    def _get_position_score(self, position: int) -> float:
        """获取位置系数"""
        if position == 1:
            return 1.0
        elif position <= 3:
            return 0.8
        elif position <= 5:
            return 0.6
        else:
            return 0.4

    def _get_length_score(self, text: str) -> float:
        """获取引用长度系数"""
        if not text:
            return 0.5
        length = len(text)
        if length > 100:
            return 1.0
        elif length >= 50:
            return 0.8
        else:
            return 0.6

2.5 缓存服务 (CacheService)

模块职责: 管理Redis缓存

缓存策略:

缓存键 数据 TTL 说明
brand:{id}:score 品牌评分 5min 实时性要求高
brand:{id}:stats 统计数据 5min 聚合数据
platform:config 平台配置 1h 相对稳定
user:{id}:session 会话信息 24h 用户会话
rate_limit:{id} 限流计数 1min 滑动窗口

缓存操作示例:

class CacheService:
    """缓存服务"""

    def __init__(self, redis: Redis):
        self.redis = redis

    async def get_brand_score(self, brand_id: UUID) -> Optional[BrandScore]:
        """获取品牌评分缓存"""
        key = f"brand:{brand_id}:score"
        data = await self.redis.get(key)
        if data:
            return BrandScore.parse_raw(data)
        return None

    async def set_brand_score(
        self,
        brand_id: UUID,
        score: BrandScore,
        ttl: int = 300
    ):
        """设置品牌评分缓存"""
        key = f"brand:{brand_id}:score"
        await self.redis.setex(key, ttl, score.json())

    async def invalidate_brand(self, brand_id: UUID):
        """失效品牌相关缓存"""
        pattern = f"brand:{brand_id}:*"
        async for key in self.redis.scan_iter(match=pattern):
            await self.redis.delete(key)

3. 接口设计

3.1 API设计规范

版本控制: URL路径包含版本号 /api/v1/

认证方式: Bearer Token (JWT)

请求格式:

{
  "content-type": "application/json"
}

响应格式:

{
  "code": 200,
  "message": "success",
  "data": {}
}

错误格式:

{
  "code": 400,
  "message": "错误描述",
  "detail": "详细错误信息"
}

3.2 认证接口

POST /api/v1/auth/register

请求:

{
  "email": "user@example.com",
  "password": "Password123",
  "confirm_password": "Password123"
}

响应 (201):

{
  "code": 201,
  "message": "注册成功",
  "data": {
    "id": "uuid",
    "email": "user@example.com",
    "plan": "free"
  }
}

POST /api/v1/auth/login

请求:

{
  "email": "user@example.com",
  "password": "Password123"
}

响应 (200):

{
  "code": 200,
  "message": "登录成功",
  "data": {
    "access_token": "eyJhbGciOiJIUzI1NiIs...",
    "token_type": "bearer",
    "expires_in": 86400,
    "user": {
      "id": "uuid",
      "email": "user@example.com",
      "plan": "free"
    }
  }
}

3.3 品牌接口

GET /api/v1/brands/

查询参数:

参数 类型 默认值 说明
skip int 0 偏移量
limit int 20 每页数量

响应 (200):

{
  "code": 200,
  "message": "success",
  "data": {
    "items": [
      {
        "id": "uuid",
        "name": "示例品牌",
        "platforms": ["wenxin", "kimi"],
        "frequency": "daily",
        "score": {
          "overall": 78,
          "trend": "+3"
        },
        "last_queried_at": "2026-05-01T00:00:00Z"
      }
    ],
    "total": 1
  }
}

POST /api/v1/brands/

请求:

{
  "name": "示例品牌",
  "aliases": ["示例", "example"],
  "platforms": ["wenxin", "kimi"],
  "frequency": "daily"
}

响应 (201):

{
  "code": 201,
  "message": "品牌创建成功",
  "data": {
    "id": "uuid",
    "name": "示例品牌",
    "status": "active"
  }
}

POST /api/v1/brands/{brand_id}/query/

请求:

{
  "platforms": ["wenxin", "kimi"]
}

响应 (202):

{
  "code": 202,
  "message": "查询任务已加入队列",
  "data": {
    "task_id": "uuid",
    "estimated_time": 30
  }
}

3.4 引用数据接口

GET /api/v1/citations/

查询参数:

参数 类型 说明
brand_id UUID 品牌ID
platform string 平台筛选
start_date date 开始日期
end_date date 结束日期
skip int 偏移量
limit int 每页数量

响应 (200):

{
  "code": 200,
  "message": "success",
  "data": {
    "items": [
      {
        "id": "uuid",
        "platform": "wenxin",
        "cited": true,
        "citation_text": "示例品牌是...",
        "position": 1,
        "sentiment": "positive",
        "queried_at": "2026-05-01T00:00:00Z"
      }
    ],
    "total": 100
  }
}

GET /api/v1/citations/stats/

查询参数:

参数 类型 说明
brand_id UUID 品牌ID

响应 (200):

{
  "code": 200,
  "message": "success",
  "data": {
    "overall_score": 78,
    "mention_rate": 65.5,
    "sov": 45.2,
    "quality": 72.3,
    "platform_breakdown": {
      "wenxin": {"score": 85, "cited": 45, "total": 50},
      "kimi": {"score": 72, "cited": 36, "total": 50}
    },
    "sentiment_breakdown": {
      "positive": 60,
      "neutral": 30,
      "negative": 10
    },
    "trend": [
      {"date": "2026-04-01", "score": 72},
      {"date": "2026-04-02", "score": 75}
    ]
  }
}

3.5 报告接口

GET /api/v1/reports/export/csv

查询参数:

参数 类型 说明
brand_id UUID 品牌ID
start_date date 开始日期
end_date date 结束日期

响应: CSV文件下载

GET /api/v1/reports/export/pdf

查询参数:

参数 类型 说明
brand_id UUID 品牌ID
type string weekly/monthly/custom

响应: PDF文件下载


4. 数据模型设计

4.1 实体关系图

┌──────────────┐       ┌──────────────┐       ┌──────────────┐
│    User      │       │    Brand     │       │ Competitor   │
├──────────────┤       ├──────────────┤       ├──────────────┤
│ id (PK)      │───1:N─│ id (PK)      │───1:N─│ id (PK)      │
│ email         │       │ user_id (FK) │       │ brand_id(FK)│
│ password_hash │       │ name         │       │ name         │
│ plan          │       │ aliases      │       │ aliases      │
│ max_queries  │       │ platforms    │       └──────────────┘
│ is_active     │       │ frequency    │
│ created_at    │       │ status       │
└──────────────┘       │ score        │
      │                │ last_queried │
      │                └──────────────┘
      │                      │
      │                ┌─────┴─────┐
      │                │           │
      │           ┌────────────┐ ┌────────────┐
      │           │CitationRec.│ │ QueryTask  │
      │           ├────────────┤ ├────────────┤
      │           │ id (PK)    │ │ id (PK)    │
      └───────────│ brand_id(FK)│ │ brand_id(FK)│
                  │ platform   │ │ platform   │
                  │ cited      │ │ status     │
                  │ sentiment  │ │ scheduled  │
                  │ position   │ │ started_at │
                  │ text       │ │ completed  │
                  │ confidence │ └────────────┘
                  │ match_type │
                  │ queried_at │
                  └────────────┘

4.2 数据库表结构

users

CREATE TABLE users (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    email VARCHAR(255) UNIQUE NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    name VARCHAR(100),
    plan VARCHAR(20) DEFAULT 'free',
    max_queries INTEGER DEFAULT 5,
    is_active BOOLEAN DEFAULT TRUE,
    email_verified BOOLEAN DEFAULT FALSE,
    verification_code VARCHAR(6),
    verification_code_expires TIMESTAMP,
    reset_token VARCHAR(255),
    reset_token_expires TIMESTAMP,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_plan ON users(plan);

brands

CREATE TABLE brands (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    name VARCHAR(50) UNIQUE NOT NULL,
    aliases JSONB DEFAULT '[]',
    website VARCHAR(500),
    industry VARCHAR(50),
    platforms JSONB NOT NULL DEFAULT '["wenxin", "kimi"]',
    frequency VARCHAR(20) DEFAULT 'weekly',
    status VARCHAR(20) DEFAULT 'active',
    last_queried_at TIMESTAMP,
    next_query_at TIMESTAMP,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_brands_user_id ON brands(user_id);
CREATE INDEX idx_brands_status ON brands(status);
CREATE INDEX idx_brands_next_query ON brands(next_query_at);

competitors

CREATE TABLE competitors (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    brand_id UUID NOT NULL REFERENCES brands(id) ON DELETE CASCADE,
    name VARCHAR(50) NOT NULL,
    aliases JSONB DEFAULT '[]',
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_competitors_brand_id ON competitors(brand_id);

citation_records

CREATE TABLE citation_records (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    brand_id UUID NOT NULL REFERENCES brands(id) ON DELETE CASCADE,
    platform VARCHAR(50) NOT NULL,
    cited BOOLEAN NOT NULL DEFAULT FALSE,
    citation_text TEXT,
    citation_position INTEGER,
    sentiment VARCHAR(20),
    competitor_brands JSONB DEFAULT '[]',
    raw_response TEXT,
    confidence FLOAT,
    match_type VARCHAR(20),
    queried_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_citations_brand_id ON citation_records(brand_id);
CREATE INDEX idx_citations_platform ON citation_records(platform);
CREATE INDEX idx_citations_queried_at ON citation_records(queried_at);
CREATE INDEX idx_citations_brand_platform ON citation_records(brand_id, platform);

query_tasks

CREATE TABLE query_tasks (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    brand_id UUID NOT NULL REFERENCES brands(id) ON DELETE CASCADE,
    platform VARCHAR(50) NOT NULL,
    status VARCHAR(20) NOT NULL DEFAULT 'pending',
    error_message TEXT,
    scheduled_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    started_at TIMESTAMP,
    completed_at TIMESTAMP
);

CREATE INDEX idx_query_tasks_brand_id ON query_tasks(brand_id);
CREATE INDEX idx_query_tasks_status ON query_tasks(status);
CREATE INDEX idx_query_tasks_scheduled ON query_tasks(scheduled_at);

5. 安全设计

5.1 认证与授权

JWT Token结构:

{
  "sub": "user_id",
  "email": "user@example.com",
  "plan": "free",
  "exp": 1717200000,
  "iat": 1717113600
}

Token配置:

  • 有效期: 24小时
  • 刷新策略: 支持刷新Token
  • 存储: HttpOnly Cookie

权限控制:

角色 品牌数限制 竞品数/品牌 每日查询次数
free用户 1个品牌 2个竞品 5次
pro用户 5个品牌 5个竞品 100次
admin 无限制 无限制 无限制

5.2 数据安全

传输加密: TLS 1.2+

存储加密:

  • 密码: bcrypt
  • 敏感字段: AES-256

数据隔离:

  • 租户级隔离 (user_id)
  • API级别鉴权

5.3 API安全

限流策略:

接口 限制
登录/注册 5次/分钟
查询接口 100次/分钟
全局 1000次/分钟

输入校验: Pydantic模型自动校验

SQL注入防护: SQLAlchemy参数化查询

XSS防护: 输出编码


6. 部署架构

6.1 Docker Compose架构

version: '3.8'

services:
  # 前端服务
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    environment:
      - NEXT_PUBLIC_API_URL=http://backend:8000
    depends_on:
      - backend
    volumes:
      - ./frontend:/app
      - /app/node_modules

  # 后端服务
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql+asyncpg://postgres:postgres@db:5432/geo_platform
      - REDIS_URL=redis://redis:6379/0
      - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}
    depends_on:
      - db
      - redis
    volumes:
      - ./backend:/app

  # 数据库
  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_DB=geo_platform
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres123
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"

  # Redis
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data

volumes:
  postgres_data:
  redis_data:

6.2 环境配置

.env配置示例:

# 数据库
DATABASE_URL=postgresql+asyncpg://postgres:postgres123@db:5432/geo_platform

# Redis
REDIS_URL=redis://redis:6379/0

# JWT
JWT_SECRET=your-super-secret-key-change-in-production
JWT_EXPIRE_HOURS=24

# LLM API
DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx

# CORS
CORS_ORIGINS=http://localhost:3000,https://geo.example.com

7. 监控与运维

7.1 监控指标

系统指标:

  • CPU使用率
  • 内存使用率
  • 磁盘使用率
  • 网络IO

应用指标:

  • API响应时间 (P50/P95/P99)
  • API错误率
  • 活跃用户数
  • 查询任务完成率

业务指标:

  • 品牌数量
  • 查询次数
  • 引用成功率

7.2 日志管理

日志级别:

  • DEBUG: 开发环境
  • INFO: 正常日志
  • WARNING: 警告
  • ERROR: 错误

日志格式:

{
  "timestamp": "2026-05-01T00:00:00Z",
  "level": "INFO",
  "service": "backend",
  "message": "Query completed",
  "context": {
    "brand_id": "uuid",
    "platform": "wenxin",
    "duration_ms": 1234
  }
}

7.3 告警策略

告警类型 触发条件 通知方式
服务宕机 HTTP 5xx > 5% 邮件+钉钉
响应超时 P99 > 2s 邮件
数据库连接 连接数 > 80% 邮件
API配额 使用率 > 90% 邮件

附录

A. 变更记录

版本 日期 变更内容 作者
v1.0 2026-05-01 初稿创建 技术团队
v1.1 2026-05-01 修正LLM成本估算增加定价依据来源 技术团队

B. 参考资料

  1. FastAPI最佳实践
  2. SQLAlchemy 2.0文档
  3. Next.js 14文档
  4. Redis缓存设计模式
  5. DeepSeek API定价 - 官方文档 - 2026-05核实
  6. OpenAI GPT-4o-mini定价 - 官方定价页 - 2026-05核实