Feat/ai billing jdk17#1079
Conversation
…el_call_log、ai_model_pricing、ai_budget_config、ai_budget_usage、ai_budget_log), 对应 5 个 DO、5 个 Mapper、5 个业务枚举和 3 个 ErrorCode
…ng 的完整 CRUD 接口(/ai/model-pricing)
… price_in_per_1m 等列名 - 流式回调 executeIgnore 改为 execute(tenantId) 修复 tenant_id 丢失 - OpenAiChatOptions 加 streamUsage(true) 修复豆包等模型流式token为0 - 同步修复 H2 测试 DDL 列名
…接口 + DefaultPricingStrategy + AiPricingStrategyManager - AiModelPricingDO新增strategy_type/strategy_config字段 - 修复AiBudgetChecker/AiBudgetUsageController写死MONTHLY导致DAILY配置不生效 - 修复流式接口预算超限时HttpMediaTypeNotAcceptableException - AiCostCalculator标记@deprecated,指向DefaultPricingStrategy - Redis key格式yyyyMM改为yyyyMMdd,支持DAILY周期 - 新增DefaultPricingStrategyTest + AiPricingStrategyManagerTest
…加方法 - AiBudgetChecker 适配原子累加逻辑 - AiBudgetUsageServiceImpl settle 改为原子累加
…lTest / AiBudgetUsageServiceImplTest 补充原子累加场景 - 新增 AiModelCallLogServiceImplTest / AiBudgetLogServiceImplTest / AiModelPricingServiceImplTest - create_tables.sql 同步更新测试 DDL
…插件,手动加 AND tenant_id 条件 - addUsage 通过 TenantContextHolder.getRequiredTenantId() 传入 tenantId - 单元测试 @beforeeach 设置 TenantContextHolder 匹配 H2 默认值
…ct 移到 insert 之前 - 预算超限抛异常时不会产生未执行的空消息/空任务记录
…务记录 insert 之前,超限时不留脏数据 - createCallLog 中 settle 移到 finally 块,日志写入失败也能结算预扣费 - settle 自身异常时 fallback 到 release,避免 Redis 预扣金额永久占用
- createBudgetConfig/updateBudgetConfig 新增唯一性校验(同租户同用户同周期类型) - H2 测试 DDL 同步加唯一索引 - 新增 BUDGET_CONFIG_DUPLICATE 错误码
- 原逻辑 MONTHLY 存在但禁用时直接返回 null,跳过 DAILY 检查 - 改为逐个检查 MONTHLY/DAILY 的启用状态,优先返回启用的配置
…hrows ServiceException
PR 计费策略说明之前的 PR 考虑到不同厂商计费策略差异较大,实现复杂度较高,且多数开源项目仅提供粗略或自定义计费方式,因此只实现了一套基础默认计费策略,可覆盖部分厂商。 但像阿里通义千问这类厂商模型,需要单独实现自定义计费策略。 当前 PR 的功能设计已具备完整扩展性,完全支持自定义计费策略。如需扩展,可参考开源项目:
|
后续可演进方向1. 账务防重与状态机显式化背景 规划 2. 多级存储对账与补偿机制背景 规划 3. 租户级预算热点行写优化背景 规划 4. 计费域与业务域的深度解耦背景 规划 5. 预估精度与精细化运营指标(Observability)背景 规划 |
背景
本 PR 完成 AI 模块 token 统计与预算计费主链路建设,目标是保证“可计量、可限额、可追溯、可告警”。
变更范围
yudao-module-aifeat/ai-billing主要改动
兼容性与影响
测试与验证
yudao-module-ai全量测试通过:备注