pipeline-opportunity — 商机产线能力包
把招标市场情报转化为软件研发商机:热点软件推荐 → 每日AI/Agent招标 → 研发报告编写 → 人工确认 → 研发审批流程。
平台边界(重要)
- 数据爬取平台(ebpe.cc:/d/ymq/work/tender_opp,独立部署):采集中国招标网站数据、
持久存储、去重,仅通过内网 HTTP 只读接口对外(
192.168.16.2:9085,X-API-Token 鉴权)。 - 本模块(产线平台侧):商机业务闭环。只消费爬虫数据,不爬取、不存招标原始数据;
报告/审批状态落产线库
opp_reports/opp_approvals表,绝不回写爬虫库。
依赖方向:产线平台 ──HTTP──> 数据爬取平台(单向)。
产线闭环与门禁
opp_hot_software / opp_daily_ai_tenders(爬虫平台数据)
↓ 选定方向
opp_create_report(草稿)→ opp_update_report(补写,数据必须来自工具返回)
↓
opp_submit_report ──> 人工确认任务(门禁,pipeline_human_tasks: opp_report_confirm)
↓ 人工确认通过(confirm 回流)
initiate_approval ──> 研发审批任务(门禁,opp_dev_approval)
↓ 人工审批结论回流
approved / rejected(rejected 可退回 draft 重来)
状态机:draft → confirmed → approval_initiated → approved/rejected(非法迁移一律拒绝)。
agent 禁止自批自审:确认与审批结论只能由人工任务回流驱动。
工具清单(主 agent / 驾驶舱)
| 工具 | 用途 |
|---|---|
| opp_hot_software | 热点软件推荐(招标量+预算+地区排名) |
| opp_daily_ai_tenders | 每日 AI/Agent 招标展示数据 |
| opp_search_tenders | 关键词检索招标信息 |
| opp_tender_detail | 单条详情(含原文/预算/联系人/来源链接) |
| opp_crawler_stats | 爬虫平台采集健康度 |
| opp_create_report / opp_update_report | 报告草稿创建与补写 |
| opp_list_reports / opp_get_report | 报告列表与全文 |
| opp_submit_report | 提交人工确认(门禁) |
| opp_list_approvals | 审批单列表 |
| opp_diagnose | 产线诊断(报告分布/待办/爬虫连通性) |
角色:agent.opp_analyst(商机分析师)、agent.opp_writer(研发报告撰写工程师)。
slash 命令:/hot /ai /reports /oppdiag。
数据参考弹窗(三级下钻,2026-09-08 交互定稿)
菜单「📋 数据参考」→ opp_references_popup.dspy,三级结构全部整行点击(cursor:pointer,
无「查看分项」按钮):
- 汇总层(主题排名:招标/国内众包/海外三板块):点主题条目 → 弹出该主题分项列表
(
opp_references_items/opp_demand_items/opp_overseas_items.dspy)。 - 分项层(明细条目):每条说明文字标注「来源:xxx」(
source_text()解析, 来源按钮已废弃删除);点条目 → 弹出具体内容(opp_item_detail.dspy: 爬虫平台/api/tenders/{id}全量字段 + 公告/需求全文 + 原文页/采集来源页按钮 + 附件列表)。 - 附件层:详情弹窗列出条目附件(爬虫平台
/api/tenders/{id}/attachments, 字段容错归一normalize_attachment),「下载」按钮走服务端代理opp_attachment_dl.dspy——先回查条目附件清单做归属校验(防 SSRF,前端传任意 att_url 不在清单内即拒绝),再按降级链取字节:记录 download_url →/api/attachments/{id}/download→ 附件原始 url;代理失败如实报错不静默。
附件端点未就绪(爬虫平台附件子系统部署中)时:分项列表不显示 📎 角标、详情弹窗 显示「附件服务暂不可用」,其余功能不受影响。
研发报告列表/详情/成果文件下载(2026-09-09 用户需求改造)
菜单「📊 研发报告」由原 CRUD 裸表页(opp_reports/index.ui,无过滤+可增删改)
改为只读列表页 api/opp_reports_list.dspy,三点改造:
- 按项目 owner 过滤(
list_visible_reports单一事实源):- 挂项目的报告:当前用户是项目 owner(
sd_projects.created_by==uid)才可见; agent 创建的项目(created_by LIKE 'agent.%',模式经${kw}$参数化—— SQL 字面量裸%会被驱动当格式化符炸 ValueError,实测踩过)降级为同机构成员可见 (对齐check_project_owner既有降级语义,不重复发明) - 未挂项目的报告(平台级调研,存量数据大多是这类):登录用户可见
- 项目已删的孤儿报告:owner 无法验证 → 不可见(宁缺勿漏,LEFT JOIN 自然排除)
- 详情/下载端点复用
check_report_visible(与列表同一规则,语义不漂移)
- 挂项目的报告:当前用户是项目 owner(
- 详情四节展示(
opp_report_detail.dspy,整行点击下钻,范式同opp_references_items): 报告正文按四节模板解析(parse_report_sections)——## 研发场景/## 输入/## 输出/## 成果,逐节 MdWidget 渲染;兼容带序号/冒号/加粗的标题变体, 三级标题不误判,重复同名节拼接不丢内容。旧报告(无四节标题)全文归「输出」节, 空节如实显示「本报告未填写此节」不编造。agent 写报告的四节模板硬要求已写进 OPP_PROMPT + opp_create/update_report 工具描述 + opp-workflow 技能。 - 成果文件多个列出、逐个下载(
list_report_files+opp_report_file_dl.dspy): 文件范围 = 项目工作空间deliverables/全部文件 + 报告 PPT(ppt_path, 按 realpath 去重)。下载安全模型对齐opp_attachment_dl:前端只传report_id + name,服务端回查清单命中才给文件,文件名绝不参与路径拼接 (清单只来自目录列举+ppt_path,../穿越名在清单里不可能出现)。
CRUD 页(opp_reports/ opp_approvals/)保留供后台运维直接编辑,菜单入口不再暴露。
爬虫平台接入配置
系统级配置禁硬编码,走 appbase params 表(兜底默认值内网地址):
| params 键 | 值 |
|---|---|
tender_api_base |
http://192.168.16.2:9085(默认) |
tender_api_token |
爬虫平台 state/api.env 中的 TENDER_API_TOKEN |
部署(宿主 = pipeline-app)
git clone到<APP_ROOT>/pkgs/pipeline-opportunitybash build.sh(建表 + 种子数据 + wwwroot 软链 + pip install)- app 入口已接线:
load_pipeline_opportunity()(try/except 兜底) - RBAC:
cd <APP_ROOT> && py3/bin/python pkgs/pipeline-opportunity/scripts/load_path.py - i18n:合并
i18n/{zh,en}/msg.txt到宿主 wwwroot(merge_i18n.py),调 /i18n_getmsgs 刷新 - 重启应用;浏览器验证驾驶舱
/pipeline-opportunity/agent
表
opp_reports:研发报告(software/title/content/status/confirm_task_id/confirmed_by)opp_approvals:研发审批(report_id/status/note/resolved_by)
技能
产线技能在 pipeline-core 技能库:skills_library/pipelines/opportunity_general/
(common/opp-workflow 总纲 + roles/agent.opp_analyst、agent.opp_writer 角色技能)。