大模型平台的计费与成本架构——多租户的 Token 计量与配额管理
大模型平台的计费与成本架构——多租户的 Token 计量与配额管理一、计费是商业化的基石大模型平台的商业化运营绕不开一个核心问题如何精确计量每个租户的 Token 消耗并进行准确计费。与传统的 SaaS 产品按功能或用户数计费不同LLM 平台本质上是按算力消耗计费——而 Token 就是算力消耗的核心度量单位。一个成熟的计费架构需要同时支撑毫秒级的实时 Token 累计、多模型差异化定价、多租户预充值/后付费/混合配额管理以及对账级别的账单准确性。二、计费架构的全局设计graph TB subgraph 租户管理层 TENANT[租户注册与配置] QUOTA[配额管理] PRICE[定价规则引擎] end subgraph 实时计量层 GW[AI 网关] -- METER[Token 计量引擎] METER -- CACHE[(Redis 实时累计)] METER -- STREAM[消息流 Kafka] end subgraph 准实时聚合层 STREAM -- AGG[流式聚合 Flink] AGG -- OLAP[(ClickHouse)] STREAM -- ALERT[超限告警] end subgraph 离线计费层 OLAP -- BILL[账单计算引擎] BILL -- INVOICE[(账单表)] BILL -- DEDUCT[余额扣减] end subgraph 控制面 ALERT -- BLOCK{超限阻断} BLOCK -- GW CACHE -- GW end三、Token 计量的核心挑战3.1 不同模型的 Token 计量方式不同不同模型对 Token 的定义存在差异——GPT 系列使用 cl100k_base 分词器Claude 使用自己的 tokenizerLlama 系列使用 BPE tokenizer。平台需要支持多种模型的 Token 计量适配/** * Token 计量引擎——多模型 Token 计数适配 */ Service public class TokenMeteringEngine { /** 模型 → Tokenizer 映射 */ private final MapString, Tokenizer tokenizerCache new ConcurrentHashMap(); /** 缓存大小上限——LRU 淘汰 */ private static final int MAX_CACHED_TOKENIZERS 20; /** * 计量一次推理请求的 Token 消耗 * * param request 推理请求元数据 * return Token 使用量摘要 */ public TokenUsageSummary meter(InferenceRequest request) { String modelName request.getModelName(); try { // Step 1: 获取对应模型的 Tokenizer Tokenizer tokenizer getTokenizer(modelName); // Step 2: 计算 Prompt Token实际生产中优先使用 API 返回值 int promptTokens request.getUsage().getPromptTokens(); int completionTokens request.getUsage().getCompletionTokens(); // Step 3: 如果 API 未返回 Token 数本地估算 if (promptTokens 0) { promptTokens tokenizer.countTokens( buildPromptText(request.getMessages())); } if (completionTokens 0) { completionTokens tokenizer.countTokens( request.getResponseText()); } int totalTokens promptTokens completionTokens; // Step 4: 计算实际费用 long costMicroDollars calculateCost(modelName, promptTokens, completionTokens); TokenUsageSummary summary TokenUsageSummary.builder() .requestId(request.getRequestId()) .tenantId(request.getTenantId()) .userId(request.getUserId()) .modelName(modelName) .promptTokens(promptTokens) .completionTokens(completionTokens) .totalTokens(totalTokens) .costMicroDollars(costMicroDollars) .timestamp(System.currentTimeMillis()) .build(); // Step 5: 实时累计到 Redis accumulateRealtime(summary); // Step 6: 异步发送至 Kafka 供流式聚合 publishToKafka(summary); return summary; } catch (Exception e) { log.error(Token 计量失败requestId{}, model{}, request.getRequestId(), modelName, e); // 计量失败不应该阻塞用户请求异步补偿 compensationService.markForCompensation(request); return TokenUsageSummary.unknown(request); } } /** * 多模型差异化定价计算 * 单位微美元1/1000000 USD避免浮点精度问题 */ private long calculateCost(String modelName, int promptTokens, int completionTokens) { PricingRule rule pricingService.getRule(modelName); // prompt 和 completion 通常不同价 long promptCost promptTokens * rule.getPromptPricePerMillionTokens() / 1_000_000L; long completionCost completionTokens * rule.getCompletionPricePerMillionTokens() / 1_000_000L; return promptCost completionCost; } /** * Redis 实时累计——支持毫秒级的配额检查 */ private void accumulateRealtime(TokenUsageSummary summary) { String key String.format(token:usage:%s:%s:%s, summary.getTenantId(), summary.getModelName(), LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE)); // Redis Lua 脚本保证原子性INCRBY 设置过期时间 String luaScript local current redis.call(INCRBY, KEYS[1], ARGV[1]) if current tonumber(ARGV[1]) then redis.call(EXPIRE, KEYS[1], ARGV[2]) end return current ; DefaultRedisScriptLong script new DefaultRedisScript(); script.setScriptText(luaScript); script.setResultType(Long.class); redisTemplate.execute(script, Collections.singletonList(key), String.valueOf(summary.getTotalTokens()), String.valueOf(86400 * 35) // 保存 35 天 ); } }四、配额管理与超限控制多租户平台需要支持预充值、后付费、试用额度等多种配额模型同时保证在配额耗尽时能及时阻断/** * 配额管理器——租户级 Token 使用额度检查与扣减 */ Service public class QuotaManager { private static final Logger log LoggerFactory.getLogger( QuotaManager.class); private final StringRedisTemplate redisTemplate; /** 配额检查的 Lua 脚本——原子化检查预留 */ private static final String QUOTA_CHECK_SCRIPT local quotaKey KEYS[1] -- 总配额 key local usedKey KEYS[2] -- 已使用 key local requested tonumber(ARGV[1]) -- 本次请求 Token 数 -- 1. 获取总配额 local totalQuota redis.call(GET, quotaKey) if not totalQuota then return -1 -- 配额未配置 end totalQuota tonumber(totalQuota) -- 2. 获取已使用量 local used redis.call(GET, usedKey) if not used then used 0 else used tonumber(used) end -- 3. 检查是否超限 if used requested totalQuota then return -2 -- 配额不足 end -- 4. 原子扣减 redis.call(INCRBY, usedKey, requested) return used requested -- 返回累计使用量 ; /** * 检查并扣减配额 * * param tenantId 租户 ID * param requestedTokens 请求消耗的 Token 数 * return 配额检查结果 */ public QuotaCheckResult checkAndDeduct(String tenantId, long requestedTokens) { String quotaKey quota: tenantId :total; String usedKey quota: tenantId :used: LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE); DefaultRedisScriptLong script new DefaultRedisScript(); script.setScriptText(QUOTA_CHECK_SCRIPT); script.setResultType(Long.class); Long result redisTemplate.execute(script, List.of(quotaKey, usedKey), String.valueOf(requestedTokens) ); if (result -1) { log.warn(租户 {} 无配额配置, tenantId); return QuotaCheckResult.notConfigured(); } if (result -2) { log.warn(租户 {} Token 配额不足当前使用已超限, tenantId); return QuotaCheckResult.exceeded(); } // 检查是否接近限额80%推送预警 Long totalQuota Long.valueOf( redisTemplate.opsForValue().get(quotaKey)); if (result totalQuota * 0.8) { alertService.sendQuotaWarning(tenantId, result, totalQuota); } return QuotaCheckResult.allowed(result, totalQuota); } }五、账单生成与对账账单需要同时保留两个维度的数据分钟级的时间序列数据供实时监控和告警和天级的聚合账单供结算和对账/** * 账单计算——基于 ClickHouse 的 OLAP 查询生成租户账单 */ Repository public class BillingRepository { private final JdbcTemplate clickHouseTemplate; /** * 生成指定租户的月度账单 * * param tenantId 租户 ID * param yearMonth 账单月份格式202607 * return 账单明细 */ public BillingStatement generateMonthlyBill(String tenantId, String yearMonth) { // 按模型汇总 Token 使用量 String sql SELECT model_name, sum(prompt_tokens) AS total_prompt_tokens, sum(completion_tokens) AS total_completion_tokens, sum(total_tokens) AS total_tokens, sum(cost_micro_dollars) / 1000000.0 AS total_cost_usd, count(DISTINCT user_id) AS active_users, count(DISTINCT request_id) AS total_requests FROM token_usage_hourly WHERE tenant_id ? AND toYYYYMM(timestamp) ? GROUP BY model_name ORDER BY total_cost_usd DESC ; try { ListModelBillingItem items clickHouseTemplate.query( sql, new Object[]{tenantId, Integer.parseInt(yearMonth)}, (rs, rowNum) - ModelBillingItem.builder() .modelName(rs.getString(model_name)) .totalPromptTokens(rs.getLong(total_prompt_tokens)) .totalCompletionTokens(rs.getLong(total_completion_tokens)) .totalTokens(rs.getLong(total_tokens)) .totalCostUsd(rs.getBigDecimal(total_cost_usd)) .activeUsers(rs.getInt(active_users)) .totalRequests(rs.getLong(total_requests)) .build() ); BillingStatement statement new BillingStatement(); statement.setTenantId(tenantId); statement.setBillingPeriod(yearMonth); statement.setItems(items); statement.setTotalCostUsd( items.stream() .map(ModelBillingItem::getTotalCostUsd) .reduce(BigDecimal.ZERO, BigDecimal::add) ); return statement; } catch (DataAccessException e) { log.error(账单生成失败tenant{}, period{}, tenantId, yearMonth, e); throw new BillingException(账单生成异常, e); } } /** * 账单对账——比对网关日志和计费系统的数据一致性 */ public ReconciliationReport reconcile(String date) { // 从网关日志统计 BigDecimal gatewayTotal getGatewayTotalCost(date); // 从计费系统统计 BigDecimal billingTotal getBillingTotalCost(date); BigDecimal diff gatewayTotal.subtract(billingTotal).abs(); BigDecimal diffPercent diff.divide(gatewayTotal, 4, RoundingMode.HALF_UP) .multiply(BigDecimal.valueOf(100)); ReconciliationReport report new ReconciliationReport(); report.setDate(date); report.setGatewayTotal(gatewayTotal); report.setBillingTotal(billingTotal); report.setDifference(diff); report.setDifferencePercent(diffPercent); // 差异超过 0.1% 触发告警 if (diffPercent.compareTo(BigDecimal.valueOf(0.1)) 0) { log.error(计费对账差异超阈值date{}, 差异{}%, gateway{}, billing{}, date, diffPercent, gatewayTotal, billingTotal); alertService.sendReconciliationAlert(report); } return report; } }六、成本优化视角计费系统不仅要关心收了多少钱还要与成本系统打通支持投入产出分析/** * 模型推理成本计算——将 GPU 使用时间折算为单次推理成本 */ Service public class InferenceCostCalculator { /** * 计算单次推理的实际成本 * * param modelName 模型名称 * param executionTimeMs GPU 执行时间毫秒 * param gpuType GPU 类型 * return 推理成本美元 */ public BigDecimal calculateInferenceCost( String modelName, long executionTimeMs, String gpuType) { // GPU 单价美元/小时——来自云服务商或自建机房核算 double gpuHourlyRate getGpuHourlyRate(gpuType); // GPU 利用率实际使用率通常 70%-85% double utilizationRate getGpuUtilizationRate(); // 实际 GPU 小时 执行时间 * 利用率修正 double gpuHours executionTimeMs / 3_600_000.0 / utilizationRate; // 推理成本 GPU 小时 * 单价 BigDecimal inferenceCost BigDecimal.valueOf(gpuHours * gpuHourlyRate); // 加上基础设施成本分摊网络、存储、运维人力 BigDecimal infrastructureOverhead inferenceCost.multiply(BigDecimal.valueOf(0.15)); // 15% 分摊 return inferenceCost.add(infrastructureOverhead); } }计费数据一致性的工程保障计费系统对数据一致性的要求极高——少计会导致收入损失多计会引发客户投诉和信任危机。我们的生产实践中计费链路的数据一致性问题主要出现在三个环节第一流式响应场景下的 Token 计数。SSE 流式输出时如果客户端中途断开连接LLM 可能已经生成了部分 Token 但未返回完整的 usage 信息。如果按 API 返回的 usage 计费会丢失这部分消耗。我们的解决方案是在 AI 网关层独立维护 Token 计数器——使用与模型一致的 tokenizer 对已发送的每个 chunk 进行本地计数即使客户端断开也至少能记录已生成的部分。这块的差异通常在 5%-10% 之间对账单准确性影响显著。第二分布式场景下的计费重复。当网关发送 Kafka 消息时at-least-once 语义可能出现同一请求的 Token 使用量被多次写入。我们在计费聚合层Flink使用requestId作为去重键配合 24 小时的去重窗口和 Bloom Filter 判定将重复率控制在 0.01% 以下。第三跨天计费的时间边界。部分长推理请求可能跨越 00:00 的日配额重置边界。我们的处理策略是以请求发起时间作为归属日在上层配额管理中按时间戳归日避免因跨天导致的配额计算偏差。此外多模型定价的差异化也对计费系统提出了挑战。同一个 Prompt 在不同模型上的 Token 化结果差异可达 15%-30%这会直接影响用户的成本感知。我们建议在管理面提供成本预览功能——用户在发送请求前可以预估各模型的 Token 消耗和费用帮助用户做出成本最优的模型选择也能有效降低事后的费用争议。七、计费架构的边界与 Trade-offs7.1 实时计费的延迟与一致性权衡Redis 实时累计方案的最大优势是毫秒级的配额检查响应但其代价是数据持久化的延迟。在我们的生产实践中Redis 异步写入 ClickHouse 的延迟通常在 3-8 秒这意味着用户在前端看到的今日已用 Token 量与实际情况之间存在时间窗差异。对于高频调用用户如每秒数十次推理请求这个时间窗内可能发生超额使用。解决方法是对高消耗租户单次请求超过 10 万 Token采用同步双写策略同时写入 Redis 和 ClickHouse确保实时账单的准确性但这会将高消耗请求的 P99 延迟增加约 15-20ms需要在网关层对这种请求单独处理。7.2 多租户场景下的资源隔离成本当多个租户共享同一套 GPU 推理集群时计费系统还需要处理资源隔离的问题。如果租户 A 的大量请求导致 GPU 显存占满会影响租户 B 的推理延迟。一种方案是为每个租户预留固定的 GPU 资源资源隔离但这样会大幅降低 GPU 整体利用率通常低于 40%。我们在生产中采用的方案是软隔离 优先级抢占默认所有租户共享资源池但当某个租户的 Token 消耗速率超过其购买配额的 2 倍时动态降低其请求优先级。这种方案的计费复杂度在于需要实时计算超额使用的惩罚费用需要在计费引擎中增加动态的单价调整逻辑。7.3 预付费与后付费的坏账风险预付费模式对平台现金流更友好但对用户的资金占用较高可能导致用户流失后付费模式用户体验更好但存在坏账风险。我们在生产中采用混合模式新注册用户默认后付费但当月消费超过 1000 美元时强制切换为预付费或提供信用卡担保。计费系统需要实时计算用户的信用风险评分基于历史付款及时性、账户余额趋势、调用量增长速度并在评分低于阈值时自动触发限额或暂停服务。这部分逻辑需要与计费系统深度集成在 Token 计量引擎中增加信用检查步骤通常增加的延迟在 5ms 以内基于 Redis 缓存的信用评分结果。八、总结大模型平台的计费架构需要同时兼顾实时性毫秒级配额检查、准确性微美元级费用计算和可靠性对账差异 0.1%。核心技术选型上推荐Redis Lua 脚本实现实时累计Kafka Flink实现准实时聚合ClickHouse存储历史账单数据。在业务层面至少需要支持预充值、后付费和混合配额三种模式并保持与成本系统的打通。数据一致性的保障需要从流式计数、幂等去重和时间边界三个维度同时治理。计费架构的设计不是一次性的工作而是需要随业务规模增长持续演进的系统工程。

相关新闻

卡美德生物科普:PcrV(铜绿假单胞菌毒力蛋白)基础实验研究指南

卡美德生物科普:PcrV(铜绿假单胞菌毒力蛋白)基础实验研究指南

PcrV 是铜绿假单胞菌 Ⅲ 型分泌系统中的关键毒力蛋白,广泛应用于微生物互作、宿主细胞免疫应答相关体外实验,是病原与上皮细胞共培养模型的核心检测靶点。本文系统梳理该蛋白分子特性、胞内调控通路、标准化检测方案与现有研究方向,为微生物方…

2026/10/18 6:01:11 阅读更多 →
从优衣库T恤上的乱码看Bash脚本混淆与逆向工程

从优衣库T恤上的乱码看Bash脚本混淆与逆向工程

从优衣库T恤上的乱码看Bash脚本混淆与逆向工程 在极客文化中,穿着带有代码片段的T恤是一种无声的宣言。最近,一件在零售店购买的优衣库T恤引发了技术社区的广泛讨论。这件T恤的背面印满了一长串看似毫无规律的字符——典型的Bash脚本混淆输出。这不仅仅是…

2026/10/18 6:01:12 阅读更多 →
内核启动核心——bootargs 启动参数详解与自定义配置

内核启动核心——bootargs 启动参数详解与自定义配置

内核启动核心——bootargs 启动参数详解与自定义配置本文由 黒漂技术佬 原创,首发于 CSDN,转载请注明出处。一、引言 前面我们学会了用 setenv 修改环境变量,今天要看的这个变量是 U-Boot 所有环境变量中的"王者"——bootargs。它决…

2026/10/18 1:56:00 阅读更多 →

最新新闻

OpenCowork 实测:支持本地文件、飞书机器人的 Windows AI 助手(只需配置 Token)

OpenCowork 实测:支持本地文件、飞书机器人的 Windows AI 助手(只需配置 Token)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:02:49 阅读更多 →
从Excel失控到自研轻量CRM:小团队客户管理实战复盘

从Excel失控到自研轻量CRM:小团队客户管理实战复盘

我最早有做 DeskcommCRM 这个项目的冲动,是因为团队里的客户信息已经乱到让人不敢打开共享盘:业务员各自维护 Excel,客服组的工单记录又是另一套系统,管理层想看一个客户的完整往来记录,得找三个人要三份文件&#xff…

2026/10/19 0:01:48 阅读更多 →
Claude Desktop 数据搬家教程(C盘 → D盘):用 robocopy 与 mklink 把数据目录改到 TaoToken

Claude Desktop 数据搬家教程(C盘 → D盘):用 robocopy 与 mklink 把数据目录改到 TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:01:48 阅读更多 →
openclaw.net 集成 ElBruno.MempalaceNet 记忆系统:把 MCP 配置改到 TaoToken 的完整实践

openclaw.net 集成 ElBruno.MempalaceNet 记忆系统:把 MCP 配置改到 TaoToken 的完整实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:01:48 阅读更多 →
GPT-6 Sol 与 Luna 怎么选?Chat、Work、Codex 版本差异与 TaoToken 接入实测

GPT-6 Sol 与 Luna 怎么选?Chat、Work、Codex 版本差异与 TaoToken 接入实测

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:01:48 阅读更多 →
VSCode开发UNI-APP配置教程:TaoToken统一Key接入与插件推荐

VSCode开发UNI-APP配置教程:TaoToken统一Key接入与插件推荐

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →