Files
loom/backend/app/scripts/seed_p6.py
T
2026-04-24 17:46:03 +08:00

122 lines
3.9 KiB
Python

"""P6 种子:OpenAI provider + 2 个模型 + 默认路由规则。
API Key 从 `.env` 的 `OPENAI_API_KEY` 读取;未配置也能建 provider(走 mock)。
执行:python -m app.scripts.seed_p6
"""
from __future__ import annotations
import asyncio
from sqlalchemy import delete, insert, select
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.config import settings
from app.core.crypto import encrypt
from app.db.session import AsyncSessionLocal
from app.models import LLMModel, LLMProvider, LLMRoutingRule
DEFAULT_PROVIDER = {
"code": "openai",
"name": "OpenAI",
"vendor": "openai",
"api_base": settings.OPENAI_API_BASE or "https://api.openai.com/v1",
"description": "OpenAI 官方;联调阶段如 .env 未配 OPENAI_API_KEY,调用将走 mock 回显",
}
DEFAULT_MODELS = [
{
"model": "gpt-4o-mini",
"name": "GPT-4o mini",
"description": "通用场景推荐;响应快、成本低",
"max_context": 128_000,
"price_input_per_1k": 0.00015,
"price_output_per_1k": 0.00060,
},
{
"model": "gpt-4o",
"name": "GPT-4o",
"description": "高复杂度推理",
"max_context": 128_000,
"price_input_per_1k": 0.0025,
"price_output_per_1k": 0.01,
},
]
async def upsert(db: AsyncSession, model, key_field: str, value, **defaults):
stmt = select(model).where(getattr(model, key_field) == value)
obj = (await db.execute(stmt)).scalar_one_or_none()
if obj is None:
obj = model(**{key_field: value}, **defaults)
db.add(obj)
await db.flush()
else:
for k, v in defaults.items():
setattr(obj, k, v)
return obj
async def seed() -> None:
async with AsyncSessionLocal() as db:
prov = await upsert(
db, LLMProvider, "code", DEFAULT_PROVIDER["code"],
name=DEFAULT_PROVIDER["name"],
vendor=DEFAULT_PROVIDER["vendor"],
api_base=DEFAULT_PROVIDER["api_base"],
description=DEFAULT_PROVIDER["description"],
)
if settings.OPENAI_API_KEY:
prov.api_key_cipher = encrypt(settings.OPENAI_API_KEY)
await db.flush()
models: dict[str, LLMModel] = {}
for m in DEFAULT_MODELS:
stmt = select(LLMModel).where(
LLMModel.provider_id == prov.id, LLMModel.model == m["model"]
)
obj = (await db.execute(stmt)).scalar_one_or_none()
if obj is None:
obj = LLMModel(provider_id=prov.id, **m)
db.add(obj)
await db.flush()
else:
for k, v in m.items():
setattr(obj, k, v)
models[m["model"]] = obj
# 默认路由规则:无条件兜底 → gpt-4o-mini
await db.execute(
delete(LLMRoutingRule).where(LLMRoutingRule.name == "default")
)
db.add(LLMRoutingRule(
name="default",
priority=1000,
conditions=None,
model_id=models["gpt-4o-mini"].id,
enabled=True,
description="全局兜底路由",
))
# 高质量:category=ad 或 reasoning 命中 gpt-4o
await db.execute(
delete(LLMRoutingRule).where(LLMRoutingRule.name == "premium")
)
db.add(LLMRoutingRule(
name="premium",
priority=10,
conditions={"category": "reasoning"},
model_id=models["gpt-4o"].id,
enabled=True,
description="高复杂度推理使用 gpt-4o",
))
await db.commit()
print("[seed_p6] done.")
print(f" provider: {prov.code} (api_key_configured={bool(settings.OPENAI_API_KEY)})")
print(f" models: {list(models.keys())}")
print(f" rules: default(gpt-4o-mini) / premium(category=reasoning → gpt-4o)")
if __name__ == "__main__":
asyncio.run(seed())