feat: PromptProvider 化 + $DEFLECTION_POOL 单一事实源注入 + runtime 必填化
- PromptProvider(app/engine/services/ai_service.py): 租户提示词四件套 from_dir 加载;build_system 把 system.md 的 $DEFLECTION_POOL 占位符替换为 wall.json deflections 话术池(按语言分组一行,EN/ZH/ES)再拼事实卡; extractor/evaluator 的 $existing_info/$messages/$profile/$recent_messages 替换逻辑自 AIService 原样搬入(行为等价);删模块级 import 时读文件的 PROMPTS_DIR 与四个常量,保留 DEFAULT_PROVIDER(jiancai 出厂,__file__ 锚定) - 两租户 system.md「三类请求的处理」第2条的迂回话术枚举 → $DEFLECTION_POOL 占位符(保留段落说明文字),话术只存 wall.json 一份,改一处两边同步变 - TenantRuntime 加 prompts 字段(加载期 from_dir(seed_dir/prompts)); ConversationManager 的 runtime 转必填(keyword-only),默认 AIService 用 runtime.prompts + compiled_wall.deflections 组装 - app/engine/prompts/ 删除(grep 无代码消费方,jiancai 出厂由 seed_profiles/jiancai/prompts 承接);test_company_facts/ test_system_prompt_dual_contact 的 cwd 相对路径改 Path(__file__) 锚定, test_extractor_evaluator_prompts 断言对象改 DEFAULT_PROVIDER(语义等价) - 新增 tests/test_prompt_provider.py(14 用例): 加载/注入/格式/占位符防漂移/ extractor-evaluator 组装/registry 接线/runtime 必填/池线过两墙 Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,16 @@
|
||||
"""公司事实卡: 拼接位置与墙安全性静态测试。"""
|
||||
from pathlib import Path
|
||||
"""公司事实卡: 拼接位置与墙安全性静态测试。
|
||||
|
||||
from app.engine.services.ai_service import AIService, COMPANY_FACTS, SYSTEM_PROMPT
|
||||
Task 6 迁移: 提示词四件套随租户化落位 seed_profiles/<slug>/prompts/,
|
||||
代码级默认 = DEFAULT_PROVIDER(jiancai 出厂,与 seed_profiles/jiancai/
|
||||
prompts 逐字节同源)——本文件断言对象从模块常量改为 DEFAULT_PROVIDER
|
||||
字段,断言语义等价。
|
||||
"""
|
||||
from app.engine.services.ai_service import AIService, DEFAULT_PROVIDER
|
||||
|
||||
FACTS_PATH = Path("app/engine/prompts/company_facts.md")
|
||||
SYSTEM_PROMPT = DEFAULT_PROVIDER.system
|
||||
COMPANY_FACTS = DEFAULT_PROVIDER.company_facts
|
||||
EXTRACTOR_PROMPT = DEFAULT_PROVIDER.extractor
|
||||
EVALUATOR_PROMPT = DEFAULT_PROVIDER.evaluator
|
||||
|
||||
|
||||
class _CapturingProvider:
|
||||
@@ -28,14 +35,16 @@ def test_facts_concatenated_between_system_and_context():
|
||||
asyncio.run(svc.chat([{"role": "user", "content": "hi"}], context="⚠️ 提醒"))
|
||||
p = svc.provider.prompts[0]
|
||||
assert "HESUPIPE" in p and "HDPE" in p # 建材事实在场
|
||||
assert p.index(SYSTEM_PROMPT) < p.index(COMPANY_FACTS) < p.index("⚠️ 提醒")
|
||||
# Task 6: system 组装含 $DEFLECTION_POOL 话术池注入,SYSTEM_PROMPT 原文
|
||||
# 不再是组装结果的连续子串——改以首行/事实卡标题锚定顺序(语义等价)
|
||||
assert (p.index(SYSTEM_PROMPT.splitlines()[0])
|
||||
< p.index("# HESUPIPE 公司事实卡") < p.index("⚠️ 提醒"))
|
||||
|
||||
|
||||
def test_facts_absent_from_extractor_prompt():
|
||||
# extractor/evaluator 不拼事实卡(它们有自己的 prompt,不该看到公司事实)
|
||||
# Task 4 起 extractor/evaluator 含通用品类词(HDPE/PVC等字段示例)——
|
||||
# 隔离断言只针对品牌/公司事实标记(HESUPIPE),不再卡通用品类词
|
||||
from app.engine.services.ai_service import EVALUATOR_PROMPT, EXTRACTOR_PROMPT
|
||||
assert "HESUPIPE" not in EXTRACTOR_PROMPT
|
||||
assert "HESUPIPE" not in EVALUATOR_PROMPT
|
||||
# 河南和硕/和硕集团 等公司主体信息同样不得泄入
|
||||
|
||||
Reference in New Issue
Block a user