Initial travel knowledge graph release

This commit is contained in:
2026-06-09 09:56:26 +08:00
commit 5f061295d8
402 changed files with 103877 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
"""STEP 02 — Simulation Panel CRUD + multi-source question intake.
Question bank for the AI quality audit. Sources:
manual 手工添加
imported 批量导入的真实用户问题
resolved 从"已答好"的 question_traces 采纳的回归用例
ai_gen AI 生成的覆盖性问题
"""
from fastapi import APIRouter, HTTPException
from app.auth import CurrentUser
from app.config import settings
from app.contracts import SimulationQuestion, SimulationQuestionUpdate
from app.db import (
list_simulation_questions,
create_simulation_question,
update_simulation_question,
delete_simulation_question,
bulk_create_simulation_questions,
adopt_hit_question_traces,
)
router = APIRouter()
_T = settings.default_tenant
_P = settings.default_project
@router.get("/simulation-panel")
async def _list(_user: CurrentUser = None):
return await list_simulation_questions(_T, _P)
@router.post("/simulation-panel")
async def _create(body: SimulationQuestion, _user: CurrentUser):
data = body.model_dump()
data["tenant_id"] = _T
data["project_id"] = _P
data["source"] = "manual"
return await create_simulation_question(data)
@router.post("/simulation-panel/import")
async def _import(body: dict, _user: CurrentUser):
"""Bulk import real user questions — one per line, or a list."""
raw = body.get("text") or body.get("questions") or ""
texts = raw if isinstance(raw, list) else str(raw).splitlines()
added = await bulk_create_simulation_questions(_T, _P, texts, "imported")
return {"added": added}
@router.post("/simulation-panel/adopt-hits")
async def _adopt_hits(_user: CurrentUser):
"""Adopt well-answered questions as regression cases (source=resolved)."""
added = await adopt_hit_question_traces(_T, _P)
return {"added": added}
@router.post("/simulation-panel/ai-generate")
async def _ai_generate(body: dict, _user: CurrentUser):
"""Let the LLM propose representative coverage questions."""
from app.llm_client import LlmClient
llm = LlmClient.from_settings() if settings.llm_api_key else None
if not llm or not llm.available():
raise HTTPException(400, "未配置 LLMAgent 设置里填好 API Key 后可用)")
count = max(1, min(int(body.get("count", 10)), 30))
topic = (body.get("topic") or "城市本地生活知识图谱(地点、区域、路线、夜间体验、标签)").strip()
try:
out = llm.chat_json(
system=(
"你是知识图谱质量稽查助手。请基于给定主题,生成有代表性、"
"覆盖不同场景的真实用户中文问题,用于检验知识图谱数据的完善度。"
'严格返回 JSON{"questions": ["...", "..."]}'
),
user=f"主题:{topic}。生成 {count} 个不同角度、不重复的问题。",
)
qs = out.get("questions") or []
qs = [str(q).strip() for q in qs if str(q).strip()][:count]
except Exception as e:
raise HTTPException(400, f"AI 生成失败:{str(e)[:160]}")
added = await bulk_create_simulation_questions(_T, _P, qs, "ai_gen")
return {"added": added, "generated": len(qs)}
@router.patch("/simulation-panel/{q_id}")
async def _update(q_id: int, body: SimulationQuestionUpdate, _user: CurrentUser):
row = await update_simulation_question(q_id, body.model_dump(exclude_none=True))
if not row:
raise HTTPException(404, "Simulation question not found")
return row
@router.delete("/simulation-panel/{q_id}")
async def _delete(q_id: int, _user: CurrentUser):
await delete_simulation_question(q_id)
return {"ok": True}