mcpField
B
bid-leveling

bid-leveling

github.com/build-plus文档处理5176 次安装38 周前更新
代码仓库

关于 bid-leveling

bid-leveling 是一项用于分析建筑投标的技能,可将费用项目映射到 UniFormat II,并生成比较表格和 PDF 报告。它既支持单份投标审查,也支持考虑范围差异的多份投标比较。

主要功能

  1. 01提取费用和合同条款
  2. 02将项目映射到 UniFormat II
  3. 03分析工作范围重叠
  4. 04按单位比较投标价格
  5. 05生成表格和 PDF
  6. 06支持单份及多份投标

适用场景

  1. 01比较工作范围有重叠的投标
  2. 02在其他投标到来前审查单份方案
  3. 03识别各方承包工作的差异
  4. 04记录投标条款和除外事项

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/build-plus/skills --skill bid-leveling

安装后在 Claude Code 中输入/bid-leveling确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
bid-analysis-guide.md
uniformat_headings.csv
scripts/
generate_csv.py
generate_pdf.py

详细介绍

投标价格平衡分析

通过将明细项映射到 UniFormat II 标题,对比施工投标,生成价格平衡电子表格和简明的分析 PDF 报告。

单份文档与多份文档

此技能支持单份投标分析和多份投标对比。两种情况的工作流程相同,但仅提供一份文档时有以下区别:

  • 跳过步骤 3(范围重叠评估)——无需比较
  • 不提供建议——完全省略 analysis.json 中的 recommendations 和 overlap_comparison。PDF 不会呈现“建议”部分。
  • 不生成范围重叠矩阵——省略 analysis.json 中的 scope_overlap。PDF 第 1 页仅显示项目信息和投标汇总表。
  • 仍会生成电子表格和 PDF——电子表格按 UniFormat 展示单个投标方的成本明细,PDF 则详细说明该投标的合同条款、范围、资质和除外项。

当用户希望分析单份提案、将其结构提取到 UniFormat 类别中,并在收到其他投标前记录其条款时,此功能很有用。

工作流程

  1. 收集项目信息并确认输出格式偏好
  2. 阅读并提取每份投标文档中的数据
  3. 评估范围重叠情况和可比性*(单份文档时跳过)*
  4. 确定比较单位
  5. 将明细项分配到 UniFormat 代码;确定细分粒度
  6. 构建结构化 JSON 数据
  7. 生成电子表格(运行 generate_csv.py)
  8. 生成 PDF(运行 generate_pdf.py)

步骤 1:收集项目信息

询问用户:

  • 项目名称(例如,“Smith Residence”)
  • 简要描述(例如,“定制住宅建造”“厨房改造”“管道分包”)
  • 输出格式:CSV 还是 Excel?

如果用户已提供这些信息,则跳过提问。

Excel 上下文

如果用户正在使用 Excel 文档(提到了 .xlsx 文件、引用了电子表格,或处于电子表格使用场景),则应将价格平衡数据添加为其现有工作簿中的新工作表,而不是新建文件。将现有文件作为第三个参数传递给 generate_csv.py。

步骤 2:阅读投标文档

阅读用户提供的每份投标文档。对每份文档,提取:

  • 每一项可识别的成本明细项(描述 + 成本)
  • references/bid-analysis-guide.md 中列出的所有合同条款

提取条款时,保留源文档中的准确措辞。

处理不同文件格式

PDF(.pdf) 使用 Read 工具读取。对于多页 PDF,按页码范围读取(每次最多 20 页)。投标文件通常采用表格格式——提取明细项时,请特别注意列对齐。如果 PDF 内容是扫描件或基于图像,而非可选文本,请将其视为图像处理(见下文)。

图像(.png、.jpg、.heic 等) 使用 Read 工具读取(多模态)。提取图像中所有可见的文本、表格和明细项。手写投标文件的照片、电子邮件截图或扫描文档等,通常都是图像。请特别注意:

  • 手写数字——通过交叉核对总额来确认有歧义的数字(例如,1 和 7、5 和 6)
  • 部分可见——如果文档部分内容被裁切,请向用户索取缺失部分
  • 分辨率较低——标明无法有把握读出的数值

Excel(.xlsx、.xls、.csv) 使用 Read 工具读取。电子表格中的投标文件通常结构最清晰——请查看:

  • 价值明细表或明细项选项卡,其中包含描述列和成本列
  • 汇总/总计选项卡或行
  • 可能包含更多详情的隐藏工作表或列
  • 用于计算小计的命名区域或公式

如果用户正在 Excel 文件中处理投标文件,这也属于 Excel 上下文——有关输出处理,请参见步骤 1。

Word(.docx、.doc) 使用 Read 工具读取。正式提案和合同常见于 Word 文档。成本信息可能出现在:

  • 内嵌表格(价值明细表、成本明细)
  • 包含嵌入式金额的段落文本(“……总计 45,000 美元……”)
  • 文末附加的附录或附件

对于 Word 文档,还应仔细提取合同条款——除外项、保留金、付款计划和保险要求等条款,通常嵌在正文中,而不是结构化表格里。

步骤 3:评估范围重叠情况

在平衡投标文件之前,先确定各投标是否具有可比性:

  • 它们是否涵盖相同的工种或工作范围?
  • 它们是否共享 UniFormat Level 2 类别?
  • 各自的总额是否处于彼此合理的范围内?

如果投标文件之间的重叠很少,请醒目地报告这一点,并说明为何直接比较可能会产生误导。仍需生成输出,并明确注明这一限制。

明细项模式

比较范围高度相似且已逐项列明的投标文件时(例如窗户明细、家电套装、预制板系统、装置清单),请检查:

  • 超过 60% 的明细项是否具有可直接比较的单价?
  • 能否在不同投标文件之间匹配等效项目?

如果可以,请使用 granularity: "line_items",将内容细化为实际汇总的明细项描述,以便进行同类比较。构建 detail_rows 数组(见步骤 6),尽可能匹配不同投标文件中的等效明细项。只有在项目确实可以按单位进行比较时,才使用此模式。

步骤 4:确定比较单位

选择最适合进行单价比较的单位。输出中的所有行项目都必须使用相同的单位。

范围类型单位理由
管道、电气、家电报价$/fixture设备数量是自然的计量单位
HVAC 报价$/zone区域是自然的计量单位
保温、石膏板、油漆、地板$/SF(范围面积)所报价具体范围的面积
木框架材料采购、混合单位材料报价$/SF(整栋房屋)没有单一单位;整栋房屋的 SF 是备用选项
涵盖多个 UniFormat 类别的整栋建筑 / GC 投标$/SF(整栋房屋)范围广;房屋 SF 是合适的单位
窗户或门清单$/unit按窗户或门计
屋顶工程$/square(100 SF)或 $/SF屋顶专用单位

规则:

  • 绝不要使用 $/lump 或 $/lumpsum——这不是有意义的比较单位。总有更好的选择。
  • 尽可能根据投标本身推导单位和数量
  • 默认备用选项始终为 $/SF(总建筑面积)——无法确定特定范围单位时使用此选项
  • 如果投标报价中注明了具体范围面积(例如“1,200 SF 瓷砖”),则使用该面积,而非整栋房屋的 SF
  • 输出中的所有行都必须使用一致的单位

在 bid_data.json 中设置 unit_of_comparison:

"unit_of_comparison": {"label": "$/fixture", "quantity": 14}

步骤 5:分配 UniFormat 代码并选择粒度

使用 references/uniformat_headings.csv 将每个行项目映射到 UniFormat Level 3 代码。

规则:

  • 始终分配最具体的 Level 3 代码(例如 D2010,而非 D20)——脚本会处理汇总
  • 如果行项目涵盖多个类别,则分配到占主导的类别;如果金额明确,也可拆分
  • 一般条件费、管理费、利润、保函、许可证 = UNCLASSIFIED(不要映射)
选择输出粒度
范围类型粒度适用情况
单一工种分包"level3"管道、电气、HVAC——精细比较很有价值
多工种或部分范围"level2"厨房改造、TI——汇总到子组级别
整栋建筑 / GC 投标"level2"从零开始建造——L2 类别能清晰呈现情况
高度相似的明细报价(重叠度 >60%)"line_items"窗户清单、家电套装、设备清单

步骤 6:构建结构化 JSON

在工作目录中创建两个 JSON 文件。

bid_data.json(用于生成电子表格)
{
  "project_name": "Smith Residence",
  "granularity": "level3",
  "unit_of_comparison": {"label": "$/fixture", "quantity": 14},
  "bidders": [
    {
      "name": "ABC Plumbing",
      "line_items": [
        {"description": "Rough-in plumbing fixtures", "uniformat_code": "D2010", "cost": 18500.00}
      ]
    }
  ],
  "detail_rows": []
}
  • granularity:"level1"、"level2"、"level3" 或 "line_items"
  • unit_of_comparison:{"label": "$/fixture", "quantity": 14}——单价的单位标签和除数
  • detail_rows:仅当 granularity = "line_items" 时必需:
"detail_rows": [
  {
    "description": "36-inch farmhouse sink",
    "uniformat_code": "D2010",
    "costs": {"ABC Plumbing": 1200.00, "XYZ Plumbing": 1350.00}
  }
]
analysis.json(用于生成 PDF)

所有详细字段都必须是简洁的项目符号字符串数组,而非段落。

{
  "project_name": "Smith Residence",
  "project_description": "Custom home build",
  "scope_description": "Roofing and exterior scope: roof coverings, exterior walls, drainage",
  "unit_of_comparison": {"label": "$/SF", "quantity": 3200},
  "recommendations": [
    {
      "scope": "Roofing (B3010)",
      "recommended_bidder": "Rolvin Carpentry",
      "rationale": "On overlapping scope (roofing only), Rolvin is $35,000 vs Perry $110,250 — 68% less"
    },
    {
      "scope": "Exterior Walls (B2010), Drainage (D2040)",
      "recommended_bidder": "Rolvin Carpentry",
      "rationale": "Only Rolvin covers these scopes; Perry does not quote exterior walls or drainage"
    }
  ],
  "overlap_comparison": {
    "shared_categories": ["B3010 ROOF COVERINGS"],
    "overlap_totals": {"Perry Verrone LLC": 110250.00, "Rolvin Carpentry Inc": 35000.00},
    "notes": "Perry's total ($110,250) appears lower than Rolvin's ($140,000) but Perry only covers roofing. On the shared scope, Rolvin is 68% cheaper."
  },
  "scope_overlap": [
    {"description": "Roof coverings", "uniformat_code": "B3010", "bidders": {"Perry Verrone LLC": true, "Rolvin Carpentry Inc": true}},
    {"description": "Exterior walls", "uniformat_code": "B2010", "bidders": {"Perry Verrone LLC": false, "Rolvin Carpentry Inc": true}},
    {"description": "Rain water drainage", "uniformat_code": "D2040", "bidders": {"Perry Verrone LLC": false, "Rolvin Carpentry Inc": true}}
  ],
  "bidders": [
    {
      "name": "ABC Plumbing",
      "brief_summary": "Comprehensive bid at $34,300 — fixtures, heater, waste, drainage",
      "total_cost": 34300.00,
      "unit_cost": 2450.00,
      "scope_differences": [
        "Includes rain water drainage (D2040) — XYZ excludes",
        "Water heater $4,500 vs XYZ $5,200 for domestic water"
      ],
      "duration_and_schedule": ["6-8 weeks", "Monthly progress billing, Net 30"],
      "preconditions": ["Framing + rough electrical complete", "Slab on grade poured"],
      "substantial_completion": ["All fixtures operational", "Pressure test passed"],
      "lien_waiver_requirements": ["Conditional with each progress payment", "Unconditional at final"],
      "qualifications": ["CA License #987654 (C-36)", "$2M GL, $1M auto"],
      "exclusions_and_terms": ["Excludes permits/inspections", "10% retainage, released at final"]
    }
  ]
}

该架构支持两种推荐方式:

  • 单一推荐:重叠度较高时,在 recommendations 中使用单个条目
  • 按范围推荐:各范围差异较大时,针对不同的 UniFormat 区域分别提出建议

overlap_comparison 对象展示共有类别中可进行同类比较的小计,并附注说明总额比较为何会产生误导。总额会造成错误印象时,请使用此对象。

范围重叠矩阵

scope_overlap 数组用于生成 PDF 第 1 页的比较表。应比 CSV 更细致地列出范围,以准确展示每位投标人包含或排除的项目。为每项标注 UniFormat 代码。尽力判断不同投标中的哪些行项目彼此等同。

推荐逻辑

范围不同的投标之间绝不要比较总额。 投标人承接的工作较少时,总价较低并不意味着价格更优。

第 1 步:识别重叠范围与非重叠范围

使用范围重叠矩阵,将各项划分为:

  • 重叠范围:两位投标方都包含的范围(可直接比较)
  • 投标方 A 独有:只有一位投标方涵盖的范围
  • 投标方 B 独有:只有另一位投标方涵盖的范围
第 2 步:仅比较重叠范围

计算每位投标方的仅重叠范围小计——仅对双方都涵盖的 UniFormat 类别的成本求和。比较投标方时应使用这个数字,而非总价。

示例:如果投标方 A 的屋面报价为 $110,250,而投标方 B 的屋面报价为 $35,000 + 外墙报价为 $93,333 + 排水报价为 $11,667,那么屋面范围的直接比较结果是 $110,250 对比 $35,000——尽管投标方 B 的总价更高,但其共同范围的报价低得多。

第 3 步:制定考虑范围差异的建议
  • 高度重叠(>70% 的项目相同):根据重叠范围成本对比、完整性和合同条款,提出单一建议
  • 部分重叠:适当时按范围分别提出建议(例如:“在屋面方面,投标方 B 的报价显著更低;投标方 A 不涵盖外墙或排水”)
  • 最低程度重叠(<30% 相同):不要建议选择其中一位投标方——说明两者范围差异过大,无法直接比较,并描述各自涵盖的内容
第 4 步:考虑独有范围

当一位投标方包含另一位未涵盖的范围时,明确指出:

  • 业主需要另行采购哪些内容?
  • 增加的范围是否值得更高的总价?
权重(针对重叠范围)
  1. 同范围价格对比——仅计算重叠类别的成本
  2. 范围完整性——额外覆盖范围可减少另行采购的需求
  3. 合同条款清晰度——条款明确、条件合理、保险充足

第 7 步:生成电子表格

CSV:

uv run scripts/generate_csv.py bid_data.json bid_level.csv

新建 Excel 文件:

uv run scripts/generate_csv.py bid_data.json bid_level.xlsx

向现有 Excel 文件添加工作表:

uv run scripts/generate_csv.py bid_data.json bid_level.xlsx existing_workbook.xlsx

输出格式根据文件扩展名自动识别。脚本会自动读取 references/uniformat_headings.csv。

第 8 步:生成 PDF

uv run scripts/generate_pdf.py analysis.json bid_level.pdf

PDF 结构如下:

  • 第 1 页:项目信息、建议、投标汇总表、带勾选标记的范围重叠矩阵
  • 第 2 页及后续页面:按投标方分别以简洁的项目符号列表列出详细信息(范围差异、进度安排、前提条件、完工情况、留置权豁免、资质、排除项)

资源

  • references/uniformat_headings.csv — 完整的 UniFormat II 第 1/2/3 级标题层级结构
  • references/bid-analysis-guide.md — 投标文件和合同条款的提取指南
  • scripts/generate_csv.py — 根据投标数据 JSON 生成电子表格(CSV 或 Excel)
  • scripts/generate_pdf.py — 根据分析 JSON 生成 PDF 报告

评论

支持 Markdown