5c6840dd71
- comparison_record 加 llm_cost_yuan(元/float)+ llm_price_snapshot(JSON)两列 - _backfill_llm_calls 回填时按 app_config 当时单价逐模型算成本、冻结成本+快照到记录 - app_config 新增 llm_token_price 配置(per_model + default 兜底,运营在系统配置页可改) - services/llm_cost.py:compute_llm_cost 纯函数(按 model 分桶、error/无 usage 跳过、 脏价格当 unpriced 不抛异常以免连累 token 回填)+ get_llm_prices reader - admin schema 暴露成本:列表项带 llm_cost_yuan,详情另带价格快照 - tests/test_llm_cost.py(10 测试);scripts/seed_mock_llm_cost.py(mock seeder) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: guke <guke@autohome.com.cn> Reviewed-on: #133
34 lines
1.3 KiB
Python
34 lines
1.3 KiB
Python
"""comparison_record: llm_cost_yuan + llm_price_snapshot(比价 LLM 调用成本 + 当时单价快照)
|
|
|
|
回填 llm_calls 时按「当时的价」逐模型算出本次比价 LLM 总成本(元),连同所用单价快照一起冻结到
|
|
记录上;admin 比价记录详情展示实际成本(旧记录 NULL → 前端回退估算)。见 services/llm_cost.py。
|
|
|
|
Revision ID: comparison_llm_cost
|
|
Revises: ad_ecpm_trace_id
|
|
Create Date: 2026-07-13
|
|
"""
|
|
from collections.abc import Sequence
|
|
|
|
import sqlalchemy as sa
|
|
from sqlalchemy.dialects import postgresql
|
|
|
|
from alembic import op
|
|
|
|
revision: str = "comparison_llm_cost"
|
|
down_revision: str | Sequence[str] | None = "ad_ecpm_trace_id"
|
|
branch_labels: str | Sequence[str] | None = None
|
|
depends_on: str | Sequence[str] | None = None
|
|
|
|
_JSONB = sa.JSON().with_variant(postgresql.JSONB(), "postgresql")
|
|
|
|
|
|
def upgrade() -> None:
|
|
# 均可空、无索引;SQLite 原生支持 ADD COLUMN,无需 batch_alter_table(同 comparison_debug_fields)。
|
|
op.add_column("comparison_record", sa.Column("llm_cost_yuan", sa.Float(), nullable=True))
|
|
op.add_column("comparison_record", sa.Column("llm_price_snapshot", _JSONB, nullable=True))
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.drop_column("comparison_record", "llm_price_snapshot")
|
|
op.drop_column("comparison_record", "llm_cost_yuan")
|