fix(skills): skills 随后端打进镜像,根治线上提取「未返回有效 JSON」(系统提示词为空)
真因(查 dev 库 + 重放真实失败请求 + 真调 ARK 定位):线上提取的 system 提示词长度=0。
core-api 镜像由 `./core/backend` 构建,而 skills/ 在仓库根、不在构建上下文 → 镜像里没有
→ _load_skill_system_prompt 返回空串 → 模型收不到「只输出 JSON」铁律 → 吐 markdown/散文
→ 正则抽不到 {} → 「提取结果解析失败(模型未返回有效 JSON)」。本地有 skills 故一直没复现。
(脚本生成同样受影响,只是它有退化兜底提示词,质量打折但不报错。)
验证:用 dev 库里你那条失败请求的真实脚本重放——空 system→无 JSON;补上 skill 提示词
→ 立即出 JSON(角色/场景齐、商品不提)。
改动:
- skills/ → core/backend/skills/(git mv,进构建上下文,Dockerfile `COPY . .` 自动打包)。
- services._skills_root()/script_agent._skill_dir():优先 BASE_DIR/skills,回落仓库根(双兜底)。
- worker 失败时也落 response_payload(含 content / reasoning 预览 / system_chars),
以后再坏一眼就能定位(本次正是因为失败没存返回,白绕一圈)。
- 回归测试 2 条:skills 必须在 BASE_DIR 内(随镜像走)+ 提取提示词非空且含 JSON 铁律。
- CLAUDE.md 标注 skills 必须放 core/backend 内的原因。
验收:完整 Django 套件 151/151 全绿。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
c8cb6d3d51
commit
8dab8b4921
@@ -1,10 +1,35 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from django.conf import settings
|
||||
from django.test import SimpleTestCase
|
||||
|
||||
from apps.ai.script_agent import normalize_draft
|
||||
|
||||
|
||||
class SkillPromptBundlingTests(SimpleTestCase):
|
||||
"""守护「skills 必须随后端打进镜像」这条线 —— 历史上 skills 放仓库根、不在 Docker 构建上下文
|
||||
(`./core/backend`)→ 镜像里没有 → 提示词加载为空 → 提取模型收不到「只输出 JSON」铁律 → 吐散文
|
||||
→ 「提取结果解析失败」。这两条断言锁死:① skills 落在 BASE_DIR 内(随镜像走);② 提示词非空且带铁律。"""
|
||||
|
||||
def test_skills_dir_bundled_under_base_dir(self):
|
||||
"""skills 必须在 BASE_DIR(=core/backend)内,才会被 Dockerfile 的 `COPY . .` 打进镜像。"""
|
||||
for name in ("ecommerce-entity-extract", "ecommerce-video-script"):
|
||||
self.assertTrue(
|
||||
(Path(settings.BASE_DIR) / "skills" / name / "SKILL.md").exists(),
|
||||
f"skills/{name}/SKILL.md 不在 BASE_DIR 内 —— 镜像将丢失该提示词(详见 services._skills_root)",
|
||||
)
|
||||
|
||||
def test_entity_extract_prompt_loads_nonempty_with_json_rule(self):
|
||||
"""提取系统提示词必须加载到非空内容,且含「只输出 JSON」铁律(空 → 模型不吐 JSON → 解析失败)。"""
|
||||
from apps.ai.services import _load_skill_system_prompt
|
||||
|
||||
prompt = _load_skill_system_prompt("ecommerce-entity-extract")
|
||||
self.assertGreater(len(prompt), 1000, "提取提示词为空/过短 —— skills 没被正确加载")
|
||||
self.assertIn("JSON", prompt)
|
||||
self.assertIn("entities", prompt)
|
||||
|
||||
|
||||
class NormalizeDraftTests(SimpleTestCase):
|
||||
"""normalize_draft 对模型不按契约输出的容错(防「旁白/画面全空」回归)。"""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user