Files
Neo-ZQYY/docs/prd/Neo_Specs/review-audit/P5.1-NS3-06.md
Neo 6f8f12314f feat: 累积功能变更 — 聊天集成、租户管理、小程序更新、ETL 增强、迁移脚本
包含多个会话的累积代码变更:
- backend: AI 聊天服务、触发器调度、认证增强、WebSocket、调度器最小间隔
- admin-web: ETL 状态页、任务管理、调度配置、登录优化
- miniprogram: 看板页面、聊天集成、UI 组件、导航更新
- etl: DWS 新任务(finance_area_daily/board_cache)、连接器增强
- tenant-admin: 项目初始化
- db: 19 个迁移脚本(etl_feiqiu 11 + zqyy_app 8)
- packages/shared: 枚举和工具函数更新
- tools: 数据库工具、报表生成、健康检查
- docs: PRD/架构/部署/合约文档更新

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 00:03:48 +08:00

71 lines
3.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# P5.1→NS3 缺失项 #6Token 用量监控和成本控制
## 简要结论
- 状态:⚠️ 部分解决
- 风险等级:🟠 中
- 已实现消息级 token 记录和 Prompt 长度截断,但缺少日/月预算控制、单次调用上限校验、超限熔断机制
## 详细审查
### 审查范围
- `apps/backend/app/ai/bailian_client.py` — 百炼 API 封装层
- `apps/backend/app/ai/conversation_service.py` — 对话持久化服务
- `apps/backend/app/ai/dispatcher.py` — AI 调用链调度器
- `apps/backend/app/ai/apps/app5_tactics.py` — 典型 App 调用流程
- `apps/backend/app/ai/cache_service.py` — 缓存服务
- `docs/database/ddl/zqyy_app__biz.sql` — biz schema DDL 基线
- `db/zqyy_app/migrations/` — 迁移脚本
### 发现
#### ✅ 已实现部分
1. **消息级 token 记录**`bailian_client.chat_json()` 返回 `(parsed_json, tokens_used)` 元组,从 `response.usage.total_tokens` 提取。所有 App3-8在调用后将 `tokens_used` 写入 `biz.ai_messages` 表。
2. **Prompt 长度截断**:各 App 的 `build_prompt()` 均实现了 system message 内容长度控制(如 App5 的 `_MAX_SYSTEM_CONTENT_LEN = 8000`),超长时截断服务记录、消费记录、备注等。
3. **API 层 max_tokens 参数**`chat_json()` 默认 `max_tokens=4000``chat_stream()` 默认 `max_tokens=2000`,限制了单次调用的输出 token 上限。
4. **数据库持久化**`biz.ai_messages` 表有 `tokens_used integer` 字段,每条 assistant 消息都记录了 token 消耗量。
#### ❌ 未实现部分
1. **无日/月预算控制**:代码中无任何按时间窗口(日/月)汇总 token 用量并与预算阈值比较的逻辑。
2. **无单次调用上限校验**`max_tokens` 是硬编码默认值,无基于配置表或环境变量的动态上限。
3. **无超限熔断机制**:当 token 消耗达到阈值时,无拒绝服务或降级处理逻辑。
4. **无 token 用量汇总表**:数据库中无 `ai_token_usage``ai_budget` 等汇总/预算表。
5. **无成本告警**:无日志告警或通知机制在 token 消耗异常时触发。
### 证据
**token 记录bailian_client.py L138**
```python
tokens_used = response.usage.total_tokens if response.usage else 0
return parsed, tokens_used
```
**消息写入conversation_service.py L77**
```python
INSERT INTO biz.ai_messages
(conversation_id, role, content, tokens_used)
VALUES (%s, %s, %s, %s)
```
**DDL 基线zqyy_app__biz.sql**
```sql
CREATE TABLE biz.ai_messages (
...
tokens_used integer,
...
);
```
**搜索 `token.*budget|cost.*control|usage.*limit|日预算|月预算` 无匹配结果**(仅匹配到缓存清理的"超限"字样,与 token 成本无关)。
### 建议
1. **新增 token 用量汇总视图或定时任务**:按 `site_id + app_id + 日期` 汇总 `biz.ai_messages.tokens_used`,写入 `biz.ai_token_daily_usage`
2. **新增预算配置**:在环境变量或配置表中定义 `AI_DAILY_TOKEN_LIMIT``AI_MONTHLY_TOKEN_LIMIT`
3. **在 dispatcher._run_step 前增加预算检查**:调用 AI 前查询当日/当月累计用量,超限则拒绝并记录日志
4. **告警机制**:当日用量达到预算 80% 时记录 WARNING 日志,达到 100% 时记录 ERROR 并熔断