文档状态:可进入技术评审 编写日期:2026-09-01 涉及仓库:
claude-code-voc-intelligence、future-server、fmode-studio、voc-profit-web
当前企业用户已经能使用 VOC 技能完成批量社媒监听、电商商品采集和报告生成,但在成本侧存在四个直接影响交付的问题:
本方案目标是形成一个统一闭环:
任务理解
-> 生成采集计划
-> 查询当前生效价目
-> 返回低/中/高三档成本预估
-> 检查余额与预算上限
-> 携带任务追踪标识执行
-> 余额不足时由 Agent 拼接现有 Balance 直达链接或取得现有支付二维码
-> 现有充值链路完成支付和余额刷新,Agent 从本地检查点继续
-> 记录每次实际扣费
-> 缓存采集结果中的多媒体到本地任务目录
-> 按任务/报告/模块/接口出账单
-> AI 给出高成本低价值项的优化建议
本方案不在技能包、报告、日志或示例中保存账号密钥、会话令牌、API Key。历史敏感清单仅作为账户归属核对输入,不进入代码和 Git。
用户用自然语言提问:
AI 应返回:
本节记录方案启动时的缺口,便于对照改造范围;当前实现状态以第 18.1 节和第 21 节的验收记录为准。
相关文件:
skills/voc-api-catalog/SKILL.mdmcp/catalog/voc-social-endpoints.jsonmcp/src/core/api-catalog.jsmcp/src/core/credentials.jsmcp/src/core/payment-links.jsmcp/src/core/activation.jsmcp/src/tools/voc-api-catalog-run.jsmcp/src/providers/voc-gateway.jsmcp/src/providers/ecommerce-gateway.jsmcp/src/providers/overseas-gateway.jsmcp/src/providers/xiaohongshu-api.jsmcp/src/providers/douyin-api.jsmcp/src/features/xiaohongshu-trend/live-collector.jsmcp/src/features/douyin-trend/live-collector.jsmcp/src/features/voc-business-workflow/business-workflow.jsmcp/src/features/fmode-image-analysis/image-analysis.jsmcp/src/server.js已具备:
缺少:
usageTraceId/reportId/skillId/stepId 等用量关联字段。sk- NewAPI Token 与 r: Session Token,并让专用采集器和通用网关共享同一计费/充值上下文。相关文件:
fmode-server/modules/shared/newapi-metering.tsfmode-server/modules/voc-social-api/src/routes.tsfmode-server/modules/voc-e-commerce/src/routes.tsfmode-server/modules/voc-ecom-api/src/routes.tsapi/api-ncloud/fmode/routes.jsapi/api-ncloud/fmode/doc/migrate-apig-newapi-billing.jsapi/api-ncloud/profit/service/revenue.service.js已具备:
APIGNewApiBillingMap 保存模块级 model/service/billingMode/priceCny/quota。chargeNewApiUsage() 同步扣减用户和 token 额度,并写入 NewAPI logs。logs.other 已记录 billing_source/apig_id/price_cny/billing_mode/request_path/source/service。requestId 幂等控制。source。关键缺口:
APIGNewApiBillingMap 只到模块/模型级,无法表达每个 proxyPath 的单价、计费单位和生效版本。pathQuota 可以改变实际扣除额度,但日志中的 price_cny 仍来自模块级映射;现有看板在 per_call 模式下优先使用 price_cny,可能出现路径级扣额与展示金额不一致。logs 没有报告和任务关联字段,历史任务只能按用户和时间窗口猜测,不能形成可审计的单报告账单。/api/fmode/newapi/user 返回余额、充值和订阅,不返回模块、任务、接口用量。r: Session 分支仍扣减旧 APIGAuth.count,未进入 NewAPI 通用余额和日志,和本需求的新模式冲突。USDExchangeRate 和每单位 500,000 quota;路径 quota 与日志人民币金额没有共享同一个解析结果。相关文件:
projects/fmode-studio/src/components/balance-modal.component.tsprojects/fmode-studio/src/modules/launcher/balance-page.component.tsprojects/fmode-studio/src/modules/launcher/auth-guard.service.tsprojects/fmode-studio/src/app/app.routes.tsprojects/fmode-studio/src/modules/launcher/fmode-home.component.ts已具备:
/balance 页面已经支持 ?token=,调用 Parse.User.become() 后立即从地址栏移除 Token。/api/fmode/recharge/order → pay_code2 → order_status2 完成建单、二维码、轮询和到账刷新。以上能力已在 fmode-studio 远端 origin/master 的 97c64bc、d5ae86f、e9ade0b 及 future-server 的 af2541aa 中核实。本需求复用现有充值中心,不重做支付页面和订单逻辑。
缺少:
相关文件:
voc-profit-web/client/src/app/api.service.tsvoc-profit-web/client/src/app/dashboard.component.*future-server/api/api-ncloud/profit/routes.jsfuture-server/api/api-ncloud/profit/service/revenue.service.js可复用能力:
module-forwarding 的模块、端点、用户、最近调用聚合。upstream-cost 的收入、上游成本、缓存率和利润分析。复用原则:
voc-profit-web。user_id,不能复用管理员全量返回。| 账本 | 含义 | 面向对象 |
|---|---|---|
| 用户消费账 | 用户实际被扣除的额度与人民币金额 | 用户、AI、客服 |
| 上游成本账 | 平台向数据供应商和模型供应商支付的成本 | 运营、财务、产品 |
| 现金与充值账 | 用户充值、钱包划转、订阅购买 | 用户、财务 |
本期余额页重点展示用户消费账和现金充值账;上游成本与毛利继续留在管理员经营看板,避免把内部采购价暴露给普通用户。
后端计费引擎是单价和实扣的权威来源。技能目录可以缓存公开价目快照,但不能自行维护另一套单价。Agent 通过接口读取当前价格后,按照自己生成的业务调用计划完成报价计算;服务端不替 Agent 决定报告方案和调用次数。
扣费、日志金额、余额页和 Agent 报价所读取的单价必须来自同一个规则解析函数:
resolveBillingRule(model, method, path, effectiveAt)
-> billingMode
-> unitName
-> unitPriceCny
-> quotaPerUnit
-> pricingVersion
-> cachePolicy
estimatedCostCny:执行前根据计划计算。budgetLimitCny:Agent 执行时遵守的用户预算上限,不冻结、不预扣 NewAPI 余额。actualCostCny:成功扣费日志汇总。unpricedCostCny:缺少有效价目、只能按兜底规则估算的部分。前端和 AI 不得把估算值显示为已消费。
每次复杂报告执行由 Agent 本地生成 usageTraceId,每份输出可生成 reportId。所有 VOC 请求和可关联的大模型请求都携带同一 usageTraceId。
usageTraceId 只是用量日志标签,用于精确拆分不同报告的接口频次和消费。它不是订单号,不创建独立余额,不冻结资金,也不改变扣费方式;所有调用仍然实时扣除同一用户的 NewAPI 通用余额。
历史任务没有这些字段时可以提供“按时间窗口推算”,但必须标记为 reconstructed,不能标记为精确账单。
VOC 技能余额不足时,不让用户重新登录和寻找充值入口,由仍可运行的 Agent 完成充值前测算。默认优先返回二维码,自助链接作为另一种方式:
/api/fmode/recharge/order 和 pay_code2,由 Agent 组装现有支付请求参数并直接返回支付二维码。https://app.fmode.cn/dev/studio/balance/?token=USER_TOKEN,用户进入现有 Balance 页面自行选择金额。充值增加的是用户 NewAPI 通用余额,不是购买某个任务。充值订单不与 usageTraceId 做财务绑定;追踪标识只用于执行前后测算和实际账单归集。
| 余额不足类型 | 发生位置 | 谁还能执行 | 正确处理 |
|---|---|---|---|
| Agent 模型账户余额不足 | 大模型/NewAPI 模型调用返回 402 | Agent 已经不能继续生成回复或调用技能 | 由 Studio、OpenClaw 或 Agent 宿主运行时拦截 402,直接展示现有 Balance 链接/充值卡片;同时在耗尽前做预警 |
| VOC 技能数据余额不足 | VOC 网关或 Skill 调用返回 needs_recharge |
Agent 模型仍可工作 | Skill 强制计算剩余成本,默认组装支付请求返回二维码,也提供带 Token 的 Balance 链接 |
Skill 规则只能解决第二类。第一类不能设计成“让 Agent 再调用一个支付工具”,因为模型余额耗尽后这一步已经没有执行条件;必须由不依赖模型推理的宿主 UI/运行时完成兜底。
所有 VOC 采集结果中出现的图片、视频、音频及封面文件必须进入统一媒体流水线:
outputs/<usageTraceId>/assets/。sourceUrl 中用于溯源,不作为报告主要展示地址。APIGEndpointPricing不建议继续把大量路径规则塞进运行时 pathQuota 配置。新增可查询、可版本化的数据表:
| 字段 | 类型 | 说明 |
|---|---|---|
objectId |
string | 主键 |
model |
string | voc-social / voc-e-commerce / voc-ecom |
channel |
string | social / ecommerce / overseas |
endpointId |
string | 技能清单中的稳定 ID |
method |
string | HTTP 方法 |
proxyPath |
string | 规范化路径,不含 query |
billingMode |
string | per_call / per_page / per_item / per_minute / per_token |
unitName |
string | 次、页、商品、账号、分钟、千 token 等 |
unitPriceCny |
number | 对用户展示的单位价格 |
quotaPerUnit |
integer | 实际扣除额度 |
cachePolicy |
string | same_as_upstream / discounted / free |
cacheQuotaPerUnit |
integer/null | 缓存命中的扣额 |
pricingVersion |
string | 如 2026-09-01.1 |
effectiveFrom |
date | 生效时间 |
effectiveTo |
date/null | 失效时间 |
enabled |
boolean | 是否启用 |
source |
string | 价格来源和校准方式 |
metadata |
object | 标题、说明、限制等非敏感信息 |
匹配优先级:
model + method + proxyPath 精确匹配。model + endpointId 匹配。APIGNewApiBillingMap 模块级规则。unpriced;生产扣费是否允许兜底由服务配置决定。UsageTrace| 字段 | 类型 | 说明 |
|---|---|---|
usageTraceId |
UUID | Agent 本地生成的一次报告执行标识,不是支付或扣款 ID |
clientId |
string/null | 安装实例或 Agent 标识,自报标签 |
skillId |
string | 如 voc-api-catalog |
workflowType |
string | 如 xhs_account_monitor、tmall_listing_audit |
title |
string | 用户可读任务名 |
reportId |
string/null | 报告或输出标识 |
stepId |
string/null | 当前采集步骤 |
budgetLimitCny |
number/null | Agent 本地预算上限,不冻结余额 |
estimateLowCny |
number | 低值 |
estimateExpectedCny |
number | 预期值 |
estimateHighCny |
number | 高值 |
pricingVersion |
string | 预估时价目版本 |
plan |
object | Agent 本地保存的结构化调用计划,不含密钥 |
首期不要求服务端新增 UsageTask 表或任务 CRUD API。追踪上下文写入本地检查点和 NewAPI logs.other 即可;当前用户用量接口按 usageTraceId 聚合实际日志。
UsageReport| 字段 | 类型 | 说明 |
|---|---|---|
reportId |
UUID | 报告 ID |
usageTraceId |
UUID | 所属执行追踪标识 |
reportType |
string | 日报、排行、Listing 诊断等 |
title |
string | 报告名称 |
artifactUrl |
string/null | 交付地址,可选 |
scope |
object | 账号数、商品数、日期等 |
status |
string | partial/completed/failed |
不新增与报告绑定的 BillingPaymentSession。充值继续使用现有支付订单、钱包账本、NewAPI top_ups 和余额刷新逻辑。Agent 只提供建议金额和访问方式,不建立一次性任务支付关系。
media-manifest.json每次报告执行生成 outputs/<usageTraceId>/assets/media-manifest.json:
{
"usageTraceId": "USAGE_TRACE_ID",
"items": [
{
"mediaId": "MEDIA_ID",
"entityType": "note",
"entityId": "ENTITY_ID",
"mediaType": "image",
"sourceUrl": "SOURCE_URL",
"localPath": "outputs/USAGE_TRACE_ID/assets/xiaohongshu/ENTITY_ID/HASH.jpg",
"cloudUrl": null,
"effectiveUrl": "outputs/USAGE_TRACE_ID/assets/xiaohongshu/ENTITY_ID/HASH.jpg",
"mimeType": "image/jpeg",
"bytes": 123456,
"sha256": "HASH",
"cacheStatus": "cached",
"uploadStatus": "disabled_local_only"
}
]
}
effectiveUrl 固定取 localPath,cloudUrl 固定为 null,uploadStatus 固定为 disabled_local_only。报告生成器只能消费 effectiveUrl。
logs.other 扩展字段继续使用现有 logs 作为实际扣费事实表,在 other 中增加:
{
"billing_source": "apig",
"service": "voc-social-api",
"request_path": "TARGET_PATH",
"request_method": "GET",
"source": "upstream",
"endpoint_id": "xiaohongshu.get_user_note_list_v4",
"usage_trace_id": "USAGE_TRACE_ID",
"report_id": "REPORT_ID",
"skill_id": "voc-api-catalog",
"workflow_type": "xhs_account_monitor",
"step_id": "collect_account_notes",
"client_id": "CLIENT_ID",
"billing_mode": "per_call",
"unit_name": "call",
"unit_count": 1,
"unit_price_cny": 0.1,
"actual_cost_cny": 0.1,
"pricing_version": "2026-09-01.1",
"cache_policy": "same_as_upstream"
}
约束:
actual_cost_cny 必须由本次实际扣除 quota 和已解析规则生成,不再从模块级 price_cny 反推。userId/tokenId 只能从鉴权结果得到,不能接受客户端覆盖。clientId 是展示维度,不作为强权限边界;同一账户共享同一密钥时,Agent 归属只能视为自报标签。统一前缀建议使用 /api/fmode/billing。同时支持两种身份:
Authorization: Bearer <NewAPI key>。所有返回只包含当前账户数据。
接口数量边界:计费、报价数据准备和用户用量只新增下面一个 billing/query 聚合接口,通过 include 和筛选入参一次返回 Agent 当前所需数据;Agent 在本地生成计划并计算报价。充值复用现有 3 个调用,不新增支付接口。媒体本轮只落本地,不调用 Storage 接口。
新增一个聚合接口,同时服务 Agent 报价和 Balance 页面:
POST /api/fmode/billing/query
Authorization: Bearer USER_TOKEN
Content-Type: application/json
Agent 执行前只查询余额和候选接口价格:
{
"include": ["balance", "pricing"],
"pricingFilter": {
"channels": ["social"],
"endpointIds": [
"xiaohongshu.search_user_v2",
"xiaohongshu.get_user_note_list_v4",
"xiaohongshu.get_note_comments_v3"
]
}
}
以上是 Agent/MCP 内部结构,不是要求用户填写的表单。用户继续用自然语言描述任务,Agent 负责抽取范围、补默认值并生成候选调用计划。
Balance 页面查询当前用户用量:
{
"include": ["balance", "pricing", "usage"],
"pricingFilter": {
"channels": ["social", "ecommerce", "overseas"]
},
"usageFilter": {
"from": "2026-08-30",
"to": "2026-09-01",
"usageTraceId": "USAGE_TRACE_ID",
"groupBy": ["module", "endpoint", "usageTraceId"],
"page": 1,
"pageSize": 100
}
}
统一响应:
{
"code": 200,
"data": {
"balance": {
"availableCny": 30,
"usedCny": 120
},
"pricing": {
"version": "2026-09-01.1",
"currency": "CNY",
"items": [
{
"endpointId": "xiaohongshu.get_user_note_list_v4",
"channel": "social",
"method": "GET",
"proxyPath": "TARGET_PATH",
"billingMode": "per_call",
"unitName": "次",
"unitPriceCny": 0.1,
"quotaPerUnit": 7353,
"cachePolicy": "same_as_upstream"
}
]
},
"usage": {
"totals": {
"calls": 280,
"billedCalls": 280,
"quota": 2058840,
"costCny": 28
},
"groups": [],
"quality": "exact"
}
}
}
接口约束:
include、groupBy、时间范围、接口数量和分页大小均使用服务端白名单和上限。user_id,usageTraceId 只是附加筛选条件。quality=exact 表示日志有追踪标识和实际金额;历史数据继续标记 mixed/reconstructed。充值中心已有余额展示、金额选择、二维码、支付轮询和到账刷新能力,本需求不重新实现这套支付链路。提供两种方式:
方式一,用户自助选择金额:
https://app.fmode.cn/dev/studio/balance/?token=USER_TOKEN
独立 Balance 页已经消费 token 完成免登录识别,并在识别后从地址栏移除。用户进入页面后自行选择充值金额。
方式二,默认由 Agent 直接返回支付二维码:
POST /api/fmode/recharge/order
POST /parse/functions/pay_code2
POST /parse/functions/order_status2
Agent 根据建议充值金额生成 tradeNo,调用现有 recharge/order 创建或复用 AccountLog,再调用 pay_code2 取得 code_url 并渲染二维码。需要等待到账时复用 order_status2;这三步均为现有链路,不新增 billing 支付接口。
统一交互规则:
usageTraceId、报告和单次任务不做财务绑定。/api/fmode/billing/query 查询最新余额,并从本地检查点继续。本轮明确采用本地优先且线上禁用的策略,不新增或调用 Storage 上传接口。媒体处理流程如下:
outputs/<usageTraceId>/assets/<platform>/<entityId>/,按 SHA-256 去重。media-manifest.json 记录 sourceUrl、localPath、摘要、MIME、大小和缓存状态。effectiveUrl 一律使用本地相对路径。cloudUrl 固定为 null,uploadStatus 固定为 disabled_local_only。storage/profile、预签名 URL 或上传完成接口,避免消耗线上 Storage 资源。newapi-metering.ts把当前 resolveQuota() 升级为 resolveBillingRule(),返回完整规则:
type ResolvedBillingRule = {
quota: number;
billingMode: string;
unitName: string;
unitCount: number;
unitPriceCny: number;
actualCostCny: number;
pricingVersion: string;
cachePolicy: string;
matchedBy: "endpoint" | "module" | "fallback";
};
chargeNewApiUsage() 返回值增加:
{
quota,
costCny,
pricingVersion,
userId,
tokenId,
channelId,
logId
}
并将解析后的真实金额写入日志。这样余额页不再依赖可能失真的模块级 price_cny。
对 voc-social-api、voc-e-commerce、voc-ecom-api 做同样改造:
proxyPath 并映射 endpointId。assertNewApiQuotaAvailable() 与 chargeNewApiUsage() 使用同一条已解析规则。成功响应增加非敏感计费头:
X-Fmode-Usage-Quota: 7353
X-Fmode-Usage-Cny: 0.100000
X-Fmode-Pricing-Version: 2026-09-01.1
X-Fmode-Usage-Source: upstream
JSON 响应暂不强制改变,避免破坏旧客户端;MCP 从响应头读取实际用量。
requestId。requestId + model + fingerprint 只扣一次。requestId 参数变化继续返回 409,防止错误复用。requestId。cachePolicy 扣费。mcp/src/core/billing-client.js
mcp/src/core/usage-context.js
mcp/src/core/budget-guard.js
mcp/src/core/recharge-client.js
mcp/src/features/voc-cost/workflow-planner.js
mcp/src/features/voc-cost/estimate-report.js
mcp/src/features/media/media-pipeline.js
mcp/src/features/media/media-manifest.js
mcp/src/tools/voc-cost-estimate-run.js
mcp/src/tools/voc-usage-report-run.js
skills/voc-cost-controller/SKILL.md
skills/voc-cost-controller/references/workflow-cost-models.md
职责:
billing-client.js:按筛选条件调用统一 /api/fmode/billing/query,读取余额、价目和实际用量。usage-context.js:本地创建和传递 usageTraceId/reportId/stepId,不创建服务端任务或支付记录。budget-guard.js:Agent 根据当前余额、本地预算和实际用量,在执行前及批次间做检查。recharge-client.js:计算差额后默认复用现有建单和 pay_code2 返回二维码;同时提供带 Token 的 Balance 自助链接。workflow-planner.js:把自然语言任务转换成确定性的接口调用计划。estimate-report.js:生成用户可读的三档报价和降本说明。media-pipeline.js:发现、下载、去重、校验、写入本地并替换多媒体 URL。media-manifest.js:维护媒体原地址、本地地址和处理状态,不保存线上访问地址。voc_cost_estimate输入保持业务化:
{
"task": "监听 280 个小红书账号并生成门店排行榜",
"workflowType": "xhs_account_monitor",
"accountCount": 280,
"unresolvedAccountCount": 105,
"notesPerAccount": 5,
"commentPagesPerNote": 0,
"mode": "standard",
"budgetCny": 100
}
voc_usage_report输入 usageTraceId/reportId 或日期范围,通过同一个 billing query 接口取得实际用量,返回可直接发送给用户的成本报告。
首期只新增以上两个用户可见 MCP 工具。voc_cost_estimate 内部完成业务计划生成、价目查询、报价和余额比较;预算检查和充值入口作为工作流内部 helper,不再拆成多组 MCP 工具。
voc_api_call 及专用采集工具的标准结果增加:
{
"usage": {
"usageTraceId": "USAGE_TRACE_ID",
"reportId": "REPORT_ID",
"endpointId": "ENDPOINT_ID",
"calls": 1,
"billedCalls": 1,
"quota": 7353,
"costCny": 0.1,
"pricingVersion": "2026-09-01.1"
}
}
整个工作流结束时,summary 增加:
{
"estimatedCostCny": 42.8,
"actualCostCny": 40.6,
"remainingBalanceCny": 59.4,
"usageReportUrl": "URL"
}
复杂任务满足任一条件时必须先估算:
默认策略:
budgetCny 时把它作为硬上限。所有 VOC 采集工具和报告工作流必须遵守:
media-manifest.json。outputs/<usageTraceId>/assets/<platform>/<entityId>/,以内容摘要命名并去重。sourceUrl/localPath/cloudUrl/effectiveUrl,其中 cloudUrl 固定为 null,effectiveUrl=localPath。effectiveUrl,保证离线浏览且不产生线上 Storage 流量。partial,不得声称完整交付。现有 cacheEvidenceAssets() 可以作为图片下载的第一版基础,但需要扩展到视频、音频、详情长图、去重、断点续传和 URL 重写;线上 Storage 上传不在本轮范围内。
成本能力必须对所有 VOC Skill、任意报告和任意复杂采集任务通用,不限定小红书和天猫。通用过程是“Skill 生成步骤和计费单位计划 → billing query 按 endpoint 筛选返回价目 → Agent 计算三档报价 → 实际调用按 usageTraceId 归集”。
下面两类报告只是首批可回放、可验收的基准样例,用于验证通用模型,不是功能范围边界。后续其他平台和工作流只需提供步骤规划适配器,不新增另一套计费接口。单价必须运行时从后端读取,文档中的 P(endpoint) 表示该接口当前生效单价。
输入变量:
| 变量 | 含义 |
|---|---|
A |
登记账号数,本场景为 280 |
D |
已有直链、可直接取用户 ID 的账号数,本场景为 179 |
S |
需要搜索匹配的账号数,本场景为 105;与 A-D 的差异必须作为数据质量提示 |
C |
本轮实际覆盖账号数,已知历史执行在 147 个时停止 |
N |
每账号读取的笔记页数 |
K |
每条入选笔记读取的评论页数 |
R |
每账号进入详情/评论的笔记数 |
基础调用公式:
账号解析费用
= S * P(xiaohongshu.search_user_v2)
账号笔记费用
= A * N * P(xiaohongshu.get_user_note_list_v4)
笔记详情费用(按需)
= A * R * P(xiaohongshu.get_note_detail_vN)
评论费用(按需)
= A * R * K * P(xiaohongshu.get_note_comment_vN)
报告生成费用
= LLM(inputTokens, outputTokens, cacheTokens, modelPrice)
三档建议:
| 模式 | 采集策略 | 适用场景 |
|---|---|---|
| 经济版 | 只搜索未解析账号;每账号 1 页笔记;不逐条拉评论;用已有互动字段排行 | 日报、赛事榜单 |
| 标准版 | 每账号 1 页笔记;只对 Top/新增笔记拉详情;仅异常样本拉评论 | 周报、运营诊断 |
| 完整版 | 多页笔记;入选笔记全量详情和评论;补用户画像 | 月报、深度研究 |
历史报告回算说明:
usageTraceId/reportId,无法把同一账户同一时段的其他调用排除。reconstructed 回算。usageTraceId,即可精确回答覆盖 147 个账号前花了多少、剩余 133 个还需多少。输入变量:
| 变量 | 含义 |
|---|---|
G |
店铺商品列表页数,本场景已知为 5 |
A |
店铺在售商品数,本场景为 134 |
S |
进入完整诊断的代表商品数,已交付报告为 8 |
K |
每商品评论页数 |
V |
每商品调用的详情版本数 |
推荐调用公式:
店铺商品清单
= G * P(taobao.get_shop_item_list_v4)
全店轻量字段
= A * P(最小可用详情接口)
代表商品价格/SKU/主图
= S * P(taobao.get_item_detail_v4)
代表商品销量/长图/视频/属性
= S * P(taobao.get_item_detail_v3)
代表商品评价
= S * K * P(taobao.get_item_comment_v3)
报告生成
= LLM(inputTokens, outputTokens, imageTokens, modelPrice)
三档建议:
| 模式 | 采集策略 | 价值与成本 |
|---|---|---|
| 经济版 | 5 页店铺清单 + 按销量/新品/价格分层抽 8 个代表 SKU | 最适合快速体检,避免 134 个商品全部深采 |
| 标准版 | 134 个商品拉轻量字段,Top 20 做完整详情与评论 | 能兼顾全店覆盖和诊断深度 |
| 完整版 | 134 个商品全部拉价格、详情、素材、评价并逐页打分 | 成本最高,仅在需要逐 SKU 改版清单时使用 |
接口选择规则:
每个步骤增加下列业务字段:
{
"required": true,
"valueScore": 5,
"valueLabel": "门店排行核心字段",
"omissionImpact": "不再能计算账号活跃率",
"fallback": "使用上次快照"
}
成本报告按以下指标排序:
costShare = stepCost / taskCost
valuePerCny = valueScore / stepCost
wasteCandidate = !required && costShare >= 0.1 && valueScore <= 2
valueScore 是业务配置和人工校准结果,不应由接口价格自动推断。AI 可以提出建议,但删除采集项前必须说明信息损失。
VOC 数据费和报告生成的大模型费必须分开显示。
reconstructed 估算。usageTraceId。usageTraceId。billing_source=apig 与模型日志按 usageTraceId 合并。最终任务账单:
{
"dataCollectionCny": 36.4,
"modelGenerationCny": 8.2,
"otherModuleCny": 0,
"totalCny": 44.6
}
在现有余额弹窗基础上补充用户成本测算和用量展示。充值中心已有 Token 免登录识别、余额展示、金额选择、支付二维码/按钮、支付轮询和到账刷新,本需求复用并回归验证,不另建支付中心。
建议整理为四个页签:
展示:
筛选:
明细字段:
exact/mixed/reconstructed。支持 CSV 导出,但导出中不包含 token、请求体、原始评论或商品数据。
默认展示 Pareto 排行:
例如:
逐条评论采集占本任务 43%,但门店排行榜只使用发帖数和互动总量。
切换为“只采 Top 20 账号评论”预计节省 ¥X,门店排行不受影响,评论洞察覆盖率下降。
voc-profit-web 保留经营角色,并增加:
usageTraceId/workflowType/skillId 聚合。现有 module-forwarding 可作为实现底稿,但需要:
actual_cost_cny 替代旧 LOG_CNY_SQL 的模块价回退。WHERE user_id = $currentUserId。mixed。管理员任务级诊断已落地为现有经营看板的一条管理员路由:
GET /api/profit/api/usage-diagnostics?days=2&limit=200
可选筛选参数为 usageTraceId、reportId、workflowType。返回内容包括任务汇总、接口调用频次、计费 quota、实际消费、缓存命中、上游调用以及高成本低价值候选和预计节省金额。该路由继续使用看板管理员鉴权,不向普通 Balance 用户开放;用户侧仍只调用 POST /api/fmode/billing/query。
future-serverP0:
APIGEndpointPricing 表和迁移/seed。resolveBillingRule()。logs.other 追踪和实际金额字段。/api/fmode/billing/query,通过入参筛选返回当前用户余额、价目和用量。/api/fmode/recharge/order、pay_code2、order_status2,不新增 billing 支付接口。P1:
usageTraceId。claude-code-voc-intelligenceP0:
voc-cost-controller skill。voc_cost_estimate 与 voc_usage_report 两个 MCP 工具。voc_api_call 传追踪头并读取实际用量头。P1:
fmode-studioP0:
P1:
voc-profit-web没有完成阶段 A 前,不应上线对外“精确任务成本”。
media-manifest.json。effectiveUrl。quota、actual_cost_cny 和余额变化一致。usageTraceId 不能突破当前用户边界。新增覆盖:
errors=[]。recharge/order + pay_code2 取得二维码,并同时生成带 Token 的 Balance 自助链接。voc_api_call 的 usage 与模拟响应头一致。建议脚本:
scripts/smoke-billing-query.js
scripts/smoke-cost-estimate.js
scripts/smoke-budget-guard.js
scripts/smoke-trend-budget.js
scripts/smoke-usage-report.js
scripts/smoke-recharge-client.js
scripts/smoke-media-pipeline.js
并纳入:
npm run mcp:smoke
npm run smoke:package
所有会发起计费采集的 VOC 技能先通过同一组通用验收:能够生成工作流调用计划、查询同一权威价目、携带 usageTraceId、执行预算保护、处理 VOC 402,并输出可按模块和接口核对的实际账单。下面两个业务场景只作为首批规模化回放样例。
小红书场景:
usageTraceId 和本地检查点续跑,不重复扣已完成批次。天猫场景:
上线后至少监控:
unpriced_endpoint_count > 0。abs(log_cost - quota_converted_cost) > tolerance。trace_actual / trace_estimated_high > 1。requestId 冲突。used_quota 增量不一致。APIGNewApiBillingMap 保留,作为模块级默认价。logs 不迁表;新增字段写入 other。mixed。r: Session Token 继续用于用户身份、Balance 免登录和支付授权,但新模式下的数据调用必须映射到该用户的 NewAPI 账户并扣减 NewAPI 通用余额;不能再把 APIGAuth.count 作为正常回退计费路径。本需求完成必须同时满足:
usageTraceId 关联到报告、技能、步骤和接口。本节是对第 18 节完成定义的代码复核结果,状态以当前工作区和已执行测试为准:
| 完成定义 | 状态 | 复核结论 |
|---|---|---|
| AI 读取当前有效计费规则 | 已完成 | 后端统一 POST /api/fmode/billing/query 返回余额、价目和版本;voc_billing_query/voc_cost_estimate 已注册。 |
| 所有已接入工作流执行前三档预估 | 部分完成 | 通用规划器覆盖小红书账号监听、天猫 Listing 和自定义 operations;其他新工作流需提供规划适配器。 |
| 每次调用关联 usageTraceId/report/skill/step/endpoint | 已完成(已接入入口) | voc_api_call、小红书/抖音 live 网关请求发送 X-Fmode-* Header,后端写入 logs.other;历史日志标记 mixed/reconstructed。 |
| Balance 按模块、追踪、报告、接口展示 | 已完成(前端已接入) | Studio Balance 用量页调用统一接口,展示调用、quota、实际消费、模块/接口明细和计费规则。 |
| 大模型与 VOC 费用分列 | 部分完成 | 用户用量账与平台成本报告已拆分;模型侧只有具备同一 trace 的日志才能精确合并。 |
| 预算上限阻止超支并保留部分成果 | 已完成(已接入批处理入口) | batch-budget-guard 在小红书/抖音 live 每个关键词批次前读取当前余额与追踪消费,支持 80% 预警、硬预算/余额阻断、差额和建议充值;首批前阻断也会写入 checkpoint.json,resume 会跳过已完成关键词。经营闭环复用同一趋势入口;跨会话自动唤醒仍由宿主运行时负责。 |
| 高成本低价值项优化建议 | 已完成(首批任务) | Agent 估算报告输出 valueScore、可删项和节省额;管理员看板 /usage-diagnostics 已按任务和接口展示成本排行、缓存命中和预计节省。 |
| 充值后从检查点继续且不重复调用 | 已完成(工具级续跑) | VOC 402 分支保留部分结果并写检查点;支付后以同一 usageTraceId + resume 续跑,已完成业务键和分页不会重复调用。跨会话自动唤醒仍由宿主运行时负责。 |
| Agent 返回免登录链接或支付二维码 | 已完成 | VOC 402 由统一 recharge client 复用现有 pay_code2/order_status2,二维码失败保留 Token Balance URL;Studio/宿主已对模型 402 直接打开现有充值入口。 |
| 采集多媒体并固定本地缓存 | 已完成(小红书/抖音 live) | 通用 discovery/manifest/pipeline 已接入;effectiveUrl 固定为本地路径,线上 Storage 上传已关闭。其他采集入口需继续接入 pipeline。 |
| 凭证不写入代码、日志、报告 | 已完成(静态与 smoke 范围) | 请求凭证只作运行时输入,输出经过脱敏;发布包扫描和安装 smoke 通过。 |
当前可以验收的 P0 交付是:统一报价、真实扣费归集、充值入口、Balance 用量页、管理员任务级成本诊断、两类首批工作流、live 媒体持久化和本地续跑检查点。后续工作集中在“为尚未接入的历史批处理 Skill 增加规划适配器、跨会话自动唤醒、更多采集入口接入媒体流水线、基于真实账号的端到端回放和历史预估校准”,不影响本轮已交付闭环。
首个可上线迭代建议只做以下闭环:
APIGEndpointPricing 和统一规则解析。usageTraceId/reportId/stepId 写入 VOC 扣费日志。/api/fmode/billing/query 接口。voc_cost_estimate 与 voc_usage_report 两个 MCP 工具。这个范围已经能回答本次业务提出的三个核心问题:预计多少钱、实际花在哪里、下一次怎么少花但保留关键结果。
本节是在对四个仓库的实际代码入口再次核对后形成的落地结论,用于开发排期、任务拆分和代码评审。前文定义产品行为与接口契约,本节明确代码具体落在哪里、如何分阶段接入,以及哪些已有行为必须保持兼容。
整体方案可以落地,但实现时必须遵守以下边界:
usageTraceId 只是 Agent 本地生成并写入日志的执行追踪标签,用于把不同报告的调用频次和实际消费分开;不需要服务端任务表和任务 CRUD。cacheAssets=false 不再允许跳过 live 数据的持久化,assetLimit 只控制报告展示数量,不再控制实际缓存数量。future-server 生产环境通过根目录 server.js 加载 .modules/*.min.cjs。改完模块源码后必须重新构建并更新对应运行时产物,否则现网不会获得新逻辑。r: Session Token 已通过 hasNewApiBillingIdentity() 映射到同一 NewAPI 计费身份;三个 VOC 网关在新模式下使用统一 NewAPI 扣费,APIGAuth.count 仅保留给明确的旧兼容路径。技能端链接、实际扣费和 Balance 用量因此使用同一账户口径。E:\workspace\server\future-server| 类型 | 文件位置 | 修改职责 | 风险 |
|---|---|---|---|
| 修改 | fmode-server/modules/shared/newapi-metering.ts |
将 resolveQuota() 扩展为统一规则解析;真实扣费、日志金额和响应计费信息使用同一解析结果;写入任务追踪字段 |
高 |
| 修改 | fmode-server/modules/shared/newapi-metering.ts |
集中完成 sk-/r: 身份解析、Session-to-NewAPI 映射、路径级价目匹配、额度检查、幂等扣费、实际金额和追踪日志写入 |
高 |
| 修改 | fmode-server/modules/voc-social-api/src/routes.ts |
接收白名单任务上下文、按路径解析价格、写日志、返回 usage 响应头 | 高 |
| 修改 | fmode-server/modules/voc-e-commerce/src/routes.ts |
与社媒网关保持相同计费和追踪行为 | 高 |
| 修改 | fmode-server/modules/voc-ecom-api/src/routes.ts |
与社媒网关保持相同计费和追踪行为 | 高 |
| 修改 | fmode-server/api/routes.ts |
在现有主路由中提供统一 POST /api/fmode/billing/query;媒体 Storage 路由不由本技能包调用 |
高 |
| 修改 | 三个模块的构建脚本或 scripts/build.mjs |
确保共享计费代码进入产物,并复制到根目录 .modules |
中 |
| 生成 | .modules/voc-social-api.min.cjs、.modules/voc-e-commerce.min.cjs、.modules/voc-ecom-api.min.cjs |
三个 VOC 网关的生产实际加载产物;由各模块构建生成,不手工编辑。billing 路由随 fmode-server/api/routes.ts 加载,不单独生成 CJS |
高 |
| 保持并复用 | api/api-ncloud/fmode/routes.js 的 /recharge/order |
Agent 和 Balance 页创建或复用充值订单及 AccountLog |
中 |
| 修改并复用 | api/api-ncloud/fmode/sync-fmode-api.js、newapi-user-resolution.js |
抽取可被计费模块复用的 Session 用户到 NewAPI 用户映射;保持 syncUser() 和 Token 创建幂等 |
高 |
| 保持并回归 | api/api-ncloud/fmode/serv-user.js、routes.js、cloud/user/auth-route.js |
继续承担现有钱包、NewAPI 划拨、pay_code2 二维码和 order_status2 状态,不引入任务支付绑定 |
高 |
| 修改 | api/api-ncloud/profit/service/revenue.service.js |
管理员聚合优先读取新的实际金额、任务和路径字段,保留历史兼容公式 | 中 |
| 修改 | api/api-ncloud/profit/routes.js |
增加管理员执行追踪/报告/接口聚合,不改变现有鉴权 | 中 |
| 新增 | 后端迁移脚本 | 创建 APIGEndpointPricing 和 NewAPI 日志查询所需索引,不创建任务支付表 |
高 |
| 新增 | 后端单元及集成测试 | 覆盖用户隔离、查询筛选、价格一致性、扣费幂等和历史日志兼容 | 高 |
注意:AuthService.guardAuthToken() 负责入口鉴权,统一计费身份和价目解析集中在 shared/newapi-metering.ts。billing query 强制使用当前请求解析出的 userId,筛选条件只能作为附加条件,不能跨用户查询。
E:\workspace\openclaw-voc-skill\claude-code\claude-code-voc-intelligence| 类型 | 文件位置 | 修改职责 | 风险 |
|---|---|---|---|
| 修改 | mcp/src/core/credentials.js |
将字符串式 Token 读取改为类型化凭证上下文,分别返回 newApiToken、sessionToken、来源和可用能力,禁止把任意 vocToken 当成可拼 Balance 链接的 Session |
高 |
| 修改 | mcp/src/core/payment-links.js |
增加 Tokenized Balance URL 构造和统一充值结果;旧 APIG/workshop helper 仅保留给旧产品流程 | 高 |
| 新增 | mcp/src/core/billing-client.js |
封装统一 billing query 请求;按场景选择 balance/pricing/usage,统一隐藏凭证和底层错误 | 中 |
| 修改 | mcp/src/providers/voc-gateway.js |
接收类型化双凭证、发送追踪头、返回实际认证/计费模式并读取 usage 响应头;统一 401/402/403 | 高 |
| 修改 | mcp/src/providers/ecommerce-gateway.js |
与 social provider 保持同一认证、计费、错误和响应上下文 | 中 |
| 修改 | mcp/src/providers/overseas-gateway.js |
与 social provider 保持同一认证、计费、错误和响应上下文 | 中 |
| 修改 | mcp/src/providers/xiaohongshu-api.js、douyin-api.js |
移除独立请求/错误分类,改为复用统一 social gateway;保留平台便捷方法 | 高 |
| 修改 | mcp/src/features/xiaohongshu-trend/live-collector.js、douyin-trend/live-collector.js |
传递完整凭证和 usage context,保留结构化错误类型、requestId 与部分进度 | 高 |
| 新增 | mcp/src/core/usage-context.js |
本地创建和传递 usageTraceId/reportId/skillId/workflowType/stepId/clientId |
中 |
| 新增 | mcp/src/features/voc-cost/workflow-planner.js、estimate-report.js |
生成经济版、标准版、完整版调用计划、成本区间和用户可读报价 | 中 |
| 新增 | mcp/src/core/budget-guard.js |
批次执行前检查余额和预算,输出差额、充值建议及检查点 | 中 |
| 新增 | mcp/src/core/recharge-client.js |
计算差额后默认调用现有建单/支付码链路返回二维码,同时提供带 Token 的 Balance 自助链接,并在到账后查询余额 | 中 |
| 新增 | mcp/src/features/media/media-pipeline.js |
发现图片/视频/音频,下载、去重、校验、写 manifest 并固定使用本地 effectiveUrl |
中 |
| 新增 | mcp/src/features/media/media-discovery.js |
从不同接口的嵌套响应中按字段映射和 MIME 类型发现媒体,避免用单一字段名硬编码 | 中 |
| 修改 | mcp/src/features/xiaohongshu-trend/assets.js |
迁移到通用媒体流水线;保留旧导出作为兼容适配器 | 中 |
| 修改 | mcp/src/tools/voc-api-catalog-run.js |
支持任务上下文、usage、默认输出目录和通用媒体副作用 | 中 |
| 修改 | mcp/src/tools/xiaohongshu-trend-run.js |
接入预估、预算、检查点、全量媒体缓存和充值续跑 | 中 |
| 修改 | mcp/src/tools/douyin-trend-run.js |
与小红书工作流保持同一规则 | 中 |
| 修改 | mcp/src/features/voc-business-workflow/business-workflow.js |
汇总大模型费用与 VOC 数据费用,输出成本价值建议 | 中 |
| 修改 | mcp/src/features/fmode-image-analysis/image-analysis.js |
复用统一错误分类与 NewAPI 充值结果;严格区分模型 402 和权限 403 | 高 |
| 修改 | mcp/src/core/result-envelope.js |
给所有工具统一增加 usage/estimate/recharge/checkpoint 可选字段,保持原字段兼容 |
中 |
| 修改 | mcp/src/core/api-catalog.js、mcp/catalog/voc-social-endpoints.json、mcp/catalog/params/*.json |
使用稳定 endpoint 标识和计费单位元数据;删除把 billing: 1 当人民币价格的行为,价格始终来自 billing query |
高 |
| 新增 | mcp/src/tools/voc-cost-estimate-run.js |
MCP voc_cost_estimate 的实现 |
低 |
| 新增 | mcp/src/tools/voc-usage-report-run.js |
MCP voc_usage_report 的实现 |
低 |
| 修改 | mcp/src/server.js |
注册新工具和 schema;调整 cacheAssets/assetLimit 描述及兼容语义 |
中 |
| 修改 | mcp/src/core/activation.js |
缺 Token 时只做配置恢复,不再打开旧 APIG 充值页;只在确认 402 且存在 Session 时生成个人充值入口 | 中 |
| 修改 | skills/voc-api-catalog/SKILL.md |
加入执行前估算、批次预算检查、余额不足返回支付入口、媒体强制持久化规则 | 低 |
| 修改 | skills/xiaohongshu-trend-intelligence/SKILL.md、skills/douyin-trend-intelligence/SKILL.md |
补充成本和媒体行为,不要求用户理解内部参数 | 低 |
| 修改 | 其他所有会发起计费采集的 skills/*/SKILL.md 或统一入口 Skill |
引用同一成本规划、追踪和 VOC 余额不足规则,避免能力只覆盖两个验收样例 | 中 |
| 修改 | skill-package-manifest.json、package.json |
登记新工具、脚本和能力说明 | 低 |
| 修改 | scripts/smoke-mcp.js、scripts/smoke-package.js |
覆盖工具发现、结构化输出、敏感信息、充值和媒体兼容 | 中 |
| 新增 | scripts/smoke-cost-estimate.js、smoke-recharge-client.js、smoke-media-pipeline.js |
独立验证 Agent 报价、现有充值入口衔接和媒体流水线 | 中 |
voc_api_call 是通用入口,不能假设所有接口都有统一媒体字段。首期由 endpoint catalog 增加可选 mediaFields 映射;未登记接口再使用受限的 URL/MIME 发现器,并把无法确认的候选项写入 warning,避免把普通链接误当作文件下载。
E:\workspace\fmode-studio| 类型 | 文件位置 | 修改职责 | 风险 |
|---|---|---|---|
| 新增 | projects/fmode-studio/src/components/billing-center.service.ts |
封装统一 billing query,供余额、规则和用量视图使用 | 中 |
| 新增 | projects/fmode-studio/src/components/billing-usage.component.ts |
展示模块、执行追踪、报告和接口用量 | 中 |
| 保持并回归 | projects/fmode-studio/src/app/app.routes.ts、auth-guard.service.ts |
复用已确认的 /balance 路由和 token/session 免登录识别;保持消费 Token 后清理地址栏 |
中 |
| 修改 | projects/fmode-studio/src/modules/launcher/fmode-home.component.ts |
保持现有 Balance 打开方式并接入用量视图 | 中 |
| 修改 | projects/fmode-studio/src/components/balance-modal.component.ts、balance-page.component.ts |
保留现有余额、二维码、支付轮询和到账刷新,只接入用量子组件 | 中 |
| 修改 | projects/fmode-studio/src/modules/codex-workspace/pages/codex-shell/* |
保持 Codex 工作区打开余额页的现有行为,并接入新用量视图 | 中 |
| 修改 | projects/fmode-studio/src/modules/codex-workspace/pages/codex-shell/codex-shell.component.ts 及模型请求错误适配层 |
拦截模型调用 402,在不依赖 Agent 回复的情况下直接打开现有 Balance 充值入口 | 高 |
| 新增 | 对应 *.spec.ts |
回归 Token 免登录、自助选金额、二维码、支付轮询、到账刷新和用量展示 | 中 |
Studio 仓库当前这些相关文件已有未提交修改。实际编码必须以当前工作树为基线做增量编辑,不能覆盖或回退既有改动。
E:\workspace\voc-profit-web| 类型 | 文件位置 | 修改职责 | 风险 |
|---|---|---|---|
| 修改 | client/src/app/api.service.ts |
扩展管理员任务、报告、接口、价格版本和数据质量类型及请求 | 低 |
| 修改 | client/src/app/dashboard.component.ts |
增加任务成本排行、接口 Top 消耗、估算偏差和低价值高成本诊断 | 中 |
| 修改 | client/src/app/dashboard.component.html |
在现有“模块转发明细”上补任务/报告视角,不复制 Balance 用户页 | 中 |
| 修改 | client/src/app/dashboard.component.scss |
支持新增表格和筛选状态 | 低 |
| 可选修改 | client/src/app/app.routes.ts |
若单独增加任务成本页面则新增路由;首期可复用现有 modules 页面 | 低 |
voc-profit-web/server/src/index.ts 只是静态站点和 /api/profit 路由装载器,业务聚合仍在 future-server/api/api-ncloud/profit。首期没有新增服务器逻辑时无需修改该文件。
一次 VOC 网关请求按以下顺序处理:
userId/tokenId。model + method + proxyPath,移除 query 和动态值。resolveBillingRule() 读取当前生效的路径规则;找不到时按现有模块映射回退,并标记 matchedBy=fallback。assertNewApiQuotaAvailable() 和 chargeNewApiUsage() 接收同一个 ResolvedBillingRule 对象,避免检查额度和实际扣费使用不同价格。requestId/idempotencyKey。quota、actual_cost_cny、价格版本和任务字段写入 logs.other。不能让网关先按 pathQuota 扣费、日志再按 APIGNewApiBillingMap.price_cny 记另一金额。规则解析结果必须是额度检查、扣除、日志和展示四处共享的唯一对象。
POST /api/fmode/billing/query 不调用管理员 profit API,而是直接基于严格解析出的当前 userId 查询 NewAPI logs:
user_id = currentUserId。usageTraceId/reportId 只能作为附加条件,不能替代用户条件。groupBy 使用服务器白名单映射到固定 SQL 表达式,不能把客户端字段直接拼进 SQL。actual_cost_cny;旧日志回退 price_cny 或 quota 换算,并返回 quality=mixed/reconstructed。from/to、分页大小和最大时间范围设置上限,避免 Balance 页形成大范围全表扫描。logs(user_id, created_at),并评估 other 中 usage_trace_id/report_id 的表达式索引或结构化列。不新增任务支付会话,按以下方式衔接现有充值中心:
/api/fmode/recharge/order 创建或复用订单,再调用 pay_code2 取得支付码并返回二维码。balance/?token=USER_TOKEN;用户打开后在现有页面自行选择金额。BalanceModalComponent.startPayment()、pay_code2、order_status2、钱包账本和 topUpNewApiQuota() 继续按现有链路运行。usageTraceId 对应的本地检查点继续。充值只增加 NewAPI 通用余额,不记录为某个 usageTraceId 的任务收入。现有支付链路仍需保持 tradeNo 幂等,但这属于原充值能力的回归要求,不是新增任务支付模型。
媒体处理只保留本地事实层:
sha256 并写入目标文件。sha256 在同一任务内只保留一份实体文件,manifest 可以有多个业务引用。effectiveUrl 固定为本地相对路径,HTML 报告和标准化 JSON 均不引用线上地址。cloudUrl 固定为 null,uploadStatus 固定为 disabled_local_only。storage/profile、预签名上传或 complete 接口,避免产生线上 Storage 流量。复用需求方确认的现有 Balance 路由:
https://app.fmode.cn/dev/studio/balance/?token=USER_TOKEN
加载顺序:
token 并复用现有免登录识别逻辑取得当前用户。远端 origin/master 已确认 auth-guard.service.ts 同时接受 token 和 session,调用 Parse.User.become(token) 后清理地址栏;app.routes.ts 已存在 /balance 路由。当前本地分支落后且有重叠的未提交改动,实际编码时以现有工作树为基线合并这些远端行为,不重建支付页面,也不覆盖本地修改。
BalanceModalComponent 手动选金额并调用原 startPayment()。balance-modal.component.ts 已承担余额、支付、订阅和轮询等职责;新增用量查询和展示应下沉到 service 和子组件,不改写现有支付主体。| 现有参数 | 当前语义 | 新语义 | 兼容行为 |
|---|---|---|---|
cacheAssets |
是否缓存少量首图 | 是否在报告中展示缓存媒体的兼容开关 | sample 模式可按旧值;live 模式始终持久化,传 false 时返回弃用 warning |
assetLimit |
最多缓存多少张首图,最大 30 | 报告最多展示多少项媒体 | 不限制实际缓存;schema 可保留原字段名并新增 mediaDisplayLimit |
output |
trend 工具输出目录 | 报告和媒体根目录 | 保持兼容 |
无输出目录的 voc_api_call |
只返回 JSON | 默认创建任务输出目录和 manifest | 可通过结构化 files 告知目录,不改变原始 data.result |
默认目录建议为工作区下 .voc/runs/<usageTraceId>/ 或现有 output 根目录下的 <usageTraceId>/。路径选择必须由统一 helper 完成,不能由各工具分别拼接。
每个批次写入检查点:
{
"usageTraceId": "USAGE_TRACE_ID",
"stepId": "collect_account_notes",
"completedItemKeys": ["ITEM_KEY"],
"nextCursor": "CURSOR",
"requestIds": ["REQUEST_ID"],
"mediaManifestPath": "assets/media-manifest.json",
"updatedAt": "ISO_TIME"
}
续跑前先读取检查点和后端任务实付记录:
requestId 的调用不再扣费重放。| 等级 | 行为 | 所需改动 | 首期 |
|---|---|---|---|
| L0 | 支付完成后用户回到 Agent 触发继续 | 现有余额刷新 + 本地检查点 | 保底能力 |
| L1 | 当前 Agent 会话周期性查询 billing query,余额到账后续跑 | 技能 recharge-client + 当前进程存活 |
P0 目标 |
| L2 | Agent 会话关闭后,支付回调唤醒后台任务并跨会话续跑 | Agent runtime/callback、持久任务队列、回调签名和执行租约 | 后续独立迭代 |
产品文案中的“充值完成后自动继续任务”在 P0 指 L1。若要求用户关闭聊天或进程后仍自动生成报告,则验收目标必须升级为 L2,并明确增加运行时仓库或服务端任务执行器的改造范围。
| 原有能力 | 影响方式 | 兼容策略 | 必测回归 |
|---|---|---|---|
| VOC 网关 JSON 响应 | 增加日志字段和响应头,不改主 JSON | 旧客户端忽略新响应头 | 三通道正常、缓存、上游失败、重试 |
| NewAPI 扣费 | 路径级规则替代部分模块级默认价 | 无路径规则时回退现有映射;灰度比对后启用扣费 | 额度检查与实际扣除一致、重复请求幂等 |
| NewAPI 历史日志 | 不迁移、不回写 | 查询时标记 mixed/reconstructed |
新旧日志合并金额和质量标识 |
| 普通余额查询 | 增加模块/执行追踪/接口视图 | 现有余额和订阅接口继续可用 | 余额总额、充值记录、订阅显示 |
| 现有充值中心 | 不重做;默认 Agent 直出二维码,Token 链接供用户自助选金额 | 保留原 Balance、二维码、轮询和到账刷新 | 免登录、自助选金额、建单、扫码、到账 |
| 支付回调划拨 | 不改变业务模型 | 继续复用 topUpNewApiQuota() 和原账本 |
重复回调、超时回调、部分失败补偿 |
| trend 图片缓存 | 从少量首图变为 live 全媒体 | 旧导出保留适配;展示上限与缓存上限分离 | 图片、视频、音频、失败降级 |
voc_api_call |
增加任务目录和媒体副作用 | 原 data.result/raw 结构保持 |
已登记和 rawPath 接口、无媒体接口 |
| 报告媒体地址 | 新报告改用本地 effectiveUrl |
旧报告不批量迁移 | 本地浏览、断网展示 |
| 管理员利润看板 | 增加任务/接口维度 | 保持管理员鉴权,不复用到用户侧 | 全局数据完整、历史公式兼容 |
风险排序:
首期明确不做以下改动:
/api/profit 权限或全局用户数据下放给 Balance 页面。clientId/skillId 当作强身份依据;真正的账户边界始终来自服务端认证结果。为降低高风险逻辑互相干扰,建议按以下提交和发布单元推进:
voc_cost_estimate、预算检查和通用工作流计划协议,以小红书和天猫模板完成首批验收,不接支付。voc_api_call 和其他计费采集入口。voc-profit-web 增加管理员成本优化分析。每个发布单元必须具备独立开关或回退点:
partial,可从检查点人工继续。完成实施后应交付以下可验收成果,而不只是代码提交:
media-manifest.json。voc-profit-web 管理员成本优化视图。本节以当前代码实际执行路径为依据,补全“改哪些位置才能让新模式真正跑通”。结论是:计费和充值逻辑目前分散在通用接口目录、两个平台趋势工具、业务闭环、图片分析、Token 检查和激活流程中。只修改 voc_api_call 或只替换一处充值 URL,无法覆盖实际报告任务。
voc_api_call当前过程:
credentials.js 分别尝试读取 NewAPI sk- Token 和 VOC Token,但 VOC Token 返回值没有类型保证。voc-api-catalog-run.js 优先把 sk- 传给 social/ecommerce/overseas gateway,同时把另一个 Token 作为鉴权失败回退。auth 时才使用回退 Token;402 和 403 不回退。sk- 时通过 newapi-metering.ts 扣减 NewAPI 用户和 Token quota,并写 NewAPI logs。r: 时走旧 APIGAuth.count 查询和扣减,不进入同一 NewAPI 日志。这条链路已经能区分大部分 401、402、403、参数和上游错误,但还不能保证“同一用户统一 NewAPI 余额、统一账单、统一充值入口”。
两个 trend runner 当前先执行:
readNewApiToken(input) || readVocToken(input)
这会把两种凭证压缩成一个字符串。后续 live-collector.js 分别实例化 XiaohongshuApi 或 DouyinApi,它们没有携带另一种凭证,也没有复用通用 gateway 的回退结果和 usage 响应。因此存在以下后果:
sk- 鉴权失败后不能可靠用 Session 身份继续。buildVocRechargeInfo(),继续返回旧 APIG/workshop 入口。usageTraceId、实付金额、检查点和可续跑状态。voc-business-workflow 调用 trend runner;非 ok 时会包一层业务提示。它会保留底层文本,但没有稳定透传 recharge/usage/estimate/checkpoint,以后很容易在包装时丢链接或二维码。fmode-image-analysis 直接调用模型网关,并把 HTTP 402 和 403 都当成 needs_recharge;同时使用旧 buildVocRechargeInfo()。这会把权限问题错误引导到充值,并且无法和 VOC 数据费用使用同一结果协议。mcp/src/server.js 中的小红书/抖音 Token check 目前主要判断“是否读到字符串”,不验证 Token 类型、有效性、NewAPI 余额和 Session 是否能生成个人充值入口。activation.js 在缺 Token 时会构造旧 workshop/APIG 页面。缺 Token 属于配置恢复,不能等同于余额不足。r: Session Token 才能放进 balance/?token=...;sk-、空值或任意 vocToken 都不能用于拼个人链接。当前目录和后端规则的实际情况如下:
| 位置 | 当前事实 | 新模式处理 |
|---|---|---|
mcp/catalog/voc-social-endpoints.json |
共 1,344 个接口:social 1,018、ecommerce 289、overseas 37 | 目录只保存稳定 endpoint 和计费单位元数据,不作为价格权威源 |
| social 目录 | 1,018 个接口没有 endpoint 级 billing |
必须通过 billing query 按 endpoint 筛选读取服务端有效价目 |
| ecommerce/overseas 目录 | 326 个接口多数写有 billing: 1 |
只表示一次调用单位,不能解释为 ¥1 或真实 quota |
newapi-metering.ts |
quota 优先级为 model:path pathQuota -> pathQuota -> options.quota -> modelQuota -> APIGNewApiBillingMap.quota -> 默认值 |
统一收敛为 resolveBillingRule(),检查、扣费、日志和展示共享结果 |
| NewAPI quota 检查 | 同时检查用户总 quota 和 Token remain quota;任一不足返回 402 | 保持双重额度约束,并在 billing query 返回可解释的可用余额 |
| 人民币换算 | quota / 500000 * USDExchangeRate;充值反向换算 |
保持现有 NewAPI 换算权威,价格版本记录汇率和换算基准 |
| 缓存 | 当前三个 VOC 模块均可能对缓存命中计费 | 将政策写入 endpoint 规则并在报价、实扣和账单中明确展示 |
因此,Agent 的成本公式只能是“计划调用单位 × billing query 返回的当前单价”,不能是“目录 billing 字段 × 调用数”。实际消费以 NewAPI 成功扣费日志为准。
目标语义不是“sk- 扣 NewAPI,r: 扣旧 VOC 次数”,而是:
| 请求凭证 | 身份解析 | 数据调用扣费 | 充值用途 |
|---|---|---|---|
有效 sk- |
NewAPI tokens -> users |
当前 NewAPI 用户通用余额 | 若同时有 Session,可返回个人 Balance 链接和二维码 |
有效 r: |
Parse _Session -> _User -> NewAPI users.parse_id |
映射后的同一 NewAPI 用户通用余额 | 可生成 Tokenized Balance 链接并授权现有支付链 |
sk- 401 且 r: 有效 |
改用 Session 身份解析 | 仍扣映射后的 NewAPI 用户通用余额 | 同上 |
| 无有效凭证 | 不建立计费身份 | 不发起数据调用 | 返回配置/登录恢复状态,不伪造个人链接 |
后端需要把计费函数从“只接受请求头里的 sk-”改成“接受严格解析后的 NewApiBillingPrincipal”。建议统一 principal:
type NewApiBillingPrincipal = {
authMode: "newapi_token" | "session_newapi";
userId: number;
tokenId: number;
parseUserId?: string;
group: string;
};
assertNewApiQuotaAvailable()、chargeNewApiUsage()、日志写入和 billing query 都使用该 principal。Session 分支可以复用 syncUser() 已有的 users.parse_id 映射和 Token 幂等创建能力,但不能把解析出的 NewAPI Token 返回给普通数据响应或写入日志。
切换新模式后,三个 VOC 网关的正常请求路径不再调用:
getApiAuth();deductApiAuthCount();APIGAuth.count 的余额检查。这些函数可以在迁移期受开关保护以便回滚,但不能和 NewAPI 同时扣费。上线前必须用同一 Session 用户验证:NewAPI quota 减少、NewAPI 日志新增、旧 APIGAuth.count 不变。
当前 newapi-metering.ts 的 quota 解析依次考虑路径配置、显式 quota、模型配置、模块映射和默认值,但日志中的 price_cny 可能仍来自模块级 APIGNewApiBillingMap。新模式应在请求开始时只解析一次:
type ResolvedBillingRule = {
endpointId: string;
model: string;
method: string;
normalizedPath: string;
unit: "call" | "item" | "page" | "token";
quota: number;
unitPriceCny: number;
pricingVersion: string;
cachePolicy: "charged" | "free" | "discounted";
matchedBy: "endpoint" | "module" | "fallback";
};
额度预检、真实扣减、logs.other.actual_cost_cny、响应 usage 和 Balance 展示必须使用同一个对象。mcp/catalog/voc-social-endpoints.json 里的 billing: 1 只能表示历史调用单位,不能再被 Agent 当作人民币价格。
三个 VOC 网关需要统一以下顺序:
isBillableBusinessSuccess() 判断业务响应成功。requestId + principal.userId + endpointId 幂等扣费。缓存是否计费由 ResolvedBillingRule.cachePolicy 决定,不能由三个路由各自硬编码。上游 HTTP 成功但业务 code 失败、参数错误、权限错误和最终失败的重试不能产生成功扣费日志。
mcp/src/core/credentials.js 应返回凭证上下文,而不是让每个工具自行 A || B:
{
newApiToken: "<secret-or-empty>",
sessionToken: "<secret-or-empty>",
sources: {
newApiToken: "request|env|claude-settings|fmode-config|none",
sessionToken: "request|env|credential-file|none"
},
capabilities: {
canCallWithNewApi: true,
canCallWithSessionIdentity: true,
canBuildPersonalBalanceUrl: true,
canCreatePaymentOrder: true
}
}
所有入口使用同一状态机:
| 条件 | 工具状态 | Agent 动作 |
|---|---|---|
| 没有任何可用调用凭证 | needs_token |
返回配置或登录恢复步骤;不称为余额不足,不生成个人链接 |
| 凭证存在但认证失败 | needs_valid_token |
返回凭证恢复步骤;不生成充值二维码 |
| 402 且有有效 Session | needs_recharge |
返回差额、建议金额、Tokenized Balance 链接;Agent 传 createPaymentQr=true 时复用现有支付链生成二维码 |
| 402 但没有 Session | needs_session |
保留检查点并返回登录/Session 恢复入口;不拼假链接 |
| 403 | needs_permission |
提示账号或接口权限处理,不引导充值 |
| 参数错误 | needs_input |
返回缺失字段和参数文档,不引导充值 |
| 上游失败 | upstream_unstable |
按规则重试或保留部分结果,不引导充值 |
| 余额足够 | ok 或继续执行 |
带追踪上下文执行并记录实付 |
其中 needs_session 是充值交互所需身份缺失,不代表数据账户没有余额。若产品不希望增加对外状态,也可以对外仍用 needs_token,但结构化 summary.errorKind 必须是 missing_session_for_recharge,避免 Agent 把它解释成 402。
所有计费工具的充值输出统一进入 recharge,业务工作流只能透传或补充说明,不能重新拼 URL:
{
"status": "needs_recharge",
"assistantMessage": "当前余额不足,还差 ¥12.40,建议充值 ¥20.00。可直接扫码支付,或打开个人充值页面。",
"summary": {
"shortageCny": 12.4,
"suggestedRechargeCny": 20,
"completedItems": 147,
"remainingItems": 133
},
"recharge": {
"paymentMode": "qr_and_balance_url",
"balanceUrl": "https://app.fmode.cn/dev/studio/balance/?token=USER_TOKEN",
"qrCodeUrl": "QR_CODE_URL",
"qrImagePath": "OUTPUT_QR_IMAGE_PATH",
"tradeNo": "TRADE_NO",
"polling": {
"supported": true,
"status": "pending"
}
},
"checkpoint": {
"usageTraceId": "USAGE_TRACE_ID",
"path": "CHECKPOINT_PATH",
"canResume": true
},
"files": ["OUTPUT_QR_IMAGE_PATH", "CHECKPOINT_PATH"],
"nextActions": ["完成支付后继续当前任务"],
"warnings": [],
"errors": []
}
规则:
shortageCny = max(estimatedRemainingHighCny - currentBalanceCny, 0)。suggestedRechargeCny 由 Agent 根据差额、平台允许金额档位和小幅缓冲计算,传给现有建单链路;它不是服务端报价,也不绑定任务。balanceUrl 不携带金额。用户进入现有 Balance 页后自行选择充值金额。/api/fmode/recharge/order -> pay_code2 -> order_status2;voc_billing_query 传 createPaymentQr=true 时由技能包调用现有支付码链路并返回 qrCodeUrl。这三个是现有接口,不计入新增接口数。POST /api/fmode/billing/query。报价、差额和建议金额均由 Agent 基于该接口返回的数据计算。balanceUrl;运行时仍可放入 HTTPS 请求的认证头或现有支付请求。日志、诊断、usage、报告正文、二维码文件名、tradeNo、埋点和错误信息必须脱敏。paymentMode=balance_url。| 文件 | 必须修改的行为 |
|---|---|
mcp/src/core/credentials.js |
增加 readCredentialContext() 和 Token 类型校验;保留旧 reader 作为兼容包装;明确 Session 来源,禁止把 sk- 作为 Balance Token |
mcp/src/core/payment-links.js |
新增 buildTokenizedBalanceUrl(sessionToken);新增统一 recharge formatter;旧 APIG/workshop URL 只供明确的旧产品流程,不再用于 NewAPI 402 |
mcp/src/core/billing-client.js |
调用唯一 billing query;支持 include、endpoint 筛选、追踪筛选;返回结构化 balance/pricing/usage |
mcp/src/core/usage-context.js |
创建并传递 usageTraceId/reportId/skillId/workflowType/stepId/requestId;写本地运行元数据 |
mcp/src/core/budget-guard.js |
接收 Agent 计划和价格,计算三档预估、剩余成本、差额、建议充值金额;批次前阻断超预算 |
mcp/src/core/recharge-client.js |
使用 Session 调现有建单、支付码、状态查询;写二维码文件;返回 Tokenized URL;到账后刷新余额并触发 L1 续跑 |
mcp/src/core/result-envelope.js |
在保持现有字段的前提下统一可选 usage/estimate/recharge/checkpoint;确保失败友好状态 errors=[] |
mcp/src/core/activation.js |
缺 Token 只返回配置恢复;确认 402 才进入统一 recharge;移除默认打开旧 APIG/workshop 页的行为 |
| 文件 | 必须修改的行为 |
|---|---|
mcp/src/providers/voc-gateway.js |
接收 credential context;携带追踪头;记录实际 authMode/billingMode;响应返回 usage;401 时才尝试 Session 身份;402/403 不混淆 |
mcp/src/providers/ecommerce-gateway.js |
复用同一个 callGateway() 或公共基类,只保留根地址与 envelope 差异 |
mcp/src/providers/overseas-gateway.js |
复用统一调用器,同时保留 /forward 请求封装 |
mcp/src/providers/xiaohongshu-api.js |
删除独立 fetch/error classifier,改用 social gateway;每个便捷方法传 endpoint、credential context 和 usage context |
mcp/src/providers/douyin-api.js |
与小红书相同,保证两个平台专用路径不再绕过统一计费和充值逻辑 |
mcp/src/features/xiaohongshu-trend/live-collector.js |
不再只收一个 token;传递 credential/usage context;每个搜索、详情、评论调用保留 requestId、费用和业务键 |
mcp/src/features/douyin-trend/live-collector.js |
同上;视频、评论和翻页均写检查点并汇总实际 usage |
| 文件 | 必须修改的行为 |
|---|---|
mcp/src/tools/voc-api-catalog-run.js |
删除 `endpoint.billing |
mcp/src/tools/xiaohongshu-trend-run.js |
删除所有分散的 buildVocRechargeInfo() 分支;使用统一预算、检查点和 recharge;部分结果也返回同一链接/二维码协议 |
mcp/src/tools/douyin-trend-run.js |
与小红书完全同源,不再重复猜测 402/403 |
mcp/src/features/voc-business-workflow/business-workflow.js |
非 ok 时原样透传 recharge/usage/estimate/checkpoint/files;成功时合并各步骤实际费用,不只包装文字 |
mcp/src/tools/voc-business-workflow-run.js |
schema 和输出契约增加预算、估算、账单与续跑字段 |
mcp/src/features/fmode-image-analysis/image-analysis.js |
使用类型化 credential;402 使用统一 NewAPI recharge,403 返回 permission;模型 usage 写同一追踪上下文 |
mcp/src/tools/fmode-image-analysis.js |
schema 注册 usage context 和统一结果字段,不泄露 Token |
mcp/src/tools/voc-cost-estimate-run.js |
接收 Agent 计划,筛选所需 endpoint 价目并输出三档报价;不让服务端决定调用次数 |
mcp/src/tools/voc-usage-report-run.js |
按当前用户和追踪标识读取实际频次、quota、人民币费用和质量标识 |
mcp/src/server.js |
注册新工具;统一 Token check;所有计费工具 schema 支持预算和上下文,但继续允许自然语言调用 |
| 文件 | 必须修改的行为 |
|---|---|
mcp/src/core/api-catalog.js |
对外输出稳定 endpointId/channel/method/path/billingUnit/mediaFields;不输出伪价格 |
mcp/catalog/voc-social-endpoints.json |
修正三通道认证和计费说明;为已登记接口补稳定 endpoint 元数据;去除“Session 回退扣旧额度”表述 |
mcp/catalog/params/*.json |
仅保留参数和计费单位相关元数据,权威价格不复制到技能包 |
skills/voc-api-catalog/SKILL.md、skills/voc-api-catalog/references/error-codes.md |
作为全包计费规则的单一说明源;统一 401/402/403、Session-to-NewAPI、Tokenized Balance 和 QR 规则 |
skills/xiaohongshu-trend-intelligence/*、skills/douyin-trend-intelligence/* |
删除旧固定 Studio/APIG 链接和旧 Session 额度描述;引用统一规则;要求部分报告保留充值及检查点 |
skills/voc-business-workflow/SKILL.md |
要求成本预估、实际账单和充值上下文穿透业务包装 |
skills/fmode-image-analysis/SKILL.md |
统一模型 402/403 和充值输出 |
skills/voc-issue-pool/SKILL.md、voc-problem-deep-dive/SKILL.md、voc-competitor-map/SKILL.md、voc-content-plan/SKILL.md、voc-speaking-script/SKILL.md |
说明自身直接费用或继承上游/Agent 模型费用的规则;组成业务闭环时共享同一 usage trace,避免账单漏项 |
README.md、docs/payment-package-links.md、docs/live-manual-acceptance-checklist.md |
更新用户流程、接口数量边界、二维码和免登录链接示例;示例只用占位 Token |
.claude-plugin/plugin.json、skill-package-manifest.json、package.json、package-lock.json |
同步工具注册、版本和产物清单 |
| 文件 | 必须修改的行为 |
|---|---|
fmode-server/modules/shared/newapi-metering.ts |
接受统一 principal 和 resolved rule;同一事务检查用户/Token quota、幂等扣费、写 actual cost 和追踪字段 |
fmode-server/modules/shared/newapi-user-auth.ts |
严格校验 sk-,解析真实 NewAPI 用户;补齐当前 AuthService 对 sk- 未验证的问题 |
fmode-server/modules/shared/session-newapi-principal.ts |
严格校验 Session;按 Parse user id 查 NewAPI users.parse_id;必要时调用幂等同步;返回计费 principal |
fmode-server/modules/shared/voc-pricing.ts |
统一 endpoint 路径规范化、价格读取、版本、缓存政策和模块回退 |
fmode-server/modules/voc-social-api/src/routes.ts |
移除新模式正常路径上的 APIGAuth.count;业务成功才调用统一 metering;接收追踪字段;返回 usage |
fmode-server/modules/voc-e-commerce/src/routes.ts |
与 social 路由共享 principal、价格、成功判断和扣费顺序 |
fmode-server/modules/voc-ecom-api/src/routes.ts |
与前两者一致;保留海外 /forward 业务封装 |
api/api-ncloud/fmode/sync-fmode-api.js |
保持 syncUser() 幂等,提供 Session 用户到 NewAPI 账户映射能力;不得在普通日志输出 Token |
api/api-ncloud/fmode/newapi-user-resolution.js |
继续处理 parse_id/username 冲突,增加计费身份映射测试 |
fmode-server/api/routes.ts + fmode-server/modules/shared/newapi-metering.ts |
实现唯一新增用户计费查询接口;同一认证解析 balance、pricing、usage;强制当前 user 条件和筛选白名单。Storage 路由不由技能包调用 |
api/api-ncloud/fmode/routes.js |
保持 /recharge/order 契约;回归 tradeNo 幂等、金额校验和 Session 身份 |
api/api-ncloud/fmode/serv-user.js、sync-fmode-api.js、cloud/user/auth-route.js |
回归 AccountLog -> pay_code2 -> order_status2 -> topUpNewApiQuota;重复回调不重复到账 |
api/api-ncloud/profit/* |
管理员看板读取新实际金额和追踪字段,同时兼容历史日志 |
fmode-server/api/routes.ts、三个模块构建脚本、.modules/voc-*.min.cjs |
源码路由和生产构建同时包含共享认证/计费实现;无需单独的 billing .min.cjs |
Studio 已有 /balance、Token 免登录、NewAPI 余额、支付二维码、订单轮询和到账刷新,首期不重做这些能力。需要的调整只有:
token/session -> Parse.User.become() 和消费后清理地址栏。由于 fmode-studio 当前本地分支存在未提交且与远端重叠的修改,编码时必须以工作树为基线增量合并,禁止用远端文件整体覆盖。
sk- 调用 social、ecommerce、overseas:只扣对应 NewAPI 账户一次。APIGAuth.count 不变。sk- 401 + 有效 Session:Session 身份继续请求,仍写 NewAPI 日志。needs_permission,不生成充值入口。requestId 重放不重复扣费;相同 id 搭配不同 endpoint/quota 返回冲突。assistantMessage 同时含差额、建议金额、可点击 Tokenized Balance 链接,并优先返回二维码文件或 URL。recharge.balanceUrl 和当前用户消息出现;其他字段、日志、报告、测试快照均不出现 Session。/recharge/order -> pay_code2 -> order_status2 能建单、出码、轮询和到账;重复建单/回调保持幂等。voc_api_call 三通道均返回同一 usage/recharge 结构。voc_business_workflow 不丢失底层 recharge/usage/estimate/checkpoint/files。sk-、Session、错误类型和是否具备个人支付能力,而不回显凭证。billing 推导人民币价格。smoke-mcp 覆盖新工具发现、统一结果字段和业务工作流透传。smoke-package 检查所有计费 Skill 引用统一规则且无旧链接。.modules 后再次扫描明文凭证、旧固定充值入口、amount= Balance 链接和把 usageTraceId 当支付 ID 的表述。APIGAuth.count、支付到账和报告实际账单,四者必须一致。新技能包不能先于 Session-to-NewAPI 后端计费能力全量发布,否则 sk- 失败后的 Session 回退仍会扣旧余额。发布顺序应为:
sk- 与 Session 映射到同一用户,并对比影子金额。APIGAuth.count 不变。必须提供以下开关:
要保证新模式正常运行,P0 不能只做页面和一个查询接口。必须同时完成以下最小闭环:
sk- 和 Session 两种身份都统一扣 NewAPI 余额。/balance/?token=... 自助链接。这六项同时完成,才能满足“所有任务统一扣 NewAPI、Agent 能估价、余额不足能直接付费、充值后能继续、Balance 能看清用量”的完整业务目标。