style: auto-format with black + isort + ruff + prettier [skip ci-format-check]
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 1s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 0s
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 1m49s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 1m53s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m18s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m8s
AI Code Review / AI Code Review (pull_request) Successful in 6m59s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 7m51s
CI/CD Pipeline / Validate - Style (pull_request) Failing after 8m30s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 8m38s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 10m39s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 10m37s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 23m5s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Failing after 1s

This commit is contained in:
CI Bot
2026-10-05 15:32:27 +00:00
parent 3bd86a272d
commit 051e28512c
3 changed files with 33 additions and 17 deletions
@@ -2,6 +2,7 @@
"""V2 prompt 解析:优先读后台 viral_video_prompt_templates 配置,30s TTL 热加载;
DB 不可用/读到默认XML模板时,fallback 到硬编码 JSON schema prompt。
"""
from __future__ import annotations
import logging
@@ -80,6 +81,7 @@ def _load_template() -> Any | None:
"""从DB读image_analysis模板,失败返回None。"""
try:
from packages.application.viral_video.prompt_loader import get_template
return get_template("image_analysis")
except Exception as e:
logger.warning("[vision.v2] 读取后台prompt配置失败: %s", e)
@@ -131,15 +133,15 @@ def _resolve(kind: str) -> tuple[str, str]:
sys_prompt = custom_sys + tail
if custom_user_tpl:
# V2 是单图调用,简单替换几个常用占位符;缺键原样保留
usr_prompt = (custom_user_tpl
.replace("{image_count}", "1")
.replace("{industry}", "通用")
.replace("{image_urls}", "")
.strip())
usr_prompt = (
custom_user_tpl.replace("{image_count}", "1")
.replace("{industry}", "通用")
.replace("{image_urls}", "")
.strip()
)
if not usr_prompt:
usr_prompt = default_user
logger.info("[vision.v2] 使用后台自定义prompt (kind=%s version=%s)",
kind, getattr(tpl, "version", "?"))
logger.info("[vision.v2] 使用后台自定义prompt (kind=%s version=%s)", kind, getattr(tpl, "version", "?"))
except Exception as e:
logger.warning("[vision.v2] 解析后台prompt失败,使用默认: %s", e)
@@ -131,10 +131,13 @@ def call_pro_vlm(
"model": _PRO_MODEL,
"messages": [
{"role": "system", "content": system_prompt},
{"role": "user", "content": [
{"type": "image_url", "image_url": {"url": img_url}},
{"type": "text", "text": user_prompt},
]},
{
"role": "user",
"content": [
{"type": "image_url", "image_url": {"url": img_url}},
{"type": "text", "text": user_prompt},
],
},
],
"temperature": 0.3,
"max_tokens": _DEFAULT_MAX_TOKENS,
@@ -165,8 +168,11 @@ def call_pro_vlm(
reasoning_tokens = ctd.get("reasoning_tokens", 0)
logger.info(
"[vision.v2] pro 完成 model=%s elapsed=%.1fs in=%d out=%d reasoning=%d",
_PRO_MODEL, elapsed,
usage.get("prompt_tokens", 0), usage.get("completion_tokens", 0), reasoning_tokens,
_PRO_MODEL,
elapsed,
usage.get("prompt_tokens", 0),
usage.get("completion_tokens", 0),
reasoning_tokens,
)
s = raw.strip()
if s.startswith("```"):
@@ -102,7 +102,9 @@ def call_fast_json(
)
elapsed = time.time() - t0
if resp.status_code != 200:
logger.warning("[vision.v2] fast_json HTTP %d elapsed=%.1fs body=%s", resp.status_code, elapsed, resp.text[:200])
logger.warning(
"[vision.v2] fast_json HTTP %d elapsed=%.1fs body=%s", resp.status_code, elapsed, resp.text[:200]
)
return None
data = resp.json()
raw = (data.get("choices") or [{}])[0].get("message", {}).get("content")
@@ -116,8 +118,11 @@ def call_fast_json(
reasoning_tokens = ctd.get("reasoning_tokens", 0)
logger.info(
"[vision.v2] fast_json 完成 model=%s elapsed=%.1fs in=%d out=%d reasoning=%d",
_FAST_MODEL, elapsed,
usage.get("prompt_tokens", 0), usage.get("completion_tokens", 0), reasoning_tokens,
_FAST_MODEL,
elapsed,
usage.get("prompt_tokens", 0),
usage.get("completion_tokens", 0),
reasoning_tokens,
)
text = _strip_code_fence(raw)
lpos, r = text.find("{"), text.rfind("}")
@@ -133,7 +138,10 @@ def call_fast_json(
return None
logger.info(
"[vision.v2] fast_json 完成 elapsed=%.1fs has_person=%s has_product=%s category=%s",
elapsed, obj.get("has_person"), obj.get("has_product"), obj.get("category"),
elapsed,
obj.get("has_person"),
obj.get("has_product"),
obj.get("category"),
)
return obj
except Exception as e: