Files
group_fqcd_jr/tools/seed_risk_agent_config.py

135 lines
6.3 KiB
Python

"""创建风控 Agent 本地验收所需的模型端点和发布配置。"""
from __future__ import annotations
import asyncio
import hashlib
import json
import sys
from datetime import UTC, datetime
from pathlib import Path
from sqlalchemy import text
PROJECT_ROOT = Path(__file__).resolve().parents[1]
if str(PROJECT_ROOT) not in sys.path:
sys.path.insert(0, str(PROJECT_ROOT))
from app.infrastructure.db import SessionFactory # noqa: E402
ADMIN_USER_ID = 9003
ENDPOINT_CODE = "deepseek-flash"
RELEASE_NO = "risk-agent-local-v1"
TOOL_CONFIGS = (
("risk:risk_overview", {"allowed_tools": ["get_risk_overview"]}),
("risk:risk_search", {"allowed_tools": ["search_risk_alerts"]}),
("risk:risk_evidence", {"allowed_tools": ["get_alert_evidence"]}),
("risk:general", {"allowed_tools": []}),
)
INTENT_CONFIGS = (
("risk_overview", "风险概览", ["请查看当前风险概览", "当前有多少高风险预警"], ["get_risk_overview"]),
("risk_search", "风险查询", ["查询高风险预警", "查看规则 RW-007 命中的预警"], ["search_risk_alerts"]),
("risk_evidence", "预警证据", ["查询预警编号 ALERT-001 的证据", "查看这条预警的证据链"], ["get_alert_evidence"]),
("general", "通用风险咨询", ["奶龙风控智能助手能做什么", "说明你的功能边界"], []),
)
def checksum(value: dict) -> str:
payload = json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":"))
return hashlib.sha256(payload.encode("utf-8")).hexdigest()
async def seed() -> None:
now = datetime.now(UTC).replace(tzinfo=None)
async with SessionFactory() as session:
await session.execute(text("""
INSERT INTO model_endpoint_config
(endpoint_code, provider, model_name, base_url, secret_ref, capabilities,
allowed_data_levels, context_window, timeout_ms, status, created_by,
reviewer_id, reviewed_at, created_at, updated_at)
VALUES
(:endpoint_code, 'deepseek', 'deepseek-chat', 'https://api.deepseek.com',
'env:DEEPSEEK_API_KEY', :capabilities, :data_levels, 64000, 30000,
'active', :admin_id, :admin_id, :now, :now, :now)
ON DUPLICATE KEY UPDATE
provider=VALUES(provider), model_name=VALUES(model_name),
base_url=VALUES(base_url), secret_ref=VALUES(secret_ref),
capabilities=VALUES(capabilities), allowed_data_levels=VALUES(allowed_data_levels),
context_window=VALUES(context_window), timeout_ms=VALUES(timeout_ms),
status='active', reviewer_id=:admin_id, reviewed_at=:now, updated_at=:now
"""), {
"endpoint_code": ENDPOINT_CODE,
"capabilities": json.dumps([
"chat",
"intent_classification",
"risk_answer",
"text_generation",
]),
"data_levels": json.dumps(["internal"]),
"admin_id": ADMIN_USER_ID,
"now": now,
})
release_id = await session.scalar(
text("SELECT id FROM config_release WHERE status='active' LIMIT 1")
)
if release_id is None:
result = await session.execute(text("""
INSERT INTO config_release
(release_no, title, change_summary, status, created_by, reviewer_id,
reviewed_at, activated_at, created_at, updated_at)
VALUES (:release_no, '奶龙风控智能助手本地配置',
'发布 risk Agent 工具白名单和意图配置', 'active',
:admin_id, :admin_id, :now, :now, :now, :now)
"""), {"release_no": RELEASE_NO, "admin_id": ADMIN_USER_ID, "now": now})
release_id = int(result.lastrowid)
for config_key, value in TOOL_CONFIGS:
await session.execute(text("""
INSERT INTO platform_config_item
(release_id, namespace, config_key, value_json, schema_version, checksum, created_at)
VALUES (:release_id, 'agent_tools', :config_key, :value_json, '1', :checksum, :now)
ON DUPLICATE KEY UPDATE
value_json=VALUES(value_json), schema_version=VALUES(schema_version),
checksum=VALUES(checksum)
"""), {
"release_id": release_id,
"config_key": config_key,
"value_json": json.dumps(value, ensure_ascii=False),
"checksum": checksum(value),
"now": now,
})
for intent_code, intent_name, examples, allowed_tools in INTENT_CONFIGS:
await session.execute(text("""
INSERT INTO agent_intent_config
(agent_type, intent_code, intent_name, description, examples,
classifier_instruction, confidence_threshold, max_clarification_rounds,
transfer_on_failure, allowed_tools, priority, version, status,
effective_at, created_by, reviewer_id, reviewed_at, created_at, updated_at)
VALUES
('risk', :intent_code, :intent_name, :description, :examples,
:instruction, 0.6500, 2, 1, :allowed_tools, 100, 1, 'active',
:now, :admin_id, :admin_id, :now, :now, :now)
ON DUPLICATE KEY UPDATE
intent_name=VALUES(intent_name), description=VALUES(description),
examples=VALUES(examples), classifier_instruction=VALUES(classifier_instruction),
allowed_tools=VALUES(allowed_tools), status='active',
effective_at=:now, reviewer_id=:admin_id, reviewed_at=:now, updated_at=:now
"""), {
"intent_code": intent_code,
"intent_name": intent_name,
"description": f"奶龙风控智能助手:{intent_name}",
"examples": json.dumps(examples, ensure_ascii=False),
"instruction": "只处理风控只读查询、分析和边界说明,不执行人工处置。",
"allowed_tools": json.dumps(allowed_tools, ensure_ascii=False),
"admin_id": ADMIN_USER_ID,
"now": now,
})
await session.commit()
print(f"risk_agent_config_ready release_id={release_id} endpoint={ENDPOINT_CODE}")
if __name__ == "__main__":
asyncio.run(seed())