五金门店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 核心优势
- 极低门槛:¥161/月起步,无需GPU
- 零维护:API服务由MiniMax托管
- 弹性扩展:100家店和1000家店架构相同
- 快速迭代:模型更新由API提供方负责
- 自动学习:用户反馈自动聚类,知识持续更新
12.2 限制
- 离线场景无法使用(无网络时)
- 响应速度依赖网络延迟
- 批量处理有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. 上线监控和告警