智标 Agent · 系统架构

对外站点 https://zhibiao.jobrag.com.cnwww.zhibiaozhibiao.jobrag.cn 跳转到此;旧 bid 子域已停用)。 本页只展开 IT 系统集成标书 Agent:询比/邀请/货物/电子招采分册 Word,解析招标、按槽位选材(含原厂授权)、按投标文件格式出稿、质量循环与风控。 不做监理/施工主线。同机还有花卉站,不画进主图。运行目录云端 /opt/bid;本机仓库只是代码副本。

1. 整体架构

浏览器打开工作台网页。日常做标走页面按钮;对话框用来问路、认材料、问进度/缺口/风控或改某一个字段,不会在对话里直接开生成。Agent 模式是固定流水线 + 受控循环,不是 ReAct。

flowchart TB
  user["用户浏览器"]
  nginx["Nginx HTTPS :443"]
  uvicorn["Uvicorn 0.52.1 :8000"]
  fastapi["FastAPI 0.141.1 / Python"]

  subgraph pages["工作台页面(SPA)"]
    work["工作台 /app"]
    proj["投标项目"]
    lib["企业资料库"]
    users["用户管理"]
    chat["左侧对话助手"]
  end

  subgraph apis["核心接口"]
    rest["REST /api/projects /api/kb /api/auth"]
    chatApi["POST /api/chat"]
    task["GET /api/tasks/{id}"]
  end

  subgraph agent["LangGraph:固定流水线 + 受控循环(不是 ReAct)"]
    router["router 意图分流"]
    parse["parse 解析招标"]
    select["prepare / select 选材"]
    plan["planner 取数计划"]
    tools["tool_executor 查库"]
    gen["generator 出 Word"]
    risk["risk 风控门"]
    qa["qa / finetune"]
  end

  subgraph data["数据"]
    pg["PostgreSQL 16"]
    kb["uploads/kb 原件"]
    st["store.py 项目 JSON"]
  end

  subgraph llm["模型"]
    txt["OPENAI_MODEL 文本"]
    vl["VISION_MODEL 视觉"]
    fb["OPENAI_FALLBACK 兜底"]
  end

  user --> nginx --> uvicorn --> fastapi
  fastapi --> pages
  fastapi --> apis
  rest --> parse
  rest --> plan
  chatApi --> router
  task --> st
  router --> parse --> select --> plan --> tools --> gen --> risk
  router --> qa
  tools --> pg
  gen --> kb
  gen --> txt
  risk --> txt
  fastapi --> pg
  rest --> st
  vl -.-> gen
  fb -.-> txt
        

SPA 是「单页应用」:登录后点「投标项目 / 资料库」只换中间内容,不会整页白屏刷新。箭头是调用方向。人负责选材确认、报价/有效期、盖章签字和实质性偏离。

2. 组件与版本

以下对照 backend/requirements.txtdocker-compose.cloud.yml。前端缓存当前为 app.js?v=56

层级组件版本作用
接入Nginx宿主机HTTPS 终结,反代 127.0.0.1:8000
前端零构建 SPAwebapp/ v=54工作台、项目、资料库、对话
APIFastAPI0.141.1REST、会话、静态页
运行时Uvicorn0.52.1ASGI 进程
编排LangGraph1.2.10对话路由与节点图
LLMlangchain-core / langchain-openai1.5.3 / 1.4.2模型封装
数据库PostgreSQL16(postgres:16,驱动 pg8000)账号、资料库元数据、对话、风格、风控
Wordpython-docx1.2.0按格式树出投标文件
PDFpdfplumber / pypdf / pypdfium20.11.10 / ≥5.1 / ≥4.30解析招标;加密 PDF 只用用户口令
OCRRapidOCR + onnxruntime≥2.0 / ≥1.17扫描件识别
表格openpyxl≥3.1报价 xlsx
图像Pillow / imagecodecs≥12.2 / ≥2024.12缩略图;Word 内 HD Photo/WDP 转 JPEG
校验pydantic2.13.4请求体
可选Dify KB环境变量全空则不用不参与主生成路径
禁止MySQL Community / GPL 传染依赖旧 bid-mysql 已停,卷保留可回滚

3. 数据库与版本

业务库是 PostgreSQL 16(容器 bid-postgres)。项目运行时状态主要在文件系统 JSON(store.py),不整份塞进 PG。Schema:backend/sql/schema.sql,启动时 ensure_* 幂等补列。

库 / 表引擎主要内容
bid_dbPostgreSQL 16唯一业务库
company / certificate / project / personnel / image_assetPG演示库结构化主数据;真实库抬头读 enterprises,资格/业绩/人员表用已选 kb_docs 拼行
kb_docsPG原件元数据:类别、demo/real、enterprise_id、owner_id
enterprisesPG真实库归属主体(子公司 parent_id)+ 投标函通讯录
usersPG账号、角色、permission、status、锁定与改密标记
login_sessionsPG会话令牌,空闲超时默认 12 小时,可在安全策略改
audit_logPG登录/失败/上传/下载/改密;管理员页 #/audit 可查
app_settingsPG安全策略:密码长度、失败锁定、空闲超时
chat_sessions / chat_messagesPG对话长期记忆,按用户+项目
user_preferencesPG默认招标类型、暗标
style_chunksPG风格句式切片与哈希向量
risk_reportsPG风控报告 JSON
uploads/kb磁盘原件二进制
store.py JSON磁盘phase、选材、路径、报价、filled_data

禁止把客户 A 的商业秘密写进客户 B 的模型微调。demo 与 real 库、enterprise_id 隔离。

4. 模型与使用节点

现网以 /healthz 为准。文本主模型失败走 OPENAI_FALLBACK_*。风格检索默认字符 3-gram 哈希向量(256 维);配了 embeddings API 则优先用 API 向量。

模型提供方用在哪个节点说明
qwen3.6-plusOPENAI_MODEL 兼容接口generator 章节撰写、router、qa、finetune、quality_iterate主文本。不负责盖章和实质性偏离决策。
qwen-vl-plusVISION_MODELfinetune 带图改稿、扫描件辅助视觉。加密招标不用它破解。
OPENAI_FALLBACK备用兼容接口主模型失败环境变量配置;未配则只报错。
embeddings API(可选)EMBEDDING_MODELstyle_chunks 检索未配则用本地 3-gram 哈希。
RapidOCR本地 onnxruntimeparse / 扫描件不是大模型。

5. Agent 工作模式

四循环(感知 → 规划 → 执行 → 反思)是分工框架。现网按这四步排工序,但不是 ReAct:下一步由按钮和写死的流水线决定,大模型主要写正文、改稿、问答和质检,不负责每步挑选工具。

ReAct本系统(现网)
模式模型每步输出思考 / 调用哪个工具 / 观察结果,再决定下一步固定流水线 + 受控循环:解析 → 选材(人)→ 生成 → 质量 → 风控
谁决定下一步大模型当场选工作台按钮 + 写死的节点顺序
规划模型拆任务planner 是规则清单,不调模型
查库模型挑选工具tool_executor 按清单跑固定的 query_*
循环上限理论上可一直转质量最多 3 轮;风控最多再生成 1 次;选材必须等人
模型主要干什么当总调度写章节、对话改稿、问答、质量审查;读招标/列格子/出 Word 骨架多为规则
flowchart LR
  perc["1 感知
读招标 / OCR / 看资料库"] --> plan["2 规划
列格子、列要查的数"] plan --> act["3 执行
查库 / 写 Word / 插图"] act --> refl["4 反思
质量循环 / 风控 / 人勾选"] refl -->|未过且未超次数| act refl -->|人选材或再问一句| perc classDef cPerc fill:#e7efe4,stroke:#315f43,color:#1c2a1e classDef cPlan fill:#e8eef8,stroke:#3d4f7c,color:#1c2a1e classDef cAct fill:#fff6df,stroke:#c4a15a,color:#1c2a1e classDef cRefl fill:#fdecec,stroke:#b45353,color:#1c2a1e class perc cPerc class plan cPlan class act cAct class refl cRefl
四步白话落在本系统哪里现网怎么做
感知先看清招标和库里有什么标书解析流水线;读招标 / 列出格子规则解析 + RapidOCR;不靠模型猜目录
规划决定要查哪些数、要附哪些证planner;材料需求格子规则清单,这一步不调大模型
执行去库里取数、按目录写出 Wordtool_executor、generator、dark_packPostgreSQL 查库;python-docx 出稿;正文用 qwen3.6-plus
反思写完检查,不行就改,人也可以拦quality_iterate、risk、选材页质量最多 3 轮;风控规则为主、最多再生成 1 次;选材必须人确认

下面三条流水线用颜色区分:绿=感知,蓝=规划,金=执行,红=反思。每个框第二行是该步用到的组件或模型。

对照市面七种智能体模式

对照博文《7 种智能体设计模式》(CoT / Self-Ask / ReAct / Plan-and-Execute / ToT / Reflexion / Role-playing)。长任务文章也推荐先规划再执行、反思要封顶、关键节点人审。智标按投标出稿改写了执行层:不把 ReAct 当操作系统

模式文章怎么用智标现网相对优势 / 取舍
CoT 思维链一步步写出推理,便于审计完成页可展开规则问题、专家建议、优化轮次、废标风险一句话给人看「为什么扣分」,解析目录仍走规则,不靠思维链猜章节
Self-Ask把大问题拆成可检索的小问题对话可问「还缺什么材料」;格子本身由规则拆出主路径不需要模型追问。缺件走资料库,不编造证书
ReAct每步思考并挑选工具;文章称框架默认范式主路径禁止。对话框问进度/缺口/风控用白名单直答;说「生成」不会后台开跑,须工作台按钮避免跳选材、填假证、对加密 PDF 乱试。对话不像通用助手「点一切 API」
Plan-and-Execute先全局计划再逐步执行;计划应可审核生成前弹出取数清单(公司/证书/业绩/人员/图片)。公司信息必查,其它可取消。计划来自规则,不调模型人看得见这次查什么。取消项留空,不编造。这是骨架
ToT 树状思维多分支探索择优,成本指数涨不做整本分叉。质量循环只定向重写弱章节时间和费用可控。不以「多套标书打分」当卖点
Reflexion评估失败原因后带教训重试;3~5 次硬停止质量最多 3 轮;风控最多再生成 1 次。评估=占位符规则+专家 JSON符合文章停止条件。教训暂不跨项目复用(只学口气)
Role-playing多角色开会;关键节点人审解析/选材/撰写/排版/风控是工位戳记,同一进程。选材必须人确认人审比「角色互聊」更硬。不启多进程对等 Agent

文章文末配方是「规划执行骨架 + ReAct 执行 + 反思兜底 + 角色分工」。智标配方是「规则规划执行骨架 + 规则执行(模型只写正文)+ 受控反思 + 角色工位 + 人选材」。执行层不用 ReAct,是针对废标风险的选择,不是少做了一层。

6. Agent 节点流程

工作台点按钮时不会经过「接待分流」,从读招标或写标书直接开始;左侧对话框里说话,才会先判断你想干什么。点图上的框,右侧说明会跟到该步骤旁边。

点框看说明,说明跟当前步骤走。 感知规划执行反思
flowchart TD
  msg["入口
SPA / FastAPI"] --> src{"入口?"} src -->|对话框| router["接待分流
规则 · 可选 qwen"] src -->|工作台上传招标| parse src -->|工作台点生成| planner router --> kind{"意图
规则"} kind -->|进度/闲问| qa["问答
qwen3.6-plus"] kind -->|有文件未解析| parse["读招标
RapidOCR / pdfplumber"] kind -->|选材中| select["记下勾选
PostgreSQL"] kind -->|改/换字段| fine["对话改稿
qwen · 可选 qwen-vl"] kind -->|生成类| planner parse --> prep["列出材料格子
requirements_parser"] prep --> wait{"选完?"} select --> wait wait -->|否| human["等待人工选材
人"] wait -->|是| planner["列取数清单
规则 不调模型"] planner --> tools["去库里取数
query_* / PostgreSQL"] tools --> gen["写出 Word
python-docx · qwen"] fine --> gen gen --> reflN["质量怎么说
quality_report"] reflN --> risk["风控检查
risk_agent 规则为主"] risk --> block{"严重且未重写?"} block -->|是 最多1次| gen block -->|否| done["结束"] qa --> done done --> pdf["转 PDF
LibreOffice"] classDef perc fill:#e7efe4,stroke:#315f43,color:#1c2a1e classDef plan fill:#e8eef8,stroke:#3d4f7c,color:#1c2a1e classDef act fill:#fff6df,stroke:#c4a15a,color:#1c2a1e classDef refl fill:#fdecec,stroke:#b45353,color:#1c2a1e class msg,src,parse perc class router,kind,planner,wait,prep plan class select,tools,gen,fine,qa,pdf act class human,reflN,risk,block,done refl

7. 标书解析流水线

新建项目里点「开始解析」之后发生什么。解析完进入选材页,不直接出 Word。颜色:绿感知 / 蓝规划 / 金执行 / 红反思。

点框看说明,说明跟当前步骤走。 感知规划执行反思
flowchart TD
  pBtn["点开始解析
工作台 SPA"] --> pTask["创建后台任务
FastAPI / projects"] pTask --> pOpen["打开招标文件
tender_ingest · RapidOCR"] pOpen --> pEnc{"加密且没口令?
pypdf 规则"} pEnc -->|是| pStop["停住请填密码
不破解"] pEnc -->|否| pTree["拆目录表单工程名
pdfplumber / python-docx"] pTree --> pReq["识别材料需求格子
requirements_parser"] pReq --> pCand["资料库检索候选
PostgreSQL"] pCand --> pPick["默认预选
规则"] pPick --> pUi["进入选材页
工作台 SPA"] classDef perc fill:#e7efe4,stroke:#315f43,color:#1c2a1e classDef plan fill:#e8eef8,stroke:#3d4f7c,color:#1c2a1e classDef act fill:#fff6df,stroke:#c4a15a,color:#1c2a1e classDef refl fill:#fdecec,stroke:#b45353,color:#1c2a1e class pBtn,pOpen,pTree,pEnc perc class pReq,pPick plan class pTask,pCand,pUi act class pStop refl

8. 工作台生成流水线

选材确认后点「生成投标文件」,先确认取数计划(公司信息必查)。颜色:绿感知 / 蓝规划 / 金执行 / 红反思。

点框看说明,说明跟当前步骤走。 感知规划执行反思
flowchart TD
  btn["工作台点生成
确认取数计划"] --> api["创建后台任务
FastAPI"] api --> planN["取数并写出初稿
规则+PG+docx+qwen"] planN --> qi["质量循环最多3轮
quality_review · qwen"] qi --> fill["最终清扫
placeholder_fill 规则"] fill --> itTech["点对点+双层方案
it_tech"] itTech --> itQ{"IT 询比/中信三册?
it_pack"} itQ -->|是| itPack["商务/技术不含价
报价独立分册"] itQ -->|否| darkQ{"暗标?
项目标记"} itPack --> darkQ darkQ -->|是| pack["暗标分册
技术去身份 / 商务留名"] darkQ -->|否| rk["风控检查
risk_agent"] pack --> rk rk --> blk{"严重问题?
规则"} blk -->|是 可再生成1次| planN blk -->|否| ingest["记住写法只学口气
style_store 哈希向量"] ingest --> doneN["完成页下载分册 Word
工作台"] classDef perc fill:#e7efe4,stroke:#315f43,color:#1c2a1e classDef plan fill:#e8eef8,stroke:#3d4f7c,color:#1c2a1e classDef act fill:#fff6df,stroke:#c4a15a,color:#1c2a1e classDef refl fill:#fdecec,stroke:#b45353,color:#1c2a1e class btn,darkQ,itQ plan class api,planN,fill,itTech,pack,itPack,ingest,doneN act class qi,rk,blk refl

9. 长短期记忆

没有独立记忆服务。分四层落库或落盘。禁止跨客户把商业秘密写进对方的微调或风格库。

flowchart TB
  subgraph shortMem["短期"]
    ch["chat_history 当前请求"]
    dbch["chat_sessions / chat_messages"]
    fd["filled_data 对话改过的字段"]
    task["_TASKS 内存进度"]
  end
  subgraph longMem["长期"]
    pref["user_preferences 标类/暗标"]
    chunks["style_chunks 句式切片"]
    kb["kb_docs + uploads/kb"]
    st["store.py 项目 JSON"]
    audit["audit_log"]
  end
  ch --> dbch
  fd --> st
  chunks --> genN["generator 只注入句式"]
  kb --> sel["select 插扫描件"]
  pref --> neu["新建项目默认"]
        
种类存哪用途生命周期
对话短期AgentState.chat_history本轮问答单次请求 / 合并自 DB
对话长期chat_sessions + chat_messages刷新后继续聊该项目用户可删会话
改稿记忆filled_data + finetune_log电话/有效期等覆盖再生成随项目 JSON
任务进度_TASKS 内存生成百分比进程重启即丢(前端按 phase 恢复)
用户偏好user_preferences默认招标类型、暗标长期
风格长期style_chunks生成时只注入句式,不抄单位证书生成成功后切片;learn_from_edits 从改稿学
企业知识kb_docs + 磁盘原件选材插图按 demo/real + enterprise_id 隔离
项目记忆store.pyphase、选材、路径、报价容器重启仍在
审计audit_log登录/失败/上传/下载/改密长期;管理员 #/audit

10. 功能清单

产品面能力。四角色:admin 系统管理员 / bidder 标书专员(含自己的企业资料) / librarian 资料管理员(可选专岗) / reviewer 只读复核。

模块能力
登录账号密码 + 动态验证码;登录框含产品名与版本;左侧栏显示当前用户;首次登录强制改密。登录页不放系统全景入口
用户管理管理员侧栏切换。建号、四角色、重置密码、停用/启用、强制下线、删除。密码 ≥8 位且须含大写、小写、数字和特殊符号(@ # % _ ! $ * + - = . ?)
审计日志管理员可筛用户/动作:登录、失败、改密、改角色、下载、删企业
系统全景仅管理员可见;新标签打开,默认停在页顶
安全策略管理员可调密码最少位数、失败锁定、空闲超时
工作台项目统计、资料库构成
投标项目列表、停止生成中任务、下载
新建项目招标 PDF/Word/图片(单文件 ≤100MB);可另附技术规范(点对点)、原厂/集成商方案、报价表/合同;暗标开关;类型默认 IT 系统集成(创建页不提供监理/施工);名称/口令/资料库两列;demo/real 库;主企业下拉,子公司可选
解析打开招标(口令/OCR);拆目录与表单并纠偏父子;默认判为 IT 系统集成(不再自动判监理/施工);识别询比/中信三册;「应答文件格式」与「投标文件格式」同等抽树;邀请谈判认「采购邀请文件的格式」,主文件抽空则用另附;PDF 转 Word 失败则从文本层抽格式树;须知/标题判定不适用章;列出材料格子(原厂授权、财务、业绩、团队、承诺书、一般纳税人)并预选;失败时按口令/OCR/空目录给出下一步
选材按槽位勾选原件;原厂授权与授权委托书分槽;人员证书 vs 社保缴费分槽;整章不适用的不要求保证金
生成先确认取数计划(公司信息必查;真实库读所选企业档案,资格/业绩/人员表用已选原件元数据填,不灌演示表;演示库读 company 表);IT 询比/中信拆商务、技术、报价三册(商务/技术 quotes 为空);询比/中信技术分册不插商务扫描件;投标函写入总价与有效期(隔离分册除外);另附规范书生成点对点(默认满足,负偏离在选材页勾选确认);原厂/集成商方案按文件名贴入技术册,不写监理腔;另附报价 xlsx/Word 贴进报价一览表(不编造金额);IT 标不写死监理保证金 1.5 万或代理费 7500;真实库按勾选槽位插扫描件;已交商务册也可按「附件7-x」落到对应章(不入库、不建工作台项目);货物单册按章把开标一览/分项报价与投标函分开;PDF 格式树去掉水印单字/页码/评标误表,句内重复汉字水印会折叠;执照/资质/人员/信誉/财务挂到对应子表(IT 不按总监证拆人员扫描件;资质留在资格审查章);章/表另起一页,扫描件一证一页;不适用章节只写「本项目不适用。」;Word 带页码目录;工程名取完整标题并去水印;招标已有目录或 IT 集成不追加工程标附件包;暗标仅技术分册去身份;质量循环(签字日期下划线不按缺项扣);完成页质检与风控占位同一口径;可停止
报价明细 + 总价 + 交货期 + 投标有效期;另附 xlsx 贴进报价分册一览表;询比/中信只进报价分册
风控生成后必跑;询比/中信商务或技术出现报价表则 error;未勾选原厂授权、未附规范书或方案抽空则告警;完成页可展开明细并再检
资料库真实库企业改为下拉筛选,可编辑企业档案(地址/电话/邮编/法人/信用代码/开户行等,写入投标函);多文件/文件夹/zip 上传(单文件 ≤100MB);待传列表可逐个移除;按文件名自动分类(章节含「原厂商」归入厂商授权书,与授权委托书分槽);选类别/招标类型即筛选;临时可从投标 Word/PDF 拆扫描件挂到企业(带水印,仅实测;按正文就近章节归类,认询比「附件7-x」,跳过目录页码行;Word 内 HD Photo/.wdp 转成 JPEG 再入库,浏览器才能预览;社保≠业绩、年检≠财务、身份证≠授权书;每类有上限);上传或拆入后对照章节/文件名/页上文字标出可能分错的项,弹窗带缩略图可点开原件再确认是否更正(不在对话里现猜);图片预览可旋转放大,放大后按住左键拖动;删企业
对话按所在页面指路;资料库概况分演示库/真实库(含当前筛选);可把扫描件发来认类别(规则对照,改分类仍走确认框);项目内问进度、缺口、招标要点、风控、改字段;不在对话里开生成
下载询比/中信:商务 / 技术 / 报价三册 Word;其它:docx;PDF 按需 LibreOffice

11. 安全基线

2026-08-16 已落地。大小写、数字、特殊符号与弱口令黑名单不可关。登录须动态验证码。

现状
密码≥8 位,须含大写、小写、数字和特殊符号(@ # % _ ! $ * + - = . ?);禁与用户名相同、禁弱口令;PBKDF2-HMAC-SHA256。已有账号登录不强制改密
登录验证码4 位点阵用普通网页格子画出(不依赖图片/画布/字体);登录框含产品名与版本,落在流程图与能力底座之间
新建用户must_change_password=TRUE,第一次登录必须改密
停用立即踢会话;内置 admin 不可删、不可停用
锁定失败 5 次锁 15 分钟;对外不区分「用户不存在」
改密本人改密保留当前会话、踢其它设备;管理员重置则全踢并强制再改密
角色admin 全部;bidder 写标+自己的资料库;librarian 可选专岗只管资料;reviewer 看+下载
系统全景仅管理员左侧栏入口;新标签打开;登录页不展示
审计页#/audit 可筛用户与动作;与用户管理、安全策略并列在左侧栏
安全策略#/security 密码长度、失败锁定、空闲超时
内部令牌BACKEND_TOKEN 仅内部/自动化,不当作页面登录
加密 PDF只用用户提供的口令打开,不破解

关键代码:backend/app.py HTTP;projects.py 任务编排;it_pack.py IT 分册与报价隔离;it_tech.py 点对点与双层方案;scan_overlay.py / kb_bid_ingest.py 已交商务册按附件落图;graph.py / nodes.py Agent 图;tender_format.py / tender_na.py 格式树与不适用章;form_order.py 解析目录纠偏;tender_render.py / tools_format.py / docgen.py 出 Word;authx.py 用户会话。