pipeline-bidding/pipeline_bidding/role_tool_schemas.py
yumoqing 44f8c18ac3 feat(bidding): 产线起点改为上传招标文件+解析产出QC契合度审核门禁
清理(前三步归商机产线):
- 删邮箱采集: bid_mail.py/bid_mail_accounts表与页面/首页按钮
- 删招标审批状态机: TD_*/HT_TENDER_APPROVAL/摘要审批工具族
- bid_tenders瘦身为解析抽取的商务要素(去邮件字段)

QC契合度审核:
- 新表bid_qc_reviews(qc_type/round/fit_score/pass_score/passed/improvement)
- bid_qc_capability: start_qc/finish_qc/list_qc/qc_report, 四类产出逐类审核
- 判定: 10分制打分, >9.5放行(参数bid_qc_pass_score); 不通过给改进意见
  +清空产出+对账器重派解析任务带意见重做; 超轮次抛qc_escalation人工
- bid_flow对账器A2门禁阶段: 幂等/在办去重/轮次守卫/重做不计首跑上限
- 驾驶舱: qc_report工具+解析QC审核菜单; 参数读appbase表+默认兜底
2026-08-31 13:37:49 +08:00

295 lines
15 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""投标产线角色工具 schema —— 注册进引擎 capability_tools.TOOL_SCHEMAS。
分工:
- 引擎 pipeline_service.capability_tools 只保留产线无关的分发机制(module 支持裸名/全路径);
- 投标产线的工具 schema(工具名→实现模块→参数)定义在这里,模块加载时注册进引擎字典。
这样宿主不装投标产线时,引擎字典里不会出现任何投标字符串。
注册时机:init.py 的 load_pipeline_bidding() 调用 register_role_tools()(import 即注册)。
"""
import logging
logger = logging.getLogger("pipeline.bidding.tools")
_M = "pipeline_bidding"
BID_ROLE_TOOL_SCHEMAS = {
# ── bid_tender_capability:立项/人员(产线从上传招标文件开始,无邮件采集/审批)──
"assign_members": {
"module": f"{_M}.bid_tender_capability",
"description": "设定投标项目参与人员,如「张三:负责人,李四:writer」",
"params": {"project_id": "项目ID(可选,默认当前)",
"members": "人员清单(姓名:角色 逗号分隔,或JSON数组)"},
"required": ["members"],
},
"list_members": {
"module": f"{_M}.bid_tender_capability",
"description": "查看投标项目参与人员",
"params": {"project_id": "项目ID(可选,默认当前)"},
"required": [],
},
# ── bid_analysis_capability:招标文件分析师 ──
"read_tender_file": {
"module": f"{_M}.bid_analysis_capability",
"description": "分段读取招标文件正文(供分析)",
"params": {"file_id": "招标文件ID", "offset": "起始字符(可选)", "length": "长度(可选)"},
"required": ["file_id"],
},
"list_tender_files": {
"module": f"{_M}.bid_analysis_capability",
"description": "列出项目招标文件及抽取状态",
"params": {"project_id": "项目ID(可选,默认当前)", "extract_status": "抽取状态(可选)"},
"required": [],
},
"extract_from_file": {
"module": f"{_M}.bid_analysis_capability",
"description": "LLM 一次性抽取评分项+得分规则/所需资质/投标文件要求并批量落库(大文件分段调)",
"params": {"project_id": "项目ID(可选,默认当前)", "file_id": "招标文件ID(可选)",
"offset": "分段起始字符(可选)", "length": "分段长度(可选)"},
"required": [],
},
"add_scoring_item": {
"module": f"{_M}.bid_analysis_capability",
"description": "录入评分项及得分规则(抽取漏项时人工补录)",
"params": {"project_id": "项目ID(可选,默认当前)", "item_name": "评分项名称", "max_score": "满分",
"scoring_rule": "得分规则原文", "section": "business|technical|price(可选)",
"is_veto": "是否否决项 0/1(可选)", "target_chapter_no": "对应章节号(可选)"},
"required": ["item_name", "max_score"],
},
"add_qualification": {
"module": f"{_M}.bid_analysis_capability",
"description": "录入招标所需资质",
"params": {"project_id": "项目ID(可选,默认当前)", "qual_name": "资质名称",
"requirement": "要求原文(可选)", "is_mandatory": "是否必需 0/1(可选)"},
"required": ["qual_name"],
},
"add_doc_requirement": {
"module": f"{_M}.bid_analysis_capability",
"description": "录入投标文件要求(structure 类即章节骨架来源)",
"params": {"project_id": "项目ID(可选,默认当前)", "requirement": "要求内容",
"req_type": "structure|format|seal|copies|deadline|other(可选)",
"chapter_no": "章节号(可选)", "chapter_title": "章节标题(可选)",
"page_limit": "页数限制(可选)"},
"required": ["requirement"],
},
"create_chapter_outline": {
"module": f"{_M}.bid_analysis_capability",
"description": "生成章节骨架(默认用 structure 类要求自动生成,并挂评分项)",
"params": {"project_id": "项目ID(可选,默认当前)", "chapters": "章节JSON数组(可选,默认自动生成)"},
"required": [],
},
"list_scoring_items": {
"module": f"{_M}.bid_analysis_capability",
"description": "列出评分项与得分规则",
"params": {"project_id": "项目ID(可选,默认当前)", "section": "评分部分(可选)"},
"required": [],
},
"list_doc_requirements": {
"module": f"{_M}.bid_analysis_capability",
"description": "列出投标文件要求",
"params": {"project_id": "项目ID(可选,默认当前)", "req_type": "类型(可选)"},
"required": [],
},
"mark_file_extracted": {
"module": f"{_M}.bid_analysis_capability",
"description": "标记招标文件抽取完成",
"params": {"file_id": "招标文件ID", "note": "说明(可选)"},
"required": ["file_id"],
},
# ── bid_kb_capability:投标资料专员 ──
"search_bid_kb": {
"module": f"{_M}.bid_kb_capability",
"description": "检索公司投标知识库(资质证书/业绩案例/模板/财务/人员)",
"params": {"query": "关键词", "doc_type": "类型(可选)", "org_id": "机构(可选)"},
"required": [],
},
"kb_doc_detail": {
"module": f"{_M}.bid_kb_capability",
"description": "取知识库文档正文",
"params": {"kb_doc_id": "知识库文档ID"},
"required": ["kb_doc_id"],
},
"list_qualifications": {
"module": f"{_M}.bid_kb_capability",
"description": "列出招标所需资质及匹配状态",
"params": {"project_id": "项目ID(可选,默认当前)", "match_status": "匹配状态(可选)"},
"required": [],
},
"match_qualification": {
"module": f"{_M}.bid_kb_capability",
"description": "把知识库文档挂到资质项上(pending→matched)",
"params": {"qual_id": "资质项ID", "kb_doc_id": "知识库文档ID", "note": "说明(可选)"},
"required": ["qual_id", "kb_doc_id"],
},
"mark_qualification_missing": {
"module": f"{_M}.bid_kb_capability",
"description": "知识库无此资质:标记 missing 或 human_required",
"params": {"qual_id": "资质项ID", "note": "说明(可选)", "need_human": "需人工提供 0/1(默认1)"},
"required": ["qual_id"],
},
"auto_match_qualifications": {
"module": f"{_M}.bid_kb_capability",
"description": "批量自动匹配全部 pending 资质项(命中知识库即 matched,否则 human_required)",
"params": {"project_id": "项目ID(可选,默认当前)"},
"required": [],
},
"request_human_docs": {
"module": f"{_M}.bid_kb_capability",
"description": "发布「人类应提供的文件」清单任务(阻塞门禁;默认自动汇总缺失资质)",
"params": {"project_id": "项目ID(可选,默认当前)", "items": "清单(可选)", "note": "说明(可选)"},
"required": [],
},
# ── bid_write_capability:标书撰写工程师 ──
"list_chapters": {
"module": f"{_M}.bid_write_capability",
"description": "列出章节及状态",
"params": {"project_id": "项目ID(可选,默认当前)", "status": "状态(可选)"},
"required": [],
},
"chapter_detail": {
"module": f"{_M}.bid_write_capability",
"description": "章节详情:要点/对应评分项及得分规则/上轮改进意见/当前正文",
"params": {"chapter_id": "章节ID"},
"required": ["chapter_id"],
},
"write_chapter": {
"module": f"{_M}.bid_write_capability",
"description": "写入章节正文(写到操作层面,禁止空话;有最小长度门槛)",
"params": {"chapter_id": "章节ID", "content": "章节正文", "summary": "本次写作要点(可选)"},
"required": ["chapter_id", "content"],
},
"submit_chapter": {
"module": f"{_M}.bid_write_capability",
"description": "提交章节评审(written 后系统自动派评审任务)",
"params": {"chapter_id": "章节ID", "note": "说明(可选)"},
"required": ["chapter_id"],
},
# ── bid_review_capability:标书评审员 ──
"review_chapter": {
"module": f"{_M}.bid_review_capability",
"description": "章节评审打分:对照评分项得分规则+招标文件/投标文件要求;不达标必须给改进意见",
"params": {"chapter_id": "章节ID", "score": "得分(数字)", "max_score": "满分(可选,默认取章节挂载满分)",
"comments": "评审意见/改进意见(不通过必填)", "detail": "评审明细(可选)"},
"required": ["chapter_id", "score"],
},
"approve_chapter": {
"module": f"{_M}.bid_review_capability",
"description": "直接通过章节(特殊情况)",
"params": {"chapter_id": "章节ID", "comment": "意见(可选)"},
"required": ["chapter_id"],
},
"reject_chapter": {
"module": f"{_M}.bid_review_capability",
"description": "退回章节重写(必须给改进意见)",
"params": {"chapter_id": "章节ID", "comment": "改进意见"},
"required": ["chapter_id", "comment"],
},
"list_reviews": {
"module": f"{_M}.bid_review_capability",
"description": "查评审记录",
"params": {"project_id": "项目ID(可选,默认当前)", "scope": "chapter|whole(可选)",
"chapter_id": "章节ID(可选)"},
"required": [],
},
# ── bid_qc_capability:解析产出 QC 契合度审核(agent.qc)──
"start_qc": {
"module": f"{_M}.bid_qc_capability",
"description": "开启一轮解析产出契合度审核:返回审核清单+该类产出物待核内容(对照招标文件原文逐项核对后打分)",
"params": {"qc_type": "审核对象 scoring_items|qualifications|doc_requirements|chapter_outline",
"project_id": "项目ID(可选,默认当前)"},
"required": ["qc_type"],
},
"finish_qc": {
"module": f"{_M}.bid_qc_capability",
"description": "落契合度分并判定:得分高于通过分(默认9.5,10分制)放行;不通过必须给改进意见,系统清空该类产出并触发解析重做",
"params": {"review_id": "start_qc 返回的评审ID", "fit_score": "契合度得分 0~10(可带一位小数)",
"improvement": "改进意见(不通过必填:缺了什么/错在哪/对照原文哪一处)",
"comments": "审核说明(可选)"},
"required": ["review_id", "fit_score"],
},
"list_qc": {
"module": f"{_M}.bid_qc_capability",
"description": "列出项目 QC 审核记录(可按审核对象过滤)",
"params": {"project_id": "项目ID(可选,默认当前)", "qc_type": "审核对象(可选)"},
"required": [],
},
"qc_report": {
"module": f"{_M}.bid_qc_capability",
"description": "项目 QC 总览:四类产出的最新契合度审核状态",
"params": {"project_id": "项目ID(可选,默认当前)"},
"required": [],
},
# ── bid_compose_capability:标书合成工程师 ──
"compose_bid": {
"module": f"{_M}.bid_compose_capability",
"description": "合成标书(要求全部章节已评审通过;产出 md+docx 并登记版本)",
"params": {"project_id": "项目ID(可选,默认当前)", "doc_name": "标书名称(可选)"},
"required": [],
},
"list_bid_documents": {
"module": f"{_M}.bid_compose_capability",
"description": "列出已合成标书版本及评分",
"params": {"project_id": "项目ID(可选,默认当前)"},
"required": [],
},
"read_bid_document": {
"module": f"{_M}.bid_compose_capability",
"description": "分段读取合成标书正文(供整书评审)",
"params": {"document_id": "标书ID", "offset": "起始字符(可选)", "length": "长度(可选)"},
"required": ["document_id"],
},
# ── bid_score_capability:标书评分员(模拟评标)──
"start_bid_score": {
"module": f"{_M}.bid_score_capability",
"description": "开启一轮整书评分:返回评审ID+全部评分项清单",
"params": {"project_id": "项目ID(可选,默认当前)", "document_id": "标书ID(可选,默认最新)"},
"required": [],
},
"add_score_item_result": {
"module": f"{_M}.bid_score_capability",
"description": "逐个评分项落分;不合格项必须给 improvement+目标章节",
"params": {"review_id": "评审ID", "scoring_item_id": "评分项ID", "score": "得分",
"max_score": "满分(可选)", "reason": "评分理由(可选)",
"improvement": "改进意见(不合格必填)", "target_chapter_no": "待改章节号(可选)",
"target_chapter_id": "待改章节ID(可选)"},
"required": ["review_id", "scoring_item_id", "score"],
},
"finalize_bid_score": {
"module": f"{_M}.bid_score_capability",
"description": "汇总整书评分:通过→发交付确认任务;不通过→改进意见落到问题章节自动退回重写",
"params": {"review_id": "评审ID", "comments": "总体评审说明(可选)"},
"required": ["review_id"],
},
"request_chapter_revise": {
"module": f"{_M}.bid_score_capability",
"description": "按改进意见定点退回单个章节",
"params": {"chapter_id": "章节ID", "improvement": "改进意见"},
"required": ["chapter_id", "improvement"],
},
"bid_score_report": {
"module": f"{_M}.bid_score_capability",
"description": "最近一轮整书评分报告(总分+逐项明细)",
"params": {"project_id": "项目ID(可选,默认当前)"},
"required": [],
},
}
def register_role_tools():
"""把投标角色工具 schema 注册进引擎分发字典(幂等)。
引擎不可用(未装 pipeline-service)时诚实降级返回 0,不抛异常。
"""
try:
from pipeline_service.capability_tools import TOOL_SCHEMAS
except Exception as e:
logger.warning("引擎不可用,投标角色工具未注册: %s", str(e)[:160])
return 0
added = 0
for name, schema in BID_ROLE_TOOL_SCHEMAS.items():
TOOL_SCHEMAS[name] = schema
added += 1
logger.info("bid role tool schemas registered: %d", added)
return added