llm_usage_event.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. from __future__ import annotations
  2. from datetime import datetime
  3. from decimal import Decimal
  4. from sqlalchemy import (
  5. BigInteger,
  6. DateTime,
  7. Index,
  8. Integer,
  9. Numeric,
  10. String,
  11. func,
  12. )
  13. from sqlalchemy.orm import Mapped, mapped_column
  14. from supply_infra.db.base import Base
  15. class LlmUsageEvent(Base):
  16. """单次 LLM 调用的用量与费用明细。"""
  17. __tablename__ = "llm_usage_event"
  18. __table_args__ = (
  19. Index("idx_llm_usage_biz_dt", "biz_dt"),
  20. Index("idx_llm_usage_biz_agent", "biz_dt", "agent_name"),
  21. Index("idx_llm_usage_biz_model", "biz_dt", "model"),
  22. Index("idx_llm_usage_run_id", "run_id"),
  23. Index("idx_llm_usage_created", "created_at"),
  24. )
  25. id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
  26. biz_dt: Mapped[str] = mapped_column(
  27. String(8),
  28. nullable=False,
  29. comment="业务日 YYYYMMDD(Asia/Shanghai)",
  30. )
  31. provider: Mapped[str] = mapped_column(
  32. String(32),
  33. nullable=False,
  34. default="openrouter",
  35. comment="提供商 openrouter / dashscope 等",
  36. )
  37. model: Mapped[str | None] = mapped_column(String(128), nullable=True, comment="模型名")
  38. agent_name: Mapped[str | None] = mapped_column(
  39. String(128),
  40. nullable=True,
  41. comment="Agent 名称",
  42. )
  43. run_id: Mapped[str | None] = mapped_column(String(128), nullable=True, comment="Agent run id")
  44. iteration: Mapped[int | None] = mapped_column(Integer, nullable=True, comment="ReAct 迭代序号")
  45. prompt_tokens: Mapped[int] = mapped_column(
  46. Integer,
  47. nullable=False,
  48. default=0,
  49. comment="输入 token 数",
  50. )
  51. completion_tokens: Mapped[int] = mapped_column(
  52. Integer,
  53. nullable=False,
  54. default=0,
  55. comment="输出 token 数",
  56. )
  57. total_tokens: Mapped[int] = mapped_column(
  58. Integer,
  59. nullable=False,
  60. default=0,
  61. comment="总 token 数",
  62. )
  63. cost_usd: Mapped[Decimal | None] = mapped_column(
  64. Numeric(14, 8),
  65. nullable=True,
  66. comment="本次调用费用(USD,优先取 provider 返回的 usage.cost)",
  67. )
  68. created_at: Mapped[datetime] = mapped_column(
  69. DateTime,
  70. nullable=False,
  71. server_default=func.now(),
  72. comment="记录时间",
  73. )