diff --git a/backend/app/services/review_service.py b/backend/app/services/review_service.py index c56b9237..c61e8396 100644 --- a/backend/app/services/review_service.py +++ b/backend/app/services/review_service.py @@ -314,6 +314,44 @@ for _contract_type, _hints in _REAL_CHINESE_CONTRACT_HINTS.items(): if _hint not in existing: existing.append(_hint) +REVIEW_PROMPT_DOMAIN_KEY_BY_CONTRACT_TYPE = { + "investment": "contract_review_investment_finance", + "investment_agreement": "contract_review_investment_finance", + "equity_transfer": "contract_review_investment_finance", + "equity_transfer_agreement": "contract_review_investment_finance", + "intercompany_loan": "contract_review_investment_finance", + "intercompany_loan_agreement": "contract_review_investment_finance", + "valuation_adjustment": "contract_review_investment_finance", + "valuation_adjustment_agreement": "contract_review_investment_finance", + "shareholder_resolution": "contract_review_corporate_governance", + "power_of_attorney": "contract_review_corporate_governance", + "legal_opinion": "contract_review_corporate_governance", + "labor": "contract_review_employment_hr", + "employment": "contract_review_employment_hr", + "labor_contract": "contract_review_employment_hr", + "labor_service": "contract_review_employment_hr", + "labor_service_agreement": "contract_review_employment_hr", + "lease": "contract_review_real_estate_property", + "lease_house": "contract_review_real_estate_property", + "property_service": "contract_review_real_estate_property", + "property_service_agreement": "contract_review_real_estate_property", + "cooperation_framework": "contract_review_channel_franchise", + "agency_distribution": "contract_review_channel_franchise", + "agency_distribution_agreement": "contract_review_channel_franchise", + "franchise": "contract_review_channel_franchise", + "franchise_agreement": "contract_review_channel_franchise", + "cooperation": "contract_review_channel_franchise", + "framework": "contract_review_channel_franchise", + "sales": "contract_review_channel_franchise", + "technical_service": "contract_review_tech_saas_data_compliance", + "software_development": "contract_review_tech_saas_data_compliance", + "technology_development": "contract_review_tech_saas_data_compliance", + "software_saas": "contract_review_tech_saas_data_compliance", + "nda": "contract_review_tech_saas_data_compliance", + "nda_commercial": "contract_review_tech_saas_data_compliance", + "license": "contract_review_tech_saas_data_compliance", +} + _REAL_CHINESE_CLAUSE_KEYWORDS = { "payment": ["\u4ed8\u6b3e", "\u4ef7\u6b3e", "\u91d1\u989d", "\u53d1\u7968", "\u8d39\u7528", "\u5c3e\u6b3e", "\u8d28\u4fdd\u91d1", "\u9884\u4ed8\u6b3e"], "acceptance": ["\u9a8c\u6536", "\u9a8c\u6536\u6807\u51c6", "\u4e66\u9762\u9a8c\u6536", "\u6d4b\u8bd5", "\u8bd5\u8fd0\u884c"], @@ -2036,10 +2074,7 @@ class ReviewService: prompt_runtime = self.prompt_runtime_service.resolve_published_prompt( runtime_user, "contract_review", - preferred_keys=[ - f"contract_review_{review.contract_type}" if review.contract_type else None, - "contract_review_default", - ], + preferred_keys=self._build_review_prompt_preferred_keys(review.contract_type), fallback_prompt_version="legal-review.v1", ) setattr(review, "_prompt_runtime", prompt_runtime) @@ -2095,6 +2130,24 @@ class ReviewService: return self.repository.update(review) + def _build_review_prompt_preferred_keys(self, contract_type: Optional[str]) -> List[str]: + normalized_contract_type = self._normalize_review_prompt_contract_type(contract_type) + preferred_keys: List[str] = [] + domain_key = REVIEW_PROMPT_DOMAIN_KEY_BY_CONTRACT_TYPE.get(normalized_contract_type) + if domain_key: + preferred_keys.append(domain_key) + if normalized_contract_type: + specific_key = f"contract_review_{normalized_contract_type}" + if specific_key not in preferred_keys: + preferred_keys.append(specific_key) + if "contract_review_default" not in preferred_keys: + preferred_keys.append("contract_review_default") + return preferred_keys + + @staticmethod + def _normalize_review_prompt_contract_type(contract_type: Optional[str]) -> str: + return str(contract_type or "").strip().lower().replace("-", "_") + def _merge_prompt_runtime_into_confidence( self, confidence_summary: Optional[Dict[str, Any]], diff --git a/backend/tests/test_prompt_asset_service.py b/backend/tests/test_prompt_asset_service.py index e85661e6..2c2d7f96 100644 --- a/backend/tests/test_prompt_asset_service.py +++ b/backend/tests/test_prompt_asset_service.py @@ -11,6 +11,7 @@ from app.models.prompt_asset_run_link import PromptAssetRunLink from app.models.prompt_asset_version import PromptAssetVersion from app.services.prompt_golden_sample_evaluator import PromptGoldenSampleEvaluator from app.services.prompt_asset_service import PromptAssetService +from tools.seed_prompt_assets import REQUIRED_PROMPT_KEYS, load_catalog class StubPromptAssetRepository: @@ -208,6 +209,26 @@ class PromptAssetServiceTestCase(unittest.TestCase): self.assertEqual(detail["versions"][0]["version_label"], "v1.0") self.assertEqual(detail["versions"][0]["variables"][0]["name"], "party_a") + def test_default_prompt_catalog_includes_specialized_review_assets(self): + catalog_path = Path(__file__).resolve().parents[2] / "project-docs/phase15-prompt-assets/default-prompt-assets.json" + catalog = load_catalog(catalog_path) + assets_by_key = {item["prompt_key"]: item for item in catalog["assets"]} + review_keys = { + "contract_review_investment_finance", + "contract_review_corporate_governance", + "contract_review_employment_hr", + "contract_review_real_estate_property", + "contract_review_channel_franchise", + "contract_review_tech_saas_data_compliance", + } + + self.assertTrue(REQUIRED_PROMPT_KEYS.issubset(set(assets_by_key))) + for prompt_key in review_keys: + asset = assets_by_key[prompt_key] + self.assertEqual(asset["prompt_type"], "contract_review") + self.assertIn("review", asset["prompt_content"].lower()) + self.assertEqual(asset["model_config"]["temperature"], 0.1) + def test_publish_requires_evaluation_report(self): created = self._create_asset(evaluation=False) diff --git a/backend/tests/test_review_service.py b/backend/tests/test_review_service.py index 0f1be000..c10d2260 100644 --- a/backend/tests/test_review_service.py +++ b/backend/tests/test_review_service.py @@ -285,6 +285,22 @@ class ReviewServiceTestCase(unittest.TestCase): self.same_tenant_other_user = {"id": "user-2", "tenant_id": "tenant-demo-001", "role": "admin"} self.other_user = {"id": "user-3", "tenant_id": "tenant-other", "role": "admin"} + def test_review_prompt_preferred_keys_route_to_specialized_domains(self): + expectations = { + "investment_agreement": "contract_review_investment_finance", + "valuation_adjustment_agreement": "contract_review_investment_finance", + "shareholder_resolution": "contract_review_corporate_governance", + "labor_contract": "contract_review_employment_hr", + "property_service": "contract_review_real_estate_property", + "franchise_agreement": "contract_review_channel_franchise", + "software_development": "contract_review_tech_saas_data_compliance", + } + + for contract_type, expected_domain_key in expectations.items(): + preferred_keys = self.service._build_review_prompt_preferred_keys(contract_type) + self.assertEqual(preferred_keys[0], expected_domain_key) + self.assertIn("contract_review_default", preferred_keys) + def test_create_review_task_finalizes_and_generates_result(self): created = self.service.create_review_task( tenant_id=self.current_user["tenant_id"], diff --git a/backend/tools/asset_inventory_gap_report.py b/backend/tools/asset_inventory_gap_report.py index b9eea80b..02bd8d4c 100644 --- a/backend/tools/asset_inventory_gap_report.py +++ b/backend/tools/asset_inventory_gap_report.py @@ -47,6 +47,21 @@ REQUIRED_PROMPT_TYPES = [ "regulation_impact", ] +REQUIRED_PROMPT_KEYS = [ + "contract_generation_default", + "contract_review_default", + "contract_review_investment_finance", + "contract_review_corporate_governance", + "contract_review_employment_hr", + "contract_review_real_estate_property", + "contract_review_channel_franchise", + "contract_review_tech_saas_data_compliance", + "legal_chat_default", + "clause_recommendation_default", + "wording_rewrite_default", + "regulation_impact_default", +] + INVENTORY_FILES = { "legal_sources": "inventories/legal-source-inventory.csv", "knowledge_cards": "inventories/legal-knowledge-card-inventory.csv", @@ -250,7 +265,17 @@ def build_gap_summary( str(item.get("prompt_type")): int(item.get("count") or 0) for item in (remote_db.get("prompt_assets_by_type") or []) } + prompt_key_rows = remote_db.get("prompt_assets_by_key") + prompt_assets_by_key = { + str(item.get("prompt_key")): int(item.get("count") or 0) + for item in (prompt_key_rows or []) + } missing_prompt_types = [prompt_type for prompt_type in REQUIRED_PROMPT_TYPES if prompt_assets_by_type.get(prompt_type, 0) == 0] + missing_prompt_keys = ( + [prompt_key for prompt_key in REQUIRED_PROMPT_KEYS if prompt_assets_by_key.get(prompt_key, 0) == 0] + if prompt_key_rows is not None + else [] + ) prepared_rows = int(prepare_summary.get("rows") or 0) inserted = int(import_summary.get("inserted") or 0) @@ -261,9 +286,9 @@ def build_gap_summary( remote_legal_sources = int(remote_db.get("legal_sources") or 0) source_count_delta = max(source_document_count - remote_legal_sources, 0) - if missing_prompt_types: + if missing_prompt_types or missing_prompt_keys: priority_order = [ - "先补 Prompt 资产入库和发布,因为远程 prompt_assets=0 或必备类型不齐,运行链路还没有完整吃到 Prompt 治理资产。", + "先补 Prompt 资产入库和发布,因为远程 prompt_assets=0 或必备类型/Key 不齐,运行链路还没有完整吃到 Prompt 治理资产。", "再补 Phase13 模板、规则、标准条款正式吸收,因为远程模板只有少量,review_rules=0。", "然后做法律库增量抓取/复核,不重复导入已完成的 690125 条。", "最后做全量法规向量化批处理,按法律、行政法规、司法解释、地方法规分批跑。", @@ -305,10 +330,12 @@ def build_gap_summary( }, "prompts": { "required_prompt_types": REQUIRED_PROMPT_TYPES, + "required_prompt_keys": REQUIRED_PROMPT_KEYS, "remote_prompt_assets": int(remote_db.get("prompt_assets") or 0), "remote_prompt_versions": int(remote_db.get("prompt_asset_versions") or remote_db.get("prompt_versions") or 0), "remote_prompt_eval_runs": int(remote_db.get("prompt_asset_evaluation_runs") or remote_db.get("prompt_eval_runs") or 0), "missing_required_prompt_types": missing_prompt_types, + "missing_required_prompt_keys": missing_prompt_keys, "golden_suites": local_assets["prompt_suite"]["suites"], }, "rules_and_clauses": { @@ -369,13 +396,13 @@ def write_markdown_report(path: Path, summary: dict[str, Any]) -> None: status = "远程已存在" if item["template_code"] in remote_template_codes else "远程缺失" template_rows.append([item["template_code"], item["name"], status]) - if prompts["missing_required_prompt_types"]: + if prompts["missing_required_prompt_types"] or prompts.get("missing_required_prompt_keys"): prompt_conclusion = ( f"- 远程 Prompt 资产为 {prompts['remote_prompt_assets']},Prompt 版本为 {prompts['remote_prompt_versions']}," "这说明 Prompt 治理页面/表已经有了,但生产运行库还没有种入完整正式 Prompt。" ) next_suggestion = ( - "先做“Prompt 资产正式种入 + 发布 + 黄金样本评测”闭环。原因是法律库主体已入库,而远程 Prompt 必备类型仍有缺口," + "先做“Prompt 资产正式种入 + 发布 + 黄金样本评测”闭环。原因是法律库主体已入库,而远程 Prompt 必备类型或 Key 仍有缺口," "这会直接影响生成、审查、Chat、条款推荐、措辞优化和法规影响扫描的运行质量。" ) else: @@ -439,6 +466,10 @@ def write_markdown_report(path: Path, summary: dict[str, Any]) -> None: "", ", ".join(prompts["missing_required_prompt_types"]) or "无", "", + "缺失的专项 Prompt Key:", + "", + ", ".join(prompts["missing_required_prompt_keys"]) or "无", + "", "## 五、规则与标准条款缺口", "", markdown_table( diff --git a/backend/tools/seed_prompt_assets.py b/backend/tools/seed_prompt_assets.py index 9ba4f029..4f8136ca 100644 --- a/backend/tools/seed_prompt_assets.py +++ b/backend/tools/seed_prompt_assets.py @@ -19,6 +19,21 @@ REQUIRED_PROMPT_TYPES = { "regulation_impact", } +REQUIRED_PROMPT_KEYS = { + "contract_generation_default", + "contract_review_default", + "contract_review_investment_finance", + "contract_review_corporate_governance", + "contract_review_employment_hr", + "contract_review_real_estate_property", + "contract_review_channel_franchise", + "contract_review_tech_saas_data_compliance", + "legal_chat_default", + "clause_recommendation_default", + "wording_rewrite_default", + "regulation_impact_default", +} + @dataclass class SeedCounters: @@ -67,6 +82,10 @@ def load_catalog(path: Path) -> dict[str, Any]: missing = sorted(REQUIRED_PROMPT_TYPES - prompt_types) if missing: raise ValueError(f"Prompt asset catalog is missing required prompt types: {', '.join(missing)}") + prompt_keys = {normalize_prompt_key(str(item.get("prompt_key") or "")) for item in assets if isinstance(item, dict)} + missing_keys = sorted(REQUIRED_PROMPT_KEYS - prompt_keys) + if missing_keys: + raise ValueError(f"Prompt asset catalog is missing required prompt keys: {', '.join(missing_keys)}") return payload diff --git a/project-docs/AI合同起草与审查助手-当前工作进度保存-2026-05-11.md b/project-docs/AI合同起草与审查助手-当前工作进度保存-2026-05-11.md index 249c6fae..aa90cc38 100644 --- a/project-docs/AI合同起草与审查助手-当前工作进度保存-2026-05-11.md +++ b/project-docs/AI合同起草与审查助手-当前工作进度保存-2026-05-11.md @@ -5165,3 +5165,17 @@ - 当前闭环结论: - Phase14 六个法条来源已全部清零。 - 下一步可以转入总结、复核或其他收尾任务。 + +## 2026-05-24 Phase15 专项审查 Prompt 继续收口 + +- 本轮补齐 6 个专项审查 Prompt 资产: + - 投融资审查 Prompt + - 公司治理审查 Prompt + - 劳动人事审查 Prompt + - 不动产/物业审查 Prompt + - 渠道/加盟审查 Prompt + - 技术/SaaS/数据合规审查 Prompt +- 默认 Prompt catalog 已新增对应 `contract_review` 专项资产,并保留原有 `contract_review_default`。 +- `ReviewService` 已接入专项 key 路由,会优先命中对应领域 Prompt,再回退到默认审查 Prompt。 +- `seed_prompt_assets.py` 和 `asset_inventory_gap_report.py` 已改为校验专项 Prompt key,避免后续只看类型不看具体资产。 +- 新增回归测试覆盖默认 Prompt catalog 与专项审查路由。 diff --git a/project-docs/phase15-prompt-assets/default-prompt-assets.json b/project-docs/phase15-prompt-assets/default-prompt-assets.json index d076c738..389e18b5 100644 --- a/project-docs/phase15-prompt-assets/default-prompt-assets.json +++ b/project-docs/phase15-prompt-assets/default-prompt-assets.json @@ -189,6 +189,198 @@ "temperature": 0.1 }, "change_summary": "Phase15 默认法规影响扫描 Prompt 正式种入" + }, + { + "prompt_key": "contract_review_investment_finance", + "prompt_type": "contract_review", + "name": "投融资专项审查 Prompt", + "description": "用于投资协议、股权转让、企业间借款、对赌协议等投融资交易的专项风险审查。", + "target_scene": "投融资合同审查", + "system_prompt": "你是投融资交易合同审查助手。你必须围绕投资结构、估值、交割、先决条件、公司治理权利、股权转让限制、回购/补偿、关联交易、担保、资金合规和退出安排进行审慎审查。不得输出无法追溯的法律结论;所有风险结论必须说明触发条款、影响范围、谈判边界和可引用法律依据。", + "prompt_content": "请 review 以下投融资类合同文本并识别 risk、issue、finding。contract_type={{contract_type}},party_position={{party_position}},contract_text={{contract_text}},legal_article_refs={{legal_article_refs}}。重点审查估值与交易价格、交割与先决条件、陈述保证、投资人保护权、清算优先、回购/赎回/对赌补偿、股权限制、关联交易、担保和资金合规。输出 JSON,字段包括 basic_info、clauses、risk_items、risk_summary、review_opinion、recommendation、rendered_report。每个 risk_items 必须包含 severity、clause_title、issue、legal_basis、suggestion、risk_boundary、negotiation_note、legal_article_refs。review risk issue finding legal law basis source article citation output return。", + "variables": [ + { "name": "contract_type", "required": false, "description": "合同或文书类型" }, + { "name": "party_position", "required": false, "description": "审查立场,如投资方、融资方、转让方、受让方" }, + { "name": "contract_text", "required": true, "description": "待审查合同正文" }, + { "name": "legal_article_refs", "required": false, "description": "相关法条引用列表" } + ], + "output_schema": { + "type": "object", + "required": ["risk_items", "risk_summary", "review_opinion", "recommendation"], + "properties": { + "risk_items": { "type": "array" }, + "risk_summary": { "type": "object" }, + "review_opinion": { "type": "string" }, + "recommendation": { "type": "string" }, + "rendered_report": { "type": "string" } + } + }, + "model_config": { + "provider": "shared-ai-platform", + "model": "platform-default", + "temperature": 0.1 + }, + "change_summary": "补充投融资专项审查 Prompt" + }, + { + "prompt_key": "contract_review_corporate_governance", + "prompt_type": "contract_review", + "name": "公司治理专项审查 Prompt", + "description": "用于股东会决议、授权委托、公司治理安排、法律意见书相关材料的专项审查。", + "target_scene": "公司治理文书审查", + "system_prompt": "你是公司治理法律文书审查助手。你必须围绕主体资格、召集程序、表决程序、授权范围、签章权限、公司章程约束、工商登记/备案材料、董事监事高管责任和决议效力进行审查。不得替代律师作最终法律意见;对事实材料不足的事项必须列为待核验清单。", + "prompt_content": "请 review 以下公司治理类文书并识别 risk、issue、finding。contract_type={{contract_type}},party_position={{party_position}},contract_text={{contract_text}},legal_article_refs={{legal_article_refs}}。重点审查主体资格、会议通知和召集程序、表决比例、章程/协议冲突、授权权限、签章真实性、登记备案材料、决议效力、法律意见边界和人工复核项。输出 JSON,字段包括 basic_info、clauses、risk_items、risk_summary、review_opinion、recommendation、rendered_report。每个 risk_items 必须包含 severity、clause_title、issue、legal_basis、suggestion、risk_boundary、negotiation_note、legal_article_refs。review risk issue finding legal law basis source article citation output return。", + "variables": [ + { "name": "contract_type", "required": false, "description": "合同或文书类型" }, + { "name": "party_position", "required": false, "description": "审查立场,如公司、股东、受托人、外部审查人" }, + { "name": "contract_text", "required": true, "description": "待审查文书正文" }, + { "name": "legal_article_refs", "required": false, "description": "相关法条引用列表" } + ], + "output_schema": { + "type": "object", + "required": ["risk_items", "risk_summary", "review_opinion", "recommendation"], + "properties": { + "risk_items": { "type": "array" }, + "risk_summary": { "type": "object" }, + "review_opinion": { "type": "string" }, + "recommendation": { "type": "string" }, + "rendered_report": { "type": "string" } + } + }, + "model_config": { + "provider": "shared-ai-platform", + "model": "platform-default", + "temperature": 0.1 + }, + "change_summary": "补充公司治理专项审查 Prompt" + }, + { + "prompt_key": "contract_review_employment_hr", + "prompt_type": "contract_review", + "name": "劳动人事专项审查 Prompt", + "description": "用于劳动合同、劳务协议、竞业限制、保密、人事管理相关协议的专项审查。", + "target_scene": "劳动人事合同审查", + "system_prompt": "你是劳动人事合同审查助手。你必须围绕劳动关系认定、岗位职责、工作地点、工时休假、工资奖金、社保公积金、试用期、培训服务期、竞业限制、保密、解除终止和经济补偿进行审查。必须提示劳动强制性规范边界和用工合规风险。", + "prompt_content": "请 review 以下劳动人事类合同文本并识别 risk、issue、finding。contract_type={{contract_type}},party_position={{party_position}},contract_text={{contract_text}},legal_article_refs={{legal_article_refs}}。重点审查劳动关系/劳务关系边界、试用期、薪酬结构、社保公积金、工时休假、绩效奖金、保密竞业、培训服务期、解除终止、经济补偿、规章制度适用和证据留存。输出 JSON,字段包括 basic_info、clauses、risk_items、risk_summary、review_opinion、recommendation、rendered_report。每个 risk_items 必须包含 severity、clause_title、issue、legal_basis、suggestion、risk_boundary、negotiation_note、legal_article_refs。review risk issue finding legal law basis source article citation output return。", + "variables": [ + { "name": "contract_type", "required": false, "description": "合同或文书类型" }, + { "name": "party_position", "required": false, "description": "审查立场,如用人单位、劳动者、劳务提供方" }, + { "name": "contract_text", "required": true, "description": "待审查合同正文" }, + { "name": "legal_article_refs", "required": false, "description": "相关法条引用列表" } + ], + "output_schema": { + "type": "object", + "required": ["risk_items", "risk_summary", "review_opinion", "recommendation"], + "properties": { + "risk_items": { "type": "array" }, + "risk_summary": { "type": "object" }, + "review_opinion": { "type": "string" }, + "recommendation": { "type": "string" }, + "rendered_report": { "type": "string" } + } + }, + "model_config": { + "provider": "shared-ai-platform", + "model": "platform-default", + "temperature": 0.1 + }, + "change_summary": "补充劳动人事专项审查 Prompt" + }, + { + "prompt_key": "contract_review_real_estate_property", + "prompt_type": "contract_review", + "name": "不动产/物业专项审查 Prompt", + "description": "用于房屋租赁、物业服务、园区服务、不动产配套协议的专项审查。", + "target_scene": "不动产与物业合同审查", + "system_prompt": "你是不动产与物业服务合同审查助手。你必须围绕房屋权属、租赁期限、交付状态、租金押金、物业费、维修资金、公共收益、安全责任、业委会/业主大会授权、解除退场和证据交接进行审查。必须提示权属和公共管理事项的人工核验边界。", + "prompt_content": "请 review 以下不动产/物业类合同文本并识别 risk、issue、finding。contract_type={{contract_type}},party_position={{party_position}},contract_text={{contract_text}},legal_article_refs={{legal_article_refs}}。重点审查权属/授权、租赁或服务范围、交付与验收、费用计费、押金和保证金、维修责任、专项维修资金、公共收益、安全保障、业主委员会授权、提前解除、退场交接和证据留存。输出 JSON,字段包括 basic_info、clauses、risk_items、risk_summary、review_opinion、recommendation、rendered_report。每个 risk_items 必须包含 severity、clause_title、issue、legal_basis、suggestion、risk_boundary、negotiation_note、legal_article_refs。review risk issue finding legal law basis source article citation output return。", + "variables": [ + { "name": "contract_type", "required": false, "description": "合同或文书类型" }, + { "name": "party_position", "required": false, "description": "审查立场,如出租方、承租方、物业公司、业主方" }, + { "name": "contract_text", "required": true, "description": "待审查合同正文" }, + { "name": "legal_article_refs", "required": false, "description": "相关法条引用列表" } + ], + "output_schema": { + "type": "object", + "required": ["risk_items", "risk_summary", "review_opinion", "recommendation"], + "properties": { + "risk_items": { "type": "array" }, + "risk_summary": { "type": "object" }, + "review_opinion": { "type": "string" }, + "recommendation": { "type": "string" }, + "rendered_report": { "type": "string" } + } + }, + "model_config": { + "provider": "shared-ai-platform", + "model": "platform-default", + "temperature": 0.1 + }, + "change_summary": "补充不动产/物业专项审查 Prompt" + }, + { + "prompt_key": "contract_review_channel_franchise", + "prompt_type": "contract_review", + "name": "渠道/加盟专项审查 Prompt", + "description": "用于代理、经销、渠道合作、加盟、特许经营和商业合作框架协议的专项审查。", + "target_scene": "渠道加盟合同审查", + "system_prompt": "你是渠道、经销、加盟和特许经营合同审查助手。你必须围绕授权范围、区域保护、价格政策、返利结算、库存和窜货、品牌使用、商业特许经营备案、培训支持、信息披露、保证金、解除退出和消费者/第三方责任进行审查。", + "prompt_content": "请 review 以下渠道/加盟类合同文本并识别 risk、issue、finding。contract_type={{contract_type}},party_position={{party_position}},contract_text={{contract_text}},legal_article_refs={{legal_article_refs}}。重点审查授权区域、独家/非独家限制、价格和返利、最低采购、库存与窜货、品牌和知识产权使用、加盟资质、信息披露、备案义务、培训支持、保证金、违约解除、售后和消费者责任。输出 JSON,字段包括 basic_info、clauses、risk_items、risk_summary、review_opinion、recommendation、rendered_report。每个 risk_items 必须包含 severity、clause_title、issue、legal_basis、suggestion、risk_boundary、negotiation_note、legal_article_refs。review risk issue finding legal law basis source article citation output return。", + "variables": [ + { "name": "contract_type", "required": false, "description": "合同或文书类型" }, + { "name": "party_position", "required": false, "description": "审查立场,如品牌方、加盟商、代理商、经销商" }, + { "name": "contract_text", "required": true, "description": "待审查合同正文" }, + { "name": "legal_article_refs", "required": false, "description": "相关法条引用列表" } + ], + "output_schema": { + "type": "object", + "required": ["risk_items", "risk_summary", "review_opinion", "recommendation"], + "properties": { + "risk_items": { "type": "array" }, + "risk_summary": { "type": "object" }, + "review_opinion": { "type": "string" }, + "recommendation": { "type": "string" }, + "rendered_report": { "type": "string" } + } + }, + "model_config": { + "provider": "shared-ai-platform", + "model": "platform-default", + "temperature": 0.1 + }, + "change_summary": "补充渠道/加盟专项审查 Prompt" + }, + { + "prompt_key": "contract_review_tech_saas_data_compliance", + "prompt_type": "contract_review", + "name": "技术/SaaS/数据合规专项审查 Prompt", + "description": "用于技术服务、软件开发、SaaS、数据处理、个人信息保护和网络安全相关合同的专项审查。", + "target_scene": "技术 SaaS 与数据合规合同审查", + "system_prompt": "你是技术、SaaS 和数据合规合同审查助手。你必须围绕交付验收、服务等级、源代码/成果归属、知识产权许可、开源软件、数据处理角色、个人信息处理、重要数据、跨境传输、网络安全、等保、审计权、服务中断和责任上限进行审查。", + "prompt_content": "请 review 以下技术/SaaS/数据合规类合同文本并识别 risk、issue、finding。contract_type={{contract_type}},party_position={{party_position}},contract_text={{contract_text}},legal_article_refs={{legal_article_refs}}。重点审查交付物、验收标准、SLA、可用性、数据处理角色、个人信息授权同意、委托处理、重要数据、跨境传输、网络安全和等保、日志与审计、开源软件、知识产权归属/许可、责任限制、服务中断和退出迁移。输出 JSON,字段包括 basic_info、clauses、risk_items、risk_summary、review_opinion、recommendation、rendered_report。每个 risk_items 必须包含 severity、clause_title、issue、legal_basis、suggestion、risk_boundary、negotiation_note、legal_article_refs。review risk issue finding legal law basis source article citation output return。", + "variables": [ + { "name": "contract_type", "required": false, "description": "合同或文书类型" }, + { "name": "party_position", "required": false, "description": "审查立场,如甲方、乙方、服务商、客户、数据处理者" }, + { "name": "contract_text", "required": true, "description": "待审查合同正文" }, + { "name": "legal_article_refs", "required": false, "description": "相关法条引用列表" } + ], + "output_schema": { + "type": "object", + "required": ["risk_items", "risk_summary", "review_opinion", "recommendation"], + "properties": { + "risk_items": { "type": "array" }, + "risk_summary": { "type": "object" }, + "review_opinion": { "type": "string" }, + "recommendation": { "type": "string" }, + "rendered_report": { "type": "string" } + } + }, + "model_config": { + "provider": "shared-ai-platform", + "model": "platform-default", + "temperature": 0.1 + }, + "change_summary": "补充技术/SaaS/数据合规专项审查 Prompt" } ] } diff --git a/scripts/run-asset-inventory-gap-report.ps1 b/scripts/run-asset-inventory-gap-report.ps1 index 15c10626..8371632e 100644 --- a/scripts/run-asset-inventory-gap-report.ps1 +++ b/scripts/run-asset-inventory-gap-report.ps1 @@ -290,6 +290,14 @@ with engine.connect() as conn: else: snapshot["prompt_assets_by_type"] = [] + if has_column("prompt_assets", "prompt_key"): + snapshot["prompt_assets_by_key"] = rows( + conn, + "select prompt_key, count(*) as count from prompt_assets group by prompt_key order by prompt_key", + ) + else: + snapshot["prompt_assets_by_key"] = [] + if has_column("review_rules", "status"): snapshot["review_rules_by_status"] = rows( conn,