feat: add business auxiliary prompts

This commit is contained in:
2026-05-24 16:13:38 +08:00
parent 8c21e3aaa4
commit 53e5eb3bba
12 changed files with 317 additions and 13 deletions
+52 -2
View File
@@ -20,6 +20,13 @@ ROUTE_PERMISSION_ACTIONS = {
"stream": "chat:stream",
}
BUSINESS_AUXILIARY_PROMPT_KEYS = {
"obligation_extraction": "obligation_extraction_default",
"filing_materials_checklist": "filing_materials_checklist_default",
"negotiation_strategy": "negotiation_strategy_default",
"legal_opinion_boundary_fallback": "legal_opinion_boundary_fallback_default",
}
def get_chat_review_service(db: Session = Depends(get_db_session)) -> ReviewService:
return ReviewService(db)
@@ -60,14 +67,14 @@ def stream_chat(
legal_article_service,
)
review_context = _enrich_review_context_with_runtime_legal_sources(review_context, runtime_legal_sources)
prompt_runtime = _resolve_chat_prompt_runtime(current_user, review_context, prompt_runtime_service)
prompt_runtime = _resolve_chat_prompt_runtime(current_user, review_context, prompt_runtime_service, payload.message)
review_context = _enrich_review_context_with_prompt_runtime(review_context, prompt_runtime, prompt_runtime_service)
template_key = prompt_runtime.get("template_key") if prompt_runtime and prompt_runtime.get("available") else None
if prompt_runtime_service is not None:
prompt_runtime_service.record_run_link(
current_user,
prompt_runtime,
run_type="legal_chat",
run_type=str((prompt_runtime or {}).get("prompt_type") or "legal_chat"),
run_id=payload.conversation_id or "new_conversation",
resource_type="conversation",
resource_id=payload.conversation_id,
@@ -98,10 +105,21 @@ def _resolve_chat_prompt_runtime(
current_user: Dict[str, Any],
review_context: Optional[Dict[str, Any]],
prompt_runtime_service: Optional[PromptRuntimeService],
message: str = "",
) -> Dict[str, Any]:
if prompt_runtime_service is None:
return {"available": False, "prompt_type": "legal_chat", "prompt_version": "legal_chat.shared_ai_stream.v1", "source": "local_default"}
has_review_context = bool(review_context and ((review_context.get("reviewId") or review_context.get("review_id"))))
business_auxiliary_key = _detect_business_auxiliary_prompt_key(message, review_context)
if business_auxiliary_key:
return prompt_runtime_service.resolve_published_prompt(
current_user,
"business_auxiliary",
preferred_keys=[
business_auxiliary_key,
],
fallback_prompt_version="business_auxiliary.shared_ai_stream.v1",
)
return prompt_runtime_service.resolve_published_prompt(
current_user,
"legal_chat",
@@ -113,6 +131,38 @@ def _resolve_chat_prompt_runtime(
)
def _detect_business_auxiliary_prompt_key(
message: str,
review_context: Optional[Dict[str, Any]],
) -> Optional[str]:
text = _build_prompt_intent_text(message, review_context)
if _contains_any(text, ["法律意见书强边界", "法律意见书兜底", "法律意见书边界", "legal opinion boundary", "legal opinion fallback"]):
return BUSINESS_AUXILIARY_PROMPT_KEYS["legal_opinion_boundary_fallback"]
if _contains_any(text, ["履约义务", "履行义务", "义务提取", "履约清单", "obligation extraction", "performance obligation"]):
return BUSINESS_AUXILIARY_PROMPT_KEYS["obligation_extraction"]
if _contains_any(text, ["工商", "备案材料", "变更登记", "材料清单", "filing materials", "registration checklist", "filing checklist"]):
return BUSINESS_AUXILIARY_PROMPT_KEYS["filing_materials_checklist"]
if _contains_any(text, ["谈判策略", "谈判建议", "怎么谈", "议价", "让步方案", "negotiation strategy", "negotiate"]):
return BUSINESS_AUXILIARY_PROMPT_KEYS["negotiation_strategy"]
if _contains_any(text, ["法律意见书", "legal opinion"]) and _contains_any(
text,
["边界", "兜底", "免责声明", "不能替代", "人工复核", "boundary", "fallback", "disclaimer", "human review"],
):
return BUSINESS_AUXILIARY_PROMPT_KEYS["legal_opinion_boundary_fallback"]
return None
def _build_prompt_intent_text(message: str, review_context: Optional[Dict[str, Any]]) -> str:
parts = [message or ""]
if isinstance(review_context, dict):
parts.append(json.dumps(review_context, ensure_ascii=False, default=str))
return "\n".join(parts).lower()
def _contains_any(value: str, candidates: Iterable[str]) -> bool:
return any(candidate.lower() in value for candidate in candidates)
def _enrich_review_context_with_prompt_runtime(
review_context: Optional[Dict[str, Any]],
prompt_runtime: Optional[Dict[str, Any]],
+3 -1
View File
@@ -26,6 +26,7 @@ class PromptAssetService:
"legal_chat",
"wording_rewrite",
"regulation_impact",
"business_auxiliary",
}
EVALUATION_STATUSES = {"not_evaluated", "pending", "passed", "failed"}
PUBLISHABLE_EVALUATION_STATUSES = {"passed"}
@@ -36,6 +37,7 @@ class PromptAssetService:
"clause_recommendation": {"suite_key": "phase13_clause_generation", "sample_count": 6},
"wording_rewrite": {"suite_key": "phase15_wording_rewrite", "sample_count": 3},
"regulation_impact": {"suite_key": "future_regulation_impact", "sample_count": 0},
"business_auxiliary": {"suite_key": "future_business_auxiliary", "sample_count": 0},
}
def __init__(self, db: Session):
@@ -559,7 +561,7 @@ class PromptAssetService:
"detail": f"referenced={len(mentioned_variables)} declared={len(variable_names)}",
}
)
if asset.prompt_type in {"contract_review", "clause_recommendation", "wording_rewrite"}:
if asset.prompt_type in {"contract_review", "clause_recommendation", "wording_rewrite", "business_auxiliary"}:
checks.append(
{
"key": "risk_boundary_instruction",
@@ -47,6 +47,11 @@ class PromptGoldenSampleEvaluator:
"sample_family": "future_regulation_impact",
"min_samples": 0,
},
"business_auxiliary": {
"suite_key": "future_business_auxiliary",
"sample_family": "future_business_auxiliary",
"min_samples": 0,
},
}
def __init__(
@@ -199,6 +204,8 @@ class PromptGoldenSampleEvaluator:
return [self._kb_qa_sample(row) for row in self._read_phase13_csv("kb-qa-golden-sample-inventory.csv")]
if prompt_type == "wording_rewrite":
return self._wording_rewrite_samples()
if prompt_type == "business_auxiliary":
return []
return []
def _evaluate_sample_with_llm(
+47 -3
View File
@@ -5,6 +5,8 @@ from fastapi import HTTPException
from fastapi.testclient import TestClient
from app.api.chat import (
_detect_business_auxiliary_prompt_key,
_resolve_chat_prompt_runtime,
get_chat_legal_article_service,
get_chat_prompt_runtime_service,
get_chat_review_service,
@@ -121,17 +123,28 @@ class StubTenantService:
class StubPromptRuntimeService:
def __init__(self):
self.record_calls = []
self.resolve_calls = []
def resolve_published_prompt(self, current_user, prompt_type, *, preferred_keys=None, fallback_prompt_version=None):
preferred_keys = [key for key in (preferred_keys or []) if key]
self.resolve_calls.append(
{
"current_user": current_user,
"prompt_type": prompt_type,
"preferred_keys": preferred_keys,
"fallback_prompt_version": fallback_prompt_version,
}
)
selected_key = preferred_keys[0] if preferred_keys else "legal_chat_default"
return {
"available": True,
"prompt_asset_id": "prompt-001",
"prompt_asset_version_id": "promptver-001",
"prompt_key": "legal_chat_default",
"prompt_key": selected_key,
"prompt_type": prompt_type,
"version_label": "v1.0",
"prompt_version": "legal_chat_default.v1.0",
"template_key": "legal_chat_default",
"prompt_version": f"{selected_key}.v1.0",
"template_key": selected_key,
"source": "published_prompt_asset",
}
@@ -240,6 +253,37 @@ class ChatApiTestCase(unittest.TestCase):
self.assertEqual(review_context["promptRuntime"]["prompt_version"], "legal_chat_default.v1.0")
self.assertEqual(prompt_runtime_service.record_calls[0][2]["run_type"], "legal_chat")
def test_stream_chat_routes_business_auxiliary_intent_to_specialized_prompt(self):
app.dependency_overrides[require_current_user] = lambda: {"id": "user-1", "tenant_id": "tenant-1"}
prompt_runtime_service = StubPromptRuntimeService()
app.dependency_overrides[get_chat_prompt_runtime_service] = lambda: prompt_runtime_service
response = self.client.post("/api/v1/chat/stream", json={"message": "请提取这份合同的履约义务并列出证据"})
self.assertEqual(response.status_code, 200)
self.assertEqual(prompt_runtime_service.resolve_calls[0]["prompt_type"], "business_auxiliary")
self.assertEqual(prompt_runtime_service.resolve_calls[0]["preferred_keys"][0], "obligation_extraction_default")
self.assertEqual(self.chat_service.stream_calls[0][4], "obligation_extraction_default")
self.assertEqual(prompt_runtime_service.record_calls[0][2]["run_type"], "business_auxiliary")
self.assertEqual(_detect_business_auxiliary_prompt_key("请提取这份合同的履约义务并列出证据", None), "obligation_extraction_default")
self.assertEqual(_detect_business_auxiliary_prompt_key("请列出工商备案材料清单", None), "filing_materials_checklist_default")
self.assertEqual(_detect_business_auxiliary_prompt_key("请给我谈判策略", None), "negotiation_strategy_default")
self.assertEqual(_detect_business_auxiliary_prompt_key("法律意见书强边界兜底怎么写", None), "legal_opinion_boundary_fallback_default")
self.assertEqual(
_resolve_chat_prompt_runtime({"id": "user-1", "tenant_id": "tenant-1"}, None, prompt_runtime_service, "请给我谈判策略"),
{
"available": True,
"prompt_asset_id": "prompt-001",
"prompt_asset_version_id": "promptver-001",
"prompt_key": "negotiation_strategy_default",
"prompt_type": "business_auxiliary",
"version_label": "v1.0",
"prompt_version": "negotiation_strategy_default.v1.0",
"template_key": "negotiation_strategy_default",
"source": "published_prompt_asset",
},
)
def test_stream_chat_adds_review_legal_article_sources(self):
app.dependency_overrides[require_current_user] = lambda: {"id": "user-1", "tenant_id": "tenant-1"}
app.dependency_overrides[get_chat_review_service] = lambda: StubReviewService()
+27 -5
View File
@@ -235,6 +235,12 @@ class PromptAssetServiceTestCase(unittest.TestCase):
"software_saas_default",
"labor_service_default",
}
business_keys = {
"obligation_extraction_default",
"filing_materials_checklist_default",
"negotiation_strategy_default",
"legal_opinion_boundary_fallback_default",
}
review_keys = {
"contract_review_investment_finance",
"contract_review_corporate_governance",
@@ -245,11 +251,17 @@ class PromptAssetServiceTestCase(unittest.TestCase):
}
self.assertTrue(REQUIRED_PROMPT_KEYS.issubset(set(assets_by_key)))
self.assertIn("business_auxiliary", self.service.PROMPT_TYPES)
for prompt_key in generation_keys:
asset = assets_by_key[prompt_key]
self.assertEqual(asset["prompt_type"], "contract_generation")
self.assertIn("generate", asset["prompt_content"].lower())
self.assertEqual(asset["model_config"]["temperature"], 0.2)
for prompt_key in business_keys:
asset = assets_by_key[prompt_key]
self.assertEqual(asset["prompt_type"], "business_auxiliary")
self.assertIn("output", asset["prompt_content"].lower())
self.assertIn(asset["model_config"]["temperature"], {0.1, 0.2})
for prompt_key in review_keys:
asset = assets_by_key[prompt_key]
self.assertEqual(asset["prompt_type"], "contract_review")
@@ -305,12 +317,22 @@ class PromptAssetServiceTestCase(unittest.TestCase):
self.assertEqual(evaluation["evaluation_report"]["evaluation_mode"], "llm")
self.assertGreaterEqual(evaluation["evaluation_run"]["sample_count"], 3)
self.assertEqual(len(fake_llm_client.calls), evaluation["evaluation_run"]["sample_count"])
self.assertEqual(
evaluation["evaluation_report"]["model_invocation"]["sample_invocation_count"],
evaluation["evaluation_run"]["sample_count"],
def test_business_auxiliary_prompt_evaluation_uses_future_suite(self):
created = self._create_asset(
evaluation=False,
prompt_key="obligation_extraction_default",
prompt_type="business_auxiliary",
name="Obligation extraction",
prompt_content="Extract obligations, output JSON, risk boundary, legal law source article citation.",
)
self.assertTrue(all(item["evaluator_mode"] == "llm" for item in evaluation["evaluation_report"]["sample_results"]))
self.assertTrue(all(call["current_user"]["id"] == self.admin_user["id"] for call in fake_llm_client.calls))
evaluation = self.service.evaluate_current_prompt_asset(self.admin_user, created["id"])
self.assertEqual(evaluation["version"]["evaluation_status"], "passed")
self.assertEqual(evaluation["evaluation_report"]["suite_key"], "future_business_auxiliary")
self.assertEqual(evaluation["evaluation_report"]["sample_count"], 0)
self.assertEqual(evaluation["evaluation_report"]["evaluation_mode"], "local_fallback")
def test_publish_with_report_and_create_next_version(self):
created = self._create_asset(evaluation=False)
+1 -1
View File
@@ -57,7 +57,7 @@ class StubPromptAssetService:
"page": page,
"page_size": page_size,
"total": 1,
"prompt_types": ["contract_generation", "contract_review"],
"prompt_types": ["business_auxiliary", "contract_generation", "contract_review"],
}
def get_prompt_asset_detail(self, current_user, asset_id):
@@ -45,6 +45,7 @@ REQUIRED_PROMPT_TYPES = [
"clause_recommendation",
"wording_rewrite",
"regulation_impact",
"business_auxiliary",
]
REQUIRED_PROMPT_KEYS = [
@@ -80,6 +81,10 @@ REQUIRED_PROMPT_KEYS = [
"clause_recommendation_default",
"wording_rewrite_default",
"regulation_impact_default",
"obligation_extraction_default",
"filing_materials_checklist_default",
"negotiation_strategy_default",
"legal_opinion_boundary_fallback_default",
]
INVENTORY_FILES = {
+5
View File
@@ -17,6 +17,7 @@ REQUIRED_PROMPT_TYPES = {
"clause_recommendation",
"wording_rewrite",
"regulation_impact",
"business_auxiliary",
}
REQUIRED_PROMPT_KEYS = {
@@ -52,6 +53,10 @@ REQUIRED_PROMPT_KEYS = {
"clause_recommendation_default",
"wording_rewrite_default",
"regulation_impact_default",
"obligation_extraction_default",
"filing_materials_checklist_default",
"negotiation_strategy_default",
"legal_opinion_boundary_fallback_default",
}
+1
View File
@@ -64,6 +64,7 @@ const promptTypeOptions: Array<{ value: PromptAssetType; label: string }> = [
{ value: "legal_chat", label: "法规问答" },
{ value: "wording_rewrite", label: "措辞改写" },
{ value: "regulation_impact", label: "法规影响分析" },
{ value: "business_auxiliary", label: "业务辅助" },
];
const statusOptions = [
+2 -1
View File
@@ -520,7 +520,8 @@ export type PromptAssetType =
| "clause_recommendation"
| "legal_chat"
| "wording_rewrite"
| "regulation_impact";
| "regulation_impact"
| "business_auxiliary";
export type PromptAssetItem = {
id: string;
@@ -5215,3 +5215,22 @@
- `python -m json.tool project-docs\phase15-prompt-assets\default-prompt-assets.json | Out-Null`
- `python -m py_compile backend\app\services\contract_generation_service.py backend\tools\seed_prompt_assets.py backend\tools\asset_inventory_gap_report.py backend\tests\test_prompt_asset_service.py backend\tests\test_contracts_api.py`
- `$env:PYTHONPATH='backend'; python -m unittest backend.tests.test_prompt_asset_service backend.tests.test_prompt_runtime_service backend.tests.test_prompt_assets_api backend.tests.test_contracts_api -v`
## 2026-05-24 Phase15 业务辅助 Prompt 缺口闭环
- 本轮新增 `business_auxiliary` Prompt 类型,用于承载不直接属于起草、审查、条款推荐、措辞改写或法规影响分析的业务辅助任务。
- 补齐 4 个业务辅助 Prompt 资产:
- `obligation_extraction_default`:履约义务提取 Prompt
- `filing_materials_checklist_default`:工商/备案材料清单 Prompt
- `negotiation_strategy_default`:谈判策略 Prompt
- `legal_opinion_boundary_fallback_default`:法律意见书强边界兜底 Prompt
- `Chat` 运行入口已接入业务辅助意图识别:
- 命中履约义务、工商/备案材料、谈判策略、法律意见书强边界兜底等关键词时,优先解析 `business_auxiliary` 类型下的专项 Prompt。
- 未命中业务辅助意图时继续走原有 `legal_chat_default` 或 `legal_chat_review` 路径。
- `PromptAssetService`、`PromptGoldenSampleEvaluator`、默认种子脚本和缺口报告均已纳入 `business_auxiliary` 类型与上述 4 个必需 key。
- 前端 Prompt 资产管理类型枚举已新增 `business_auxiliary`,页面下拉可创建/筛选业务辅助 Prompt。
- 验证:
- `python -m json.tool project-docs\phase15-prompt-assets\default-prompt-assets.json | Out-Null`
- `python -m py_compile backend\app\api\chat.py backend\app\services\prompt_asset_service.py backend\app\services\prompt_golden_sample_evaluator.py backend\tools\seed_prompt_assets.py backend\tools\asset_inventory_gap_report.py backend\tests\test_prompt_asset_service.py backend\tests\test_chat_api.py backend\tests\test_prompt_assets_api.py`
- `$env:PYTHONPATH='backend'; python -m unittest backend.tests.test_prompt_asset_service backend.tests.test_prompt_assets_api backend.tests.test_chat_api backend.tests.test_prompt_runtime_service -v`
- `npm run lint`(frontend)
@@ -355,6 +355,154 @@
},
"change_summary": "Phase15 默认法律问答 Prompt 正式种入"
},
{
"prompt_key": "obligation_extraction_default",
"prompt_type": "business_auxiliary",
"name": "履约义务提取 Prompt",
"description": "用于从合同文本、审查结果或业务背景中提取双方履约义务、期限、触发条件和证据留存要求。",
"target_scene": "合同履约管理与义务清单提取",
"system_prompt": "你是 AI 合同履约辅助助手。你只能基于输入的合同文本、审查上下文和法条来源提取义务,不得新增合同没有约定的事实。对无法确认的事项必须列入 missing_fields 或 verification_items。",
"prompt_content": "请 extract obligations from contract_text={{contract_text}},review_context={{review_context}},party_position={{party_position}},legal_article_refs={{legal_article_refs}}。输出 return JSON,字段包括 obligations、timeline、evidence_requirements、risk_flags、missing_fields、verification_items、legal_basis、quality_notes。每项 obligations 必须包含 obligor、beneficiary、obligation_text、trigger_condition、deadline、performance_standard、evidence_to_keep、breach_consequence、source_clause、risk_boundary。必须标注 legal law source article citation,并说明不确定项。output return JSON risk boundary legal law source article citation",
"variables": [
{ "name": "contract_text", "required": true, "description": "待提取义务的合同或法律文书文本" },
{ "name": "review_context", "required": false, "description": "审查结果或业务上下文" },
{ "name": "party_position", "required": false, "description": "提取视角,例如甲方、乙方、平台方、投资方" },
{ "name": "legal_article_refs", "required": false, "description": "相关法条来源列表" }
],
"output_schema": {
"type": "object",
"required": ["obligations", "missing_fields", "legal_basis"],
"properties": {
"obligations": { "type": "array" },
"timeline": { "type": "array" },
"evidence_requirements": { "type": "array" },
"risk_flags": { "type": "array" },
"missing_fields": { "type": "array" },
"verification_items": { "type": "array" },
"legal_basis": { "type": "array" },
"quality_notes": { "type": "array" }
}
},
"model_config": {
"provider": "shared-ai-platform",
"model": "platform-default",
"temperature": 0.1
},
"change_summary": "补齐业务辅助履约义务提取 Prompt"
},
{
"prompt_key": "filing_materials_checklist_default",
"prompt_type": "business_auxiliary",
"name": "工商/备案材料清单 Prompt",
"description": "用于根据交易、公司治理或变更事项输出工商登记、备案、内部审批和材料准备清单。",
"target_scene": "工商登记备案材料清单生成",
"system_prompt": "你是 AI 工商备案材料辅助助手。你必须区分内部审批材料、工商登记材料、备案材料、签署文件和待人工核验事项。不得承诺登记机关一定受理或通过。",
"prompt_content": "请 generate filing materials checklist。matter_type={{matter_type}},document_type_code={{document_type_code}},contract_text={{contract_text}},company_context={{company_context}},legal_article_refs={{legal_article_refs}}。输出 return JSON,字段包括 matter_summary、preconditions、materials、signing_requirements、filing_authority、sequence、missing_fields、verification_items、risk_boundary、legal_basis。materials 每项必须包含 material_name、purpose、provider、signatory_or_seal、copy_or_original、required_or_optional、notes。必须标注 legal law source article citation,说明工商/备案口径可能因地区和登记机关要求变化。output return JSON risk boundary legal law source article citation",
"variables": [
{ "name": "matter_type", "required": false, "description": "事项类型,例如股权转让、增资、章程修订、法定代表人变更" },
{ "name": "document_type_code", "required": false, "description": "文书类型编码" },
{ "name": "contract_text", "required": false, "description": "合同或决议文本" },
{ "name": "company_context", "required": false, "description": "公司主体、股东、章程和登记背景" },
{ "name": "legal_article_refs", "required": false, "description": "相关法条来源列表" }
],
"output_schema": {
"type": "object",
"required": ["materials", "missing_fields", "legal_basis"],
"properties": {
"matter_summary": { "type": "string" },
"preconditions": { "type": "array" },
"materials": { "type": "array" },
"signing_requirements": { "type": "array" },
"filing_authority": { "type": "string" },
"sequence": { "type": "array" },
"missing_fields": { "type": "array" },
"verification_items": { "type": "array" },
"risk_boundary": { "type": "string" },
"legal_basis": { "type": "array" }
}
},
"model_config": {
"provider": "shared-ai-platform",
"model": "platform-default",
"temperature": 0.1
},
"change_summary": "补齐业务辅助工商备案材料清单 Prompt"
},
{
"prompt_key": "negotiation_strategy_default",
"prompt_type": "business_auxiliary",
"name": "谈判策略 Prompt",
"description": "用于根据合同文本、风险审查结果和我方立场输出可执行的谈判策略、底线、让步阶梯和备选条款。",
"target_scene": "合同谈判策略与条款改写建议",
"system_prompt": "你是 AI 合同谈判策略助手。你必须把商业目标、法律风险、证据条件和谈判筹码分开表达,不得建议违法、失衡或无法履行的条款。",
"prompt_content": "请 provide negotiation strategy。contract_text={{contract_text}},review_context={{review_context}},party_position={{party_position}},business_goal={{business_goal}},legal_article_refs={{legal_article_refs}}。输出 return JSON,字段包括 strategy_summary、must_hold_positions、negotiable_positions、concession_ladder、fallback_clauses、red_flags、talking_points、risk_boundaries、legal_basis、next_actions。必须说明 negotiate strategy risk boundary,给出可落地话术和备选条款,但不得删除法定义务或必要责任边界。必须标注 legal law source article citation。output return JSON risk boundary negotiate legal law source article citation",
"variables": [
{ "name": "contract_text", "required": false, "description": "合同文本或关键条款" },
{ "name": "review_context", "required": false, "description": "审查结果或风险项" },
{ "name": "party_position", "required": false, "description": "谈判立场,例如甲方、乙方、投资方、融资方" },
{ "name": "business_goal", "required": false, "description": "业务目标和谈判优先级" },
{ "name": "legal_article_refs", "required": false, "description": "相关法条来源列表" }
],
"output_schema": {
"type": "object",
"required": ["strategy_summary", "must_hold_positions", "risk_boundaries", "legal_basis"],
"properties": {
"strategy_summary": { "type": "string" },
"must_hold_positions": { "type": "array" },
"negotiable_positions": { "type": "array" },
"concession_ladder": { "type": "array" },
"fallback_clauses": { "type": "array" },
"red_flags": { "type": "array" },
"talking_points": { "type": "array" },
"risk_boundaries": { "type": "array" },
"legal_basis": { "type": "array" },
"next_actions": { "type": "array" }
}
},
"model_config": {
"provider": "shared-ai-platform",
"model": "platform-default",
"temperature": 0.2
},
"change_summary": "补齐业务辅助谈判策略 Prompt"
},
{
"prompt_key": "legal_opinion_boundary_fallback_default",
"prompt_type": "business_auxiliary",
"name": "法律意见书强边界兜底 Prompt",
"description": "用于法律意见书场景下材料不足、事实未核验或风险过高时输出强边界兜底说明和人工复核清单。",
"target_scene": "法律意见书边界兜底与人工复核",
"system_prompt": "你是 AI 法律意见书边界兜底助手。你不得替代律师出具最终法律意见,不得对未核验事实作确定性结论。必须优先输出边界、假设、无法判断事项和人工复核要求。",
"prompt_content": "请 generate legal opinion boundary fallback。matter_summary={{matter_summary}},facts={{facts}},materials={{materials}},draft_opinion={{draft_opinion}},legal_article_refs={{legal_article_refs}}。输出 return JSON,字段包括 boundary_notice、assumptions、cannot_conclude_items、missing_materials、human_review_required、safe_response、risk_boundary、legal_basis、next_actions。必须明确:AI 输出仅为辅助草稿,不构成正式法律意见;材料不足时只能给出条件性意见或拒绝确定性结论。必须标注 legal law source article citation。output return JSON risk boundary fallback legal law source article citation",
"variables": [
{ "name": "matter_summary", "required": false, "description": "事项概述" },
{ "name": "facts", "required": false, "description": "已知事实和待核验事实" },
{ "name": "materials", "required": false, "description": "用户提供的材料清单" },
{ "name": "draft_opinion", "required": false, "description": "已有法律意见书草稿或拟输出内容" },
{ "name": "legal_article_refs", "required": false, "description": "相关法条来源列表" }
],
"output_schema": {
"type": "object",
"required": ["boundary_notice", "cannot_conclude_items", "human_review_required", "legal_basis"],
"properties": {
"boundary_notice": { "type": "string" },
"assumptions": { "type": "array" },
"cannot_conclude_items": { "type": "array" },
"missing_materials": { "type": "array" },
"human_review_required": { "type": "array" },
"safe_response": { "type": "string" },
"risk_boundary": { "type": "string" },
"legal_basis": { "type": "array" },
"next_actions": { "type": "array" }
}
},
"model_config": {
"provider": "shared-ai-platform",
"model": "platform-default",
"temperature": 0.1
},
"change_summary": "补齐业务辅助法律意见书强边界兜底 Prompt"
},
{
"prompt_key": "clause_recommendation_default",
"prompt_type": "clause_recommendation",