x

五金门店AI对话收银系统 - 自学习系统技术方案(纯API版)

本方案基于 MiniMax API 全云端计算,无需 GPU 服务器,极低成本实现智能化自学习能力。


一、概述

1.1 方案定位

本方案面向 100家门店规模 的五金零售场景,提供一套完整的人工智能自学习系统。系统通过持续学习用户表达习惯,自动优化意图识别和同义词归一化能力,大幅提升对话收银系统的智能化水平。

1.2 核心特点

特点 说明
零硬件投入 无需 GPU 服务器,所有计算通过 API 完成
极低门槛 月费用 ¥161 起,适合中小规模部署
零维护 API 服务由云端托管,无需操心运维
弹性扩展 100家店和1000家店架构相同,按需扩容
自动迭代 无需人工干预,系统自动学习和更新知识

1.3 技术路线

用户反馈 → 数据采集 → API聚类 → 知识更新 → 缓存刷新 → 效果验证
    ↑                                                            │
    └────────────────────────────────────────────────────────────┘
                           闭环迭代

二、系统架构

2.1 整体架构图

┌──────────────────────────────────────────────────────────────────┐
│                    纯API自学习系统架构                             │
│                                                                  │
│  ┌──────────────┐   ┌──────────────┐   ┌──────────────┐        │
│  │ 数据采集     │ → │ 特征处理     │ → │ 知识更新     │        │
│  │ (MySQL)     │   │ (API调用)    │   │ (API调用)    │        │
│  └──────────────┘   └──────────────┘   └──────────────┘        │
│          │                  │                  │                 │
│          ▼                  ▼                  ▼                 │
│  ┌──────────────────────────────────────────────────────┐       │
│  │              MiniMax API(全云端计算)                │       │
│  │  • Embedding API(向量化)                           │       │
│  │  • LLM API(语义分析/聚类/分类)                     │       │
│  └──────────────────────────────────────────────────────┘       │
│                          │                                       │
│                          ▼                                       │
│  ┌──────────────┐   ┌──────────────┐   ┌──────────────┐        │
│  │ 意图路由     │   │ 同义词发现   │   │ 效果验证     │        │
│  │ (查表+API)  │   │ (API聚类)   │   │ (A/B测试)   │        │
│  └──────────────┘   └──────────────┘   └──────────────┘        │
└──────────────────────────────────────────────────────────────────┘

2.2 数据流图

┌─────────────────────────────────────────────────────────────────┐
                        自学习数据流                              
└─────────────────────────────────────────────────────────────────┘

阶段1: 数据收集
────────────────────────────────
用户说"我要一箱螺钉"    系统无法识别意图
       
记录到 feedback_log 
┌─────────────────────────────────────┐
 id | original_text | intent | ... 
 1  | 一箱螺钉      | NULL   | ... 
└─────────────────────────────────────┘

阶段2: 定时聚类(每日/每周)
────────────────────────────────
SELECT original_text, COUNT(*)
FROM feedback_log
WHERE intent IS NULL
AND store_id = :store_id
AND user_id = :user_id
AND auth_allow = 1
GROUP BY original_text
HAVING COUNT(*) >= 5

       
store_id/user_id/auth_allow 一起传递
       
批量调用 MiniMax API
       
生成同义词簇和意图建议(带权限字段)

阶段3: 知识更新
────────────────────────────────
       
写入 synonym_table 表(pending状态
+ store_id/user_id/auth_allow 一起写入

       
写入 intent_mapping 
+ store_id/user_id/auth_allow 一起写入

       
记录 model_version 快照
+ store_id/user_id/auth_allow 一起记录

阶段4: 热更新
────────────────────────────────
Redis DEL intent:synonym:*
       
MySQL加载新词表到Redis
       
意图路由服务 reload(无需重启)

阶段5: 效果验证
────────────────────────────────
新用户说"我要一箱螺钉"
       
命中 canonical: 一盒螺丝钉  intent: buy
       
记录命中日志
       
A/B 测试对比新旧策略效果

三、硬件与软件配置

3.1 硬件配置(极简)

┌─────────────────────────────────────────┐
│         全量部署(1台服务器)             │
├─────────────────────────────────────────┤
│ CPU: 4核 (任意主流CPU)                   │
│ 内存: 8GB DDR4                          │
│ 磁盘: 100GB SSD                          │
│ 网络: 5Mbps带宽                         │
│ 月费用: ~150元(云服务器)               │
│                                         │
│ 软件:                                    │
│ - MySQL 8.4 LTS(反馈存储)             │
│ - Redis 7.0(缓存)                     │
│ - Python 3.10+(调度脚本)              │
│ - Cron(定时任务)                       │
└─────────────────────────────────────────┘

推荐云服务器配置:

厂商 规格 月费用
腾讯云 SA2 2核4G ¥100
阿里云 ecs.s6 2核4G ¥120
华为云 s6 2核4G ¥130

如果现有系统已有 MySQL 和 Redis,可直接复用,无需额外购买。

3.2 软件组件

组件 用途 资源 成本
MySQL 8.4 反馈日志、词表、样本库 4核8G ¥50/月
Redis 7.0 缓存意图路由、同义词表 复用服务器 ¥0

四、数据库设计

4.1 ER图

┌──────────────┐       ┌──────────────┐       ┌──────────────┐
│feedback_log │       │synonym_table │       │intent_mapping│
├──────────────┤       ├──────────────┤       ├──────────────┤
│id            │       │id            │       │id            │
│user_input    │       │canonical     │───────│canonical     │
│intent        │       │synonyms      │       │intent        │
│canonical     │       │source_count  │       │confidence    │
│confidence    │       │confidence    │       │is_system     │
│session_id    │       │status        │       │status        │
│store_id      │       │approved_by   │       │created_at    │
│created_at    │       │created_at    │       └──────────────┘
└──────────────┘       │updated_at    │               ▲
                       └──────────────┘               │
                              │                      │
                              ▼                      │
                       ┌──────────────┐              │
                       │model_version │
                       ├──────────────┤              │
                       │id            │              │
                       │version       │──────────────┘
                       │synonym_snap  │
                       │intent_snap  │
                       │traffic_split │
                       │status        │
                       └──────────────┘

4.2 表结构

-- 反馈日志表
CREATE TABLE feedback_log (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    user_input VARCHAR(500) NOT NULL,      -- 用户原始输入
    intent VARCHAR(100) DEFAULT NULL,       -- 系统识别的意图(NULL表示未识别)
    canonical VARCHAR(200) DEFAULT NULL,    -- 归一化后的标准说法
    confidence DECIMAL(5,4) DEFAULT NULL,  -- 置信度
    session_id VARCHAR(100),                -- 会话ID
    store_id VARCHAR(50) NOT NULL,         -- 门店ID(权限隔离)
    user_id VARCHAR(50) NOT NULL,          -- 用户ID(操作审计)
    auth_allow TINYINT(1) DEFAULT 1,       -- 是否有权限 0=无 1=有
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_created_at (created_at),
    INDEX idx_intent (intent),
    INDEX idx_canonical (canonical),
    INDEX idx_store_id (store_id),
    INDEX idx_user_id (user_id)
);

-- 同义词表(自动更新)
CREATE TABLE synonym_table (
    id INT AUTO_INCREMENT PRIMARY KEY,
    canonical VARCHAR(200) NOT NULL,        -- 标准说法
    synonyms JSON NOT NULL,                 -- 同义词列表(JSON数组)
    source_count INT DEFAULT 1,             -- 聚合的原始样本数
    confidence DECIMAL(5,4) DEFAULT 0.8,   -- 置信度
    status ENUM('pending', 'approved', 'rejected') DEFAULT 'pending',
    store_id VARCHAR(50) NOT NULL,         -- 门店ID(权限隔离)
    user_id VARCHAR(50) NOT NULL,          -- 用户ID(操作审计)
    auth_allow TINYINT(1) DEFAULT 1,        -- 是否有权限 0=无 1=有
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    approved_by VARCHAR(100),
    INDEX idx_canonical (canonical),
    INDEX idx_status (status),
    INDEX idx_store_id (store_id),
    INDEX idx_user_id (user_id)
);

-- 意图映射表
CREATE TABLE intent_mapping (
    id INT AUTO_INCREMENT PRIMARY KEY,
    canonical VARCHAR(200) NOT NULL,        -- 标准说法
    intent VARCHAR(100) NOT NULL,           -- 意图
    confidence DECIMAL(5,4) DEFAULT 1.0,   -- 置信度
    is_system ENUM('Y', 'N') DEFAULT 'N', -- 是否系统内置
    status ENUM('active', 'inactive') DEFAULT 'active',
    store_id VARCHAR(50) NOT NULL,         -- 门店ID(权限隔离)
    user_id VARCHAR(50) NOT NULL,          -- 用户ID(操作审计)
    auth_allow TINYINT(1) DEFAULT 1,       -- 是否有权限 0=无 1=有
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_intent (intent),
    INDEX idx_canonical (canonical),
    INDEX idx_store_id (store_id),
    INDEX idx_user_id (user_id)
);

-- 模型版本表(用于A/B测试)
CREATE TABLE model_version (
    id INT AUTO_INCREMENT PRIMARY KEY,
    version VARCHAR(50) NOT NULL,           -- 版本号
    synonym_table_snapshot JSON,            -- 当时的词表快照
    intent_mapping_snapshot JSON,           -- 当时的意图映射快照
    traffic_split INT DEFAULT 50,           -- 流量分配比例%
    status ENUM('active', 'archived') DEFAULT 'active',
    store_id VARCHAR(50) NOT NULL,         -- 门店ID(权限隔离)
    user_id VARCHAR(50) NOT NULL,          -- 用户ID(操作审计)
    auth_allow TINYINT(1) DEFAULT 1,       -- 是否有权限 0=无 1=有
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_status (status),
    INDEX idx_store_id (store_id),
    INDEX idx_user_id (user_id)
);

-- A/B测试结果表
CREATE TABLE ab_test_result (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    version_a INT,                           -- 版本A ID
    version_b INT,                           -- 版本B ID
    session_id VARCHAR(100),               -- 会话ID
    user_input VARCHAR(500),               -- 用户输入
    intent_a VARCHAR(100),                 -- 版本A识别结果
    intent_b VARCHAR(100),                 -- 版本B识别结果
    user_corrected VARCHAR(100),           -- 用户纠正的意图
    is_a_winner BOOLEAN,                  -- A是否正确
    is_b_winner BOOLEAN,                  -- B是否正确
    store_id VARCHAR(50) NOT NULL,         -- 门店ID(权限隔离)
    user_id VARCHAR(50) NOT NULL,          -- 用户ID(操作审计)
    auth_allow TINYINT(1) DEFAULT 1,       -- 是否有权限 0=无 1=有
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_created_at (created_at),
    INDEX idx_store_id (store_id),
    INDEX idx_user_id (user_id)
);

五、API调用设计

5.1 同义词发现API

import requests
import json

def batch_discover_synonyms(texts: list[str], store_id: int, user_id: int) -> list[dict]:
    """
    批量发现同义词(基于语义聚类)
    texts: 最多50条文本
    store_id: 门店ID(用于权限校验)
    user_id: 用户ID(用于权限校验)
    返回: [{canonical: str, synonyms: list[str], store_id: int, user_id: int, auth_allow: bool}]
    """
    prompt = f"""
你是一个同义词发现专家。以下是用户说的多条意思相同的话:
{json.dumps(texts, ensure_ascii=False)}

请识别它们表达的核心意思(canonical form),并列出所有同义词。

输出格式(JSON):
{{
  "canonical": "一盒螺丝钉",
  "synonyms": ["一箱螺钉", "螺钉一盒", "螺丝一盒"],
  "intent_hint": "buy",
  "store_id": {store_id},
  "user_id": {user_id},
  "auth_allow": true
}}

注意:
1. canonical是最规范、最常见的说法
2. synonyms是意思完全相同的表达
3. intent_hint是根据语境推测的意图(buy/search/query等)
4. store_id和user_id必须原样传递
5. auth_allow表示当前用户是否有权限执行该操作
6. 只返回JSON,不要其他文字
"""

    response = requests.post(
        "https://api.minimax.chat/v1/text/chatcompletion_pro",
        headers={
            "Authorization": f"Bearer {MINIMAX_API_KEY}",
            "Content-Type": "application/json"
        },
        json={
            "model": "MiniMax-M2.2-highspeed",
            "messages": [{"role": "user", "content": prompt}],
            "temperature": 0.3,  # 低温度保证稳定性
            "max_tokens": 500
        }
    )

    result = json.loads(response.json()["choices"][0]["message"]["content"])
    return result

5.2 新意图检测API

def detect_new_intent(texts: list[str], store_id: int, user_id: int) -> list[dict]:
    """
    检测是否是新意图
    texts: 用户说的多句话
    store_id: 门店ID(用于权限校验)
    user_id: 用户ID(用于权限校验)
    返回: [{text: str, is_new: bool, suggested_intent: str, reason: str, store_id: int, user_id: int, auth_allow: bool}]
    """
    prompt = f"""
你是一个意图识别专家。以下是用户说的话:
{json.dumps(texts, ensure_ascii=False)}

请判断:
1. 每句话属于哪个已知意图(buy/search/query/refund/hello/goodbye等)
2. 如果某句话不属于任何已知意图,标记为NEW意图

已知意图定义:
- buy: 购买商品
- search: 搜索商品
- query: 查询订单/价格/库存
- refund: 退货退款
- hello: 问候
- goodbye: 告别

输出格式(JSON数组):
[
  {{
    "text": "我要买螺丝钉",
    "is_new": false,
    "intent": "buy",
    "confidence": 0.95,
    "store_id": {store_id},
    "user_id": {user_id},
    "auth_allow": true
  }},
  {{
    "text": "能不能便宜点",
    "is_new": true,
    "suggested_intent": "negotiate",
    "reason": "这是砍价/议价意图,不在已知意图中",
    "store_id": {store_id},
    "user_id": {user_id},
    "auth_allow": true
  }}
]

注意:
1. store_id和user_id必须原样传递
2. auth_allow表示当前用户是否有权限执行该操作
"""

    response = requests.post(
        "https://api.minimax.chat/v1/text/chatcompletion_pro",
        headers={
            "Authorization": f"Bearer {MINIMAX_API_KEY}",
            "Content-Type": "application/json"
        },
        json={
            "model": "MiniMax-M2.2-highspeed",
            "messages": [{"role": "user", "content": prompt}],
            "temperature": 0.1,
            "max_tokens": 1000
        }
    )

    return json.loads(response.json()["choices"][0]["message"]["content"])

5.3 Embedding向量化

def get_embeddings(texts: list[str], store_id: int, user_id: int) -> list[dict]:
    """
    获取文本的向量表示(用于相似度计算)
    texts: 最多100条文本
    store_id: 门店ID(用于权限校验)
    user_id: 用户ID(用于权限校验)
    返回: [{text: str, embedding: list[float], store_id: int, user_id: int, auth_allow: bool}]
    """
    response = requests.post(
        "https://api.minimax.chat/v1/embeddings",
        headers={
            "Authorization": f"Bearer {MINIMAX_API_KEY}",
            "Content-Type": "application/json"
        },
        json={
            "model": "embo-01",
            "texts": texts,
            "store_id": store_id,
            "user_id": user_id
        }
    )

    result = response.json()["data"]
    # 补充权限字段
    for i, item in enumerate(result):
        item["store_id"] = store_id
        item["user_id"] = user_id
        item["auth_allow"] = True
    return result

5.4 权限校验说明

所有API调用必须携带权限字段,服务端需校验:

def validate_permission(store_id: int, user_id: int, action: str) -> bool:
    """
    校验用户是否有权限执行该操作
    store_id: 门店ID(多租户隔离)
    user_id: 用户ID
    action: 操作类型
    返回: 是否允许
    """
    # 1. 校验store_id是否属于该用户可访问范围
    # 2. 校验user_id是否有该action权限
    # 3. 返回auth_allow
    pass

# 调用示例
def call_api_with_permission(texts: list[str], store_id: int, user_id: int, action: str):
    auth_allow = validate_permission(store_id, user_id, action)
    if not auth_allow:
        return {"error": "Permission denied", "store_id": store_id, "user_id": user_id, "auth_allow": False}

    # 继续调用API...
    return {"store_id": store_id, "user_id": user_id, "auth_allow": True}

权限字段传递规则:

字段 说明 必须性
store_id 门店ID,用于多租户隔离 必须
user_id 用户ID,用于操作审计 必须
auth_allow 是否有权限执行该操作 必须

六、定时任务设计

6.1 任务列表

任务 频率 时长 说明
同步未识别反馈 每小时 <1分钟 把未识别的反馈同步到处理队列
同义词聚类 每天凌晨2点 5-30分钟 批量调用API聚类
新意图检测 每天凌晨2点 5-30分钟 检测是否有新意图
知识更新 每天凌晨3点 <5分钟 把新知识写入词表
Redis缓存刷新 每天凌晨3:05 <1分钟 热更新缓存
A/B测试统计 每天凌晨4点 <5分钟 统计各版本效果
模型切换 每周一凌晨 <1分钟 如果某版本持续领先,切换流量

6.2 Crontab配置

# 自学习系统定时任务(所有任务必须带 store_id 和 user_id 参数)
# 用法: self-learning [command] [store_id] [user_id]
0 * * * * /usr/local/bin/self-learning sync-pending 314 23
0 2 * * * /usr/local/bin/self-learning batch-clustering 314 23
0 2 * * * /usr/local/bin/self-learning detect-new-intents 314 23
0 3 * * * /usr/local/bin/self-learning update-knowledge 314 23
5 3 * * * /usr/local/bin/self-learning refresh-cache 314 23
0 4 * * * /usr/local/bin/self-learning ab-test-report 314 23
0 5 * * 1 /usr/local/bin/self-learning promote-winner 314 23

6.3 主调度脚本

#!/usr/bin/env python3
"""
self-learning: 自学习调度脚本
用法: self-learning [command]
"""

import sys
import os
import json
import time
from datetime import datetime
from typing import Optional, List, Dict

class SelfLearningScheduler:
    """自学习调度器"""

    def __init__(self, store_id: int = None, user_id: int = None):
        self.minimax_api_key = os.environ.get("MINIMAX_API_KEY", "")
        self.store_id = store_id  # 门店ID(权限隔离)
        self.user_id = user_id    # 用户ID(操作审计)
        self.db_config = {
            "host": os.environ.get("DB_HOST", "localhost"),
            "user": os.environ.get("DB_USER", "root"),
            "password": os.environ.get("DB_PASSWORD", ""),
            "database": os.environ.get("DB_NAME", "self_learning")
        }
        self.redis_config = {
            "host": os.environ.get("REDIS_HOST", "localhost"),
            "port": int(os.environ.get("REDIS_PORT", 6379)),
            "password": os.environ.get("REDIS_PASSWORD", "")
        }

    def timestamp(self) -> str:
        return datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    def _check_permission(self, action: str) -> bool:
        """检查权限:store_id和user_id必须有值才能执行写操作"""
        if self.store_id is None or self.user_id is None:
            return False
        # 可在此扩展更细粒度的权限校验
        return True

    def sync_pending(self, store_id: int = None, user_id: int = None):
        """同步未识别的反馈"""
        store_id = store_id or self.store_id
        user_id = user_id or self.user_id
        if not self._check_permission("sync_pending"):
            raise PermissionError(f"无权限执行 sync_pending: store_id={store_id}, user_id={user_id}")
        print(f"[{self.timestamp()}] 开始同步未识别反馈... store_id={store_id}, user_id={user_id}")
        # 1. 从 feedback_log 读取 intent=NULL 的记录(带权限校验)
        # 2. 批量写入处理队列(Redis list)
        # 3. 记录同步时间戳
        print(f"[{self.timestamp()}] 完成")

    def batch_clustering(self, store_id: int = None, user_id: int = None):
        """批量同义词聚类"""
        store_id = store_id or self.store_id
        user_id = user_id or self.user_id
        if not self._check_permission("batch_clustering"):
            raise PermissionError(f"无权限执行 batch_clustering: store_id={store_id}, user_id={user_id}")
        print(f"[{self.timestamp()}] 开始同义词聚类... store_id={store_id}, user_id={user_id}")
        # 1. 读取待处理文本(出现5次以上的,带store_id/user_id过滤)
        # 2. 按意图分组,每组最多50条
        # 3. 批量调用 MiniMax API 聚类
        # 4. 写入 synonym_table(status=pending,带权限字段)
        print(f"[{self.timestamp()}] 完成")

    def detect_new_intents(self, store_id: int = None, user_id: int = None):
        """检测新意图"""
        store_id = store_id or self.store_id
        user_id = user_id or self.user_id
        if not self._check_permission("detect_new_intents"):
            raise PermissionError(f"无权限执行 detect_new_intents: store_id={store_id}, user_id={user_id}")
        print(f"[{self.timestamp()}] 开始检测新意图... store_id={store_id}, user_id={user_id}")
        # 1. 读取待分析文本(带权限过滤)
        # 2. 调用 MiniMax 意图检测 API
        # 3. 标记新意图,等待人工确认
        print(f"[{self.timestamp()}] 完成")

    def update_knowledge(self, store_id: int = None, user_id: int = None):
        """更新知识库"""
        store_id = store_id or self.store_id
        user_id = user_id or self.user_id
        if not self._check_permission("update_knowledge"):
            raise PermissionError(f"无权限执行 update_knowledge: store_id={store_id}, user_id={user_id}")
        print(f"[{self.timestamp()}] 开始更新知识库... store_id={store_id}, user_id={user_id}")
        # 1. 读取 pending 状态的同义词(带store_id/user_id过滤)
        # 2. 写入/更新 intent_mapping(带权限字段)
        # 3. 记录 model_version 快照(带权限字段)
        print(f"[{self.timestamp()}] 完成")

    def refresh_cache(self, store_id: int = None, user_id: int = None):
        """刷新Redis缓存"""
        store_id = store_id or self.store_id
        user_id = user_id or self.user_id
        if not self._check_permission("refresh_cache"):
            raise PermissionError(f"无权限执行 refresh_cache: store_id={store_id}, user_id={user_id}")
        print(f"[{self.timestamp()}] 开始刷新缓存... store_id={store_id}, user_id={user_id}")
        # 1. 连接 Redis
        # 2. 删除旧缓存 keys: intent:synonym:*
        # 3. 从 MySQL 加载新词表(带store_id/user_id过滤)
        # 4. 写入 Redis Hash
        print(f"[{self.timestamp()}] 完成")

    def ab_test_report(self, store_id: int = None, user_id: int = None):
        """A/B测试统计"""
        store_id = store_id or self.store_id
        user_id = user_id or self.user_id
        print(f"[{self.timestamp()}] 开始A/B测试统计... store_id={store_id}, user_id={user_id}")
        # 1. 读取过去24小时的 ab_test_result(带权限过滤)
        # 2. 计算各版本准确率
        # 3. 输出报告到日志
        print(f"[{self.timestamp()}] 完成")

    def promote_winner(self, store_id: int = None, user_id: int = None):
        """升级获胜版本"""
        store_id = store_id or self.store_id
        user_id = user_id or self.user_id
        if not self._check_permission("promote_winner"):
            raise PermissionError(f"无权限执行 promote_winner: store_id={store_id}, user_id={user_id}")
        print(f"[{self.timestamp()}] 开始版本切换检查... store_id={store_id}, user_id={user_id}")
        # 1. 如果某版本连续3天领先>5%,提升其流量占比
        # 2. 更新 model_version.traffic_split(带权限字段)
        print(f"[{self.timestamp()}] 完成")

def main():
    command = sys.argv[1] if len(sys.argv) > 1 else "help"
    store_id = int(sys.argv[2]) if len(sys.argv) > 2 else None
    user_id = int(sys.argv[3]) if len(sys.argv) > 3 else None
    scheduler = SelfLearningScheduler(store_id=store_id, user_id=user_id)

    if hasattr(scheduler, command):
        getattr(scheduler, command)()
    else:
        print(f"未知命令: {command}")
        print("可用命令: sync-pending, batch-clustering, detect-new-intents, "
              "update-knowledge, refresh-cache, ab-test-report, promote-winner")
        print("示例: self-learning sync-pending 314 23")

if __name__ == "__main__":
    main()

七、API成本分析

7.1 假设条件

参数 数值
每日门店对话量 100次/店
门店数量 100家
总对话量 10,000次/天
未识别需处理比例 5%
每次聚类处理 500条

7.2 成本明细

项目 计算方式 单次tokens 单次费用 月费用
同义词发现 每天1次,每次500条 2,500 ¥0.025 ¥0.75
新意图检测 每天1次,每次500条 4,000 ¥0.04 ¥1.20
Embedding向量化 每天1次,每次500条 10,000 ¥0.01 ¥0.30
实时意图识别 1%兜底场景 100 ¥0.001 ¥3.00
Embedding缓存命中 90%场景命中 18,000 ¥0.018 ¥5.40
月度API总费用 ¥10.65

7.3 成本优化技巧

# 1. 批量处理减少API调用次数
# 坏:每条文本单独调用
# 好:每次批量50-100条

# 2. 缓存复用
# 用Redis缓存Embedding结果
# 相同文本只计算一次

# 3. 关键词快速过滤
# 先用关键词匹配,命中则不调用API
# 只对模糊输入调用API

# 4. 闲时处理
# 聚类任务安排在凌晨2点
# 避开API限流时段

八、成本汇总

8.1 月度费用

项目 配置 月费用
云服务器 4核8G 100G SSD ¥150
MySQL 复用服务器(不单独计费) ¥0
Redis 复用服务器(不单独计费) ¥0
MiniMax API 全部调用 ¥11
总计 ¥161/月

8.2 年费用

¥161 × 12 = ¥1,932/年

8.3 可选增值服务

服务 月费用 用途
云监控 ¥30 告警、日志
自动备份 ¥20 MySQL自动备份
CDN加速 ¥50 意图路由API加速
合计可选 ¥100/月

九、扩容路径

起步(¥161/月)
    │
    ├─ 100家门店
    ├─ 每日1万次对话
    ├─ 每日500条聚类
    └─ API全云端
            │
            ▼ (业务增长后)
¥500/月
    ├─ 独立MySQL(升级配置)
    ├─ Redis独立部署
    ├─ 意图路由多实例
    └─ 每日5万次对话
            │
            ▼ (全国推广)
¥2000/月
    ├─ MySQL主从
    ├─ Redis Cluster
    ├─ 意图路由集群
    └─ 每日50万次对话

十、与GPU方案对比

对比项 GPU方案 纯API方案
月费用 ¥3000+ ¥161
硬件投入 ¥20000+ ¥0
部署难度 复杂(GPU驱动/CUDA) 简单(Python脚本)
维护成本 高(模型更新/硬件故障) 低(API托管)
响应速度 快(本地) 中等(API延迟)
扩展性 受GPU限制 无限扩展
适合规模 中大型(100+店) 小中型(1000店内)

十一、核心技术组件选型

11.1 技术栈总表

组件 用途 技术选型 成本
数据存储 反馈日志、词表 MySQL 8.4 ¥0(复用)
缓存 意图路由、同义词 Redis 7.0 ¥0(复用)
向量检索 语义相似度 MiniMax API ¥5.7/月
语义分析 聚类/分类 MiniMax LLM API ¥2.95/月
调度编排 定时任务 Python + Cron ¥0
监控 日志/告警 云监控(可选) ¥30/月

11.2 MySQL版本选择

版本 状态 推荐度
MySQL 7.2 之前 已停止支持 ❌ 不建议
MySQL 8.0.x 当前稳定版 ✅ 推荐
MySQL 8.4 LTS 最新LTS,支持到2029年 首选
MySQL 9.0 创新版本 ⚠️ 观望

推荐 MySQL 8.4 LTS

  • 2024年发布,长期支持到2029年
  • 完全兼容 MySQL 8.0 语法
  • 性能优化,资源占用更低
  • 安装命令:dnf install mysql-server -y(CentOS Stream 9)

十二、总结

12.1 核心优势

  1. 极低门槛:¥161/月起步,无需GPU
  2. 零维护:API服务由MiniMax托管
  3. 弹性扩展:100家店和1000家店架构相同
  4. 快速迭代:模型更新由API提供方负责
  5. 自动学习:用户反馈自动聚类,知识持续更新

12.2 限制

  1. 离线场景无法使用(无网络时)
  2. 响应速度依赖网络延迟
  3. 批量处理有QPS限制

12.3 适用场景

场景 是否适合
1-100家门店 ✅ 非常适合
100-1000家门店 ✅ 适合
1000家以上 ⚠️ 需增加缓存层和API配额
离线/内网环境 ❌ 不适合

12.4 结论

100家门店规模下,纯API方案完全够用,且成本极低。建议先用 MVP 方案跑通流程,确认业务价值后再按需升级。


附录:快速启动清单

  • [ ] 1. 申请 MiniMax API Key
  • [ ] 2. 部署 MySQL 8.4 LTS
  • [ ] 3. 部署 Redis 7.0
  • [ ] 4. 创建数据库和表结构
  • [ ] 5. 部署 Python 调度脚本
  • [ ] 6. 配置 Crontab 定时任务
  • [ ] 7. 配置 Redis 缓存热更新
  • [ ] 8. 联调测试完整流程
  • [ ] 9. 上线监控和告警
Left-click: follow link, Right-click: select node, Scroll: zoom
x