bid-leveling

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Bid Leveling

投标找平

Compare construction bids by mapping line items to UniFormat II headings, producing a leveling spreadsheet and a concise analytical PDF report.
通过将分项条目映射至UniFormat II标题来对比建筑投标,生成找平电子表格和简洁的分析性PDF报告。

Single Document vs. Multiple Documents

单文档与多文档处理

This skill handles both single-bid analysis and multi-bid comparison. The workflow is the same either way, with these differences when only one document is provided:
  • Skip Step 3 (scope overlap assessment) — there is nothing to compare
  • No recommendation — omit
    recommendations
    and
    overlap_comparison
    from
    analysis.json
    entirely. The PDF will not render a Recommendation section.
  • No scope overlap matrix — omit
    scope_overlap
    from
    analysis.json
    . The PDF page 1 will show project info and the bid summary table only.
  • The spreadsheet and PDF are still produced — the spreadsheet shows the single bidder's costs broken down by UniFormat, and the PDF details the bid's contractual terms, scope, qualifications, and exclusions.
This is useful when the user wants to analyze a single proposal, extract its structure into UniFormat categories, and document its terms before additional bids come in.
本工具支持单投标分析和多投标对比两种场景。两种场景的工作流程基本一致,但仅提供一份文档时存在以下差异:
  • 跳过步骤3(范围重叠评估)—— 无可对比内容
  • 无推荐意见—— 在
    analysis.json
    中完全省略
    recommendations
    overlap_comparison
    字段,PDF报告也不会显示推荐章节
  • 无范围重叠矩阵—— 在
    analysis.json
    中省略
    scope_overlap
    字段,PDF第1页仅显示项目信息和投标摘要表格
  • 仍会生成电子表格和PDF—— 电子表格展示单个投标方按UniFormat分类的成本明细,PDF则详细说明该投标的合同条款、范围、资质和除外责任
当用户希望在收到更多投标前分析单个提案、将其结构提取至UniFormat分类并记录相关条款时,此模式非常实用。

Workflow

工作流程

  1. Collect project info and output format preference
  2. Read and extract data from each bid document
  3. Assess scope overlap and comparability (skip for single document)
  4. Determine unit of comparison
  5. Assign line items to UniFormat codes; decide granularity
  6. Build structured JSON data
  7. Generate spreadsheet (run
    generate_csv.py
    )
  8. Generate PDF (run
    generate_pdf.py
    )
  1. 收集项目信息和输出格式偏好
  2. 读取并提取每份投标文档的数据
  3. 评估范围重叠度和可比性*(单文档场景跳过此步骤)*
  4. 确定对比单位
  5. 将分项条目分配至UniFormat编码;确定粒度
  6. 构建结构化JSON数据
  7. 生成电子表格(运行
    generate_csv.py
  8. 生成PDF报告(运行
    generate_pdf.py

Step 1: Collect Project Info

步骤1:收集项目信息

Ask the user for:
  • Project name (e.g., "Smith Residence")
  • Brief description (e.g., "Custom home build", "Kitchen remodel", "Plumbing subcontract")
  • Output format: CSV or Excel?
If the user has already provided this information, skip the questions.
向用户询问以下信息:
  • 项目名称(例如:“史密斯住宅”)
  • 项目简要描述(例如:“定制住宅建造”“厨房翻新”“管道分包工程”)
  • 输出格式:CSV还是Excel?
如果用户已提供上述信息,则跳过询问。

Excel Context

Excel上下文处理

If the user is already working in an Excel document (they mention an
.xlsx
file, reference a spreadsheet, or are in a spreadsheet context), add the leveling data as a new sheet in their existing workbook instead of creating a new file. Pass the existing file as the third argument to
generate_csv.py
.
如果用户正在使用Excel文档(提及
.xlsx
文件、引用电子表格或处于电子表格操作场景),则将找平数据添加至现有工作簿的新工作表中,而非创建新文件。将现有文件作为第三个参数传递给
generate_csv.py

Step 2: Read Bid Documents

步骤2:读取投标文档

Read each provided bid document. For each document, extract:
  • Every identifiable cost line item (description + cost)
  • All contractual terms listed in
    references/bid-analysis-guide.md
Preserve exact wording from source documents when extracting terms.
读取每份提供的投标文档,为每份文档提取:
  • 所有可识别的成本分项条目(描述+成本)
  • references/bid-analysis-guide.md
    中列出的所有合同条款
提取条款时需保留源文档的原始措辞。

Handling Different File Formats

不同文件格式的处理方式

PDF (
.pdf
)
Read with the Read tool. For multi-page PDFs, read in page ranges (max 20 pages per request). Bids are often formatted as tables — pay close attention to column alignment when extracting line items. If the PDF contains scanned/image-based content rather than selectable text, treat it as an image (see below).
Image (
.png
,
.jpg
,
.heic
, etc.)
Read with the Read tool (multimodal). Extract all visible text, tables, and line items from the image. Images are common for photos of handwritten bids, screenshots of emails, or scanned documents. Take extra care with:
  • Handwritten numbers — confirm ambiguous digits (e.g., 1 vs 7, 5 vs 6) by cross-referencing totals
  • Partial visibility — if parts of the document are cut off, ask the user for the missing portions
  • Low resolution — flag any values you cannot read confidently
Excel (
.xlsx
,
.xls
,
.csv
)
Read with the Read tool. Spreadsheet bids often have the clearest structure — look for:
  • A schedule of values or line-item tab with description + cost columns
  • Summary/totals tabs or rows
  • Hidden sheets or columns that may contain additional detail
  • Named ranges or formulas that compute subtotals
If the bid is in an Excel file the user is actively working in, this is also an Excel context — see Step 1 for output handling.
Word (
.docx
,
.doc
)
Read with the Read tool. Word documents are common for formal proposals and contracts. Cost information may appear as:
  • Inline tables (schedule of values, cost breakdowns)
  • Paragraph text with embedded dollar amounts ("...for a total of $45,000...")
  • Appendices or exhibits attached at the end
For Word docs, also extract contractual language carefully — terms like exclusions, retainage, payment schedules, and insurance requirements are often embedded in the body text rather than in a structured table.
PDF(
.pdf
使用读取工具读取。对于多页PDF,按页面范围读取(每次请求最多20页)。投标文档通常以表格形式呈现——提取分项条目时需特别注意列对齐。如果PDF包含扫描/基于图像的内容而非可选文本,则将其视为图像处理(见下文)。
图像(
.png
,
.jpg
,
.heic
等)
使用多模态读取工具读取。从图像中提取所有可见文本、表格和分项条目。图像常用于手写投标的照片、电子邮件截图或扫描文档。需特别注意:
  • 手写数字——通过交叉核对总计金额确认模糊数字(例如:1与7、5与6)
  • 部分内容被截断——若文档部分内容缺失,向用户索要缺失部分
  • 低分辨率——标记所有无法自信读取的数值
Excel(
.xlsx
,
.xls
,
.csv
使用读取工具读取。电子表格形式的投标通常结构最清晰——需关注:
  • 价值明细表或包含描述+成本列的分项制表
  • 汇总/总计标签页或行
  • 可能包含额外细节的隐藏工作表或列
  • 用于计算小计的命名区域或公式
如果投标位于用户正在操作的Excel文件中,同样属于Excel上下文场景——请参考步骤1的输出处理方式。
Word(
.docx
,
.doc
使用读取工具读取。Word文档常用于正式提案和合同。成本信息可能以下列形式呈现:
  • 嵌入式表格(价值明细表、成本 breakdown)
  • 包含嵌入金额的段落文本(例如:“……总计45,000美元……”)
  • 附在文档末尾的附录或附件
对于Word文档,还需仔细提取合同语言——除外责任、保留金、付款计划和保险要求等条款通常嵌入正文中,而非结构化表格。

Step 3: Assess Scope Overlap

步骤3:评估范围重叠度

Before leveling, determine if the bids are comparable:
  • Do they cover the same trade or scope of work?
  • Do they share UniFormat Level 2 categories?
  • Are totals in a reasonable range relative to each other?
If bids have minimal overlap, report this prominently and explain why a direct comparison may be misleading. Still produce outputs with a clear caveat.
在进行找平前,需确定投标是否具有可比性:
  • 它们是否涵盖相同的工种或工作范围?
  • 它们是否共享UniFormat Level 2分类?
  • 总计金额是否处于合理的相对范围内?
如果投标的重叠度极低,需突出报告此情况并解释为何直接对比可能产生误导。仍需生成输出结果,但需附上明确的警告说明。

Line-Item Detail Mode

分项条目明细模式

When comparing bids with highly similar, itemized scopes (e.g., window schedules, appliance packages, panelized systems, fixture lists), check:
  • Do >60% of line items have per-unit pricing that can be compared directly?
  • Can equivalent items be matched across bids?
If yes, use
granularity: "line_items"
to break down to actual summarized line item descriptions for an apples-to-apples comparison. Build the
detail_rows
array (see Step 6) with best-effort matching of equivalent line items across bids. Only use this mode when items are truly comparable at the unit level.
当对比具有高度相似的分项范围的投标时(例如:窗户明细表、设备套餐、预制系统、固定装置清单),需检查:
  • 是否有超过60%的分项条目具备可直接对比的单位定价?
  • 能否在不同投标间匹配等价条目?
如果是,则使用
granularity: "line_items"
模式,分解为实际汇总的分项条目描述,进行一对一对比。在
detail_rows
数组(见步骤6)中尽可能匹配不同投标间的等价条目。仅当条目在单位层面真正具备可比性时,才使用此模式。

Step 4: Determine Unit of Comparison

步骤4:确定对比单位

Choose the most meaningful unit for per-unit cost comparison. Use the same unit across all line items in the output.
Scope typeUnitRationale
Plumbing, electrical, appliance quotes
$/fixture
Count of fixtures is the natural quantity
HVAC quotes
$/zone
Zones are the natural unit
Insulation, drywall, painting, flooring
$/SF
(scope area)
Area of the specific scope being quoted
Framing material purchases, mixed-unit material quotes
$/SF
(whole house)
No single unit; whole-house SF is the fallback
Whole-building / GC bids spanning many UniFormat categories
$/SF
(whole house)
Broad scope; house SF is appropriate
Window or door schedules
$/unit
Per-window or per-door
Roofing
$/square
(100 SF) or
$/SF
Roofing-specific unit
Rules:
  • Never use $/lump or $/lumpsum — this is not a meaningful comparison unit. There is always a better option.
  • Derive the unit and quantity from the bids themselves when possible
  • Default fallback is always
    $/SF
    (total construction square footage)
    — use this when no scope-specific unit can be determined
  • If the bids quote a specific scope area (e.g., "1,200 SF of tile"), use that area, not whole-house SF
  • The unit must be consistent across all rows in the output
Set
unit_of_comparison
in
bid_data.json
:
json
"unit_of_comparison": {"label": "$/fixture", "quantity": 14}
选择最有意义的单位进行单位成本对比。输出中所有分项条目需使用相同的单位
范围类型单位理由
管道、电气、设备报价
$/fixture
设备数量是自然计量单位
HVAC报价
$/zone
区域是自然计量单位
保温、石膏板、粉刷、地板
$/SF
(范围面积)
所报价特定范围的面积
框架材料采购、混合单位材料报价
$/SF
(整栋房屋)
无单一合适单位;整栋房屋面积作为 fallback
涵盖多个UniFormat分类的整栋建筑/总承包投标
$/SF
(整栋房屋)
范围广泛;房屋面积是合适的选择
窗户或门明细表
$/unit
按每扇窗户或门计算
屋顶工程
$/square
(100平方英尺)或
$/SF
屋顶工程专用单位
规则:
  • 切勿使用$/lump或$/lumpsum——这并非有意义的对比单位,总有更合适的选择
  • 尽可能从投标本身推导单位和数量
  • 默认 fallback 始终为
    $/SF
    (总建筑面积)
    ——当无法确定范围特定单位时使用此选项
  • 如果投标报价特定范围面积(例如:“1200平方英尺瓷砖”),使用该面积而非整栋房屋面积
  • 输出中所有行的单位必须保持一致
bid_data.json
中设置
unit_of_comparison
json
"unit_of_comparison": {"label": "$/fixture", "quantity": 14}

Step 5: Assign UniFormat Codes and Choose Granularity

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

Map each line item to a UniFormat Level 3 code using
references/uniformat_headings.csv
.
Rules:
  • Always assign the most specific Level 3 code (e.g.,
    D2010
    not
    D20
    ) — the script handles roll-up
  • If a line item spans categories, assign to the dominant one or split if amounts are clear
  • General conditions, overhead, profit, bonds, permits = UNCLASSIFIED (do not map)
使用
references/uniformat_headings.csv
将每个分项条目映射至UniFormat Level 3编码。
规则:
  • 始终分配最具体的Level 3编码(例如:
    D2010
    而非
    D20
    )——脚本会自动处理汇总
  • 如果分项条目跨多个分类,分配至主要分类;若金额明确,可拆分
  • 一般条件、管理费用、利润、保证金、许可证 = 未分类(不进行映射)

Choosing Output Granularity

选择输出粒度

Scope typeGranularityWhen
Single-trade subcontract
"level3"
Plumbing, electrical, HVAC — fine-grained comparison is valuable
Multi-trade or partial scope
"level2"
Kitchen remodel, TI — roll up to sub-group level
Whole-building / GC bids
"level2"
Ground-up build — L2 categories give a clear picture
Highly similar itemized quotes (>60% overlap)
"line_items"
Window schedules, appliance packages, fixture lists
范围类型粒度使用场景
单一工种分包
"level3"
管道、电气、HVAC——细粒度对比具有较高价值
多工种或部分范围
"level2"
厨房翻新、租户改善——汇总至子组层面
整栋建筑/总承包投标
"level2"
新建建筑——Level 2分类可清晰呈现整体情况
高度相似的分项报价(重叠度>60%)
"line_items"
窗户明细表、设备套餐、固定装置清单

Step 6: Build Structured JSON

步骤6:构建结构化JSON

Create two JSON files in the working directory.
在工作目录中创建两个JSON文件。

bid_data.json
(for spreadsheet generation)

bid_data.json
(用于生成电子表格)

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"
    , or
    "line_items"
  • unit_of_comparison
    :
    {"label": "$/fixture", "quantity": 14}
    — the label and divisor for per-unit cost
  • detail_rows
    : required only when
    granularity
    =
    "line_items"
    :
json
"detail_rows": [
  {
    "description": "36-inch farmhouse sink",
    "uniformat_code": "D2010",
    "costs": {"ABC Plumbing": 1200.00, "XYZ Plumbing": 1350.00}
  }
]
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"
    时需要:
json
"detail_rows": [
  {
    "description": "36-inch farmhouse sink",
    "uniformat_code": "D2010",
    "costs": {"ABC Plumbing": 1200.00, "XYZ Plumbing": 1350.00}
  }
]

analysis.json
(for PDF generation)

analysis.json
(用于生成PDF报告)

All detail fields are arrays of concise bullet strings, not paragraphs.
json
{
  "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"]
    }
  ]
}
The schema supports two recommendation styles:
  • Single recommendation: When overlap is high, use a single entry in
    recommendations
  • Per-scope recommendations: When scopes diverge, make separate recommendations per UniFormat area
The
overlap_comparison
object shows the apples-to-apples subtotals for shared categories and a note explaining why total comparison is misleading. Use this when grand totals would give a false impression.
所有明细字段均为简洁项目符号字符串数组,而非段落。
json
{
  "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"]
    }
  ]
}
该 schema 支持两种推荐意见格式:
  • 单一推荐意见:当重叠度较高时,在
    recommendations
    中使用单个条目
  • 按范围推荐:当范围存在差异时,针对每个UniFormat区域分别给出推荐意见
overlap_comparison
对象显示共享分类的一对一小计金额,并说明为何对比总计金额会产生误导。当总计金额会给出错误印象时使用此对象。

Scope Overlap Matrix

范围重叠矩阵

The
scope_overlap
array drives the PDF's page-1 comparison table. Enumerate scopes more granularly than the CSV to show exactly what each bidder includes/excludes. Tag each with a UniFormat code. Make a best effort to interpret which line items across bids are equivalent.
scope_overlap
数组驱动PDF第1页的对比表格。枚举范围时需比CSV更细粒度,以准确展示每个投标方包含/排除的内容。为每个范围标记UniFormat编码。尽最大努力解读不同投标间哪些分项条目是等价的。

Recommendation Logic

推荐意见逻辑

Never compare totals across bids with different scopes. A lower total does not mean a better price if the bidder covers less work.
切勿对比范围不同的投标的总计金额。如果投标方涵盖的工作内容更少,较低的总计金额并不意味着更优的价格。

Step 1: Identify overlapping vs. non-overlapping scope

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

Using the scope overlap matrix, separate line items into:
  • Overlapping: Both bidders include this scope (apples-to-apples)
  • Unique to Bidder A: Only one bidder covers this
  • Unique to Bidder B: Only the other bidder covers this
使用范围重叠矩阵,将分项条目分为:
  • 重叠范围:两个投标方均包含此范围(一对一对比)
  • 投标方A独有:仅一个投标方涵盖此范围
  • 投标方B独有:仅另一个投标方涵盖此范围

Step 2: Compare on overlapping scope only

步骤2:仅对比重叠范围

Compute an overlap-only subtotal for each bidder — the sum of costs for only the UniFormat categories both bidders cover. Compare bidders on this number, not on their grand totals.
Example: If Bidder A quotes roofing at $110,250 and Bidder B quotes roofing at $35,000 + exterior walls at $93,333 + drainage at $11,667, the apples-to-apples comparison for roofing is $110,250 vs. $35,000 — Bidder B is dramatically cheaper on the shared scope, even though their total is higher.
为每个投标方计算仅重叠范围的小计金额——即两个投标方均涵盖的UniFormat分类的成本总和。仅基于此金额对比投标方,而非其总计金额。
示例:如果投标方A的屋顶报价为110,250美元,投标方B的屋顶报价为35,000美元+外墙报价93,333美元+排水报价11,667美元,那么屋顶的一对一对比为110,250美元 vs 35,000美元——尽管投标方B的总计金额更高,但其在共享范围的价格显著更低。

Step 3: Make scope-aware recommendations

步骤3:给出基于范围的推荐意见

  • High overlap (>70% of line items shared): Make a single recommendation based on overlapping cost comparison, thoroughness, and contractual terms
  • Partial overlap: Make separate recommendations per scope area when appropriate (e.g., "For roofing, Bidder B is significantly cheaper; Bidder A does not cover exterior walls or drainage")
  • Minimal overlap (<30% shared): Do not recommend one bidder over the other — state that the scopes are too different to compare directly and describe what each covers
  • 高重叠度(>70%分项条目共享):基于重叠范围的成本对比、全面性和合同条款给出单一推荐意见
  • 部分重叠:适当时按范围区域分别给出推荐意见(例如:“对于屋顶工程,投标方B的价格显著更低;投标方A不涵盖外墙和排水工程”)
  • 低重叠度(<30%共享)不要推荐某一投标方优于另一投标方——说明范围差异过大无法直接对比,并描述每个投标方涵盖的内容

Step 4: Factor in unique scope

步骤4:考虑独有范围

When one bidder includes scope the other doesn't, call this out explicitly:
  • What would the owner need to procure separately?
  • Does the additional scope justify a higher total?
当一个投标方包含另一个投标方未涵盖的范围时,需明确指出:
  • 业主需要单独采购哪些内容?
  • 额外涵盖的范围是否能证明更高的总计金额合理?

Weights (for overlapping scope)

权重(针对重叠范围)

  1. Apples-to-apples price — cost for overlapping categories only
  2. Scope completeness — additional coverage reduces separate procurement
  3. Contractual clarity — clear terms, reasonable conditions, adequate insurance
  1. 一对一价格——仅重叠分类的成本
  2. 范围全面性——额外覆盖可减少单独采购需求
  3. 合同清晰度——条款清晰、条件合理、保险充足

Step 7: Generate Spreadsheet

步骤7:生成电子表格

CSV:
bash
uv run scripts/generate_csv.py bid_data.json bid_level.csv
New Excel file:
bash
uv run scripts/generate_csv.py bid_data.json bid_level.xlsx
Add sheet to existing Excel file:
bash
uv run scripts/generate_csv.py bid_data.json bid_level.xlsx existing_workbook.xlsx
Output format is detected from file extension. The script reads
references/uniformat_headings.csv
automatically.
CSV格式:
bash
uv run scripts/generate_csv.py bid_data.json bid_level.csv
新建Excel文件:
bash
uv run scripts/generate_csv.py bid_data.json bid_level.xlsx
添加至现有Excel文件:
bash
uv run scripts/generate_csv.py bid_data.json bid_level.xlsx existing_workbook.xlsx
输出格式由文件扩展名自动识别。脚本会自动读取
references/uniformat_headings.csv

Step 8: Generate PDF

步骤8:生成PDF报告

bash
uv run scripts/generate_pdf.py analysis.json bid_level.pdf
The PDF is structured as:
  • Page 1: Project info, recommendation, bid summary table, scope overlap matrix with checkmarks
  • Page 2+: Per-bidder details as concise bulleted lists (scope diffs, schedule, preconditions, completion, lien waivers, qualifications, exclusions)
bash
uv run scripts/generate_pdf.py analysis.json bid_level.pdf
PDF报告结构如下:
  • 第1页:项目信息、推荐意见、投标摘要表格、带勾选标记的范围重叠矩阵
  • 第2页及以后:每个投标方的详细信息,以简洁的项目符号列表呈现(范围差异、进度计划、前置条件、完工要求、留置权豁免要求、资质、除外责任)

Resources

资源

  • references/uniformat_headings.csv
    — Full UniFormat II Level 1/2/3 heading hierarchy
  • references/bid-analysis-guide.md
    — Extraction guide for bid documents and contractual terms
  • scripts/generate_csv.py
    — Spreadsheet generation (CSV or Excel) from bid data JSON
  • scripts/generate_pdf.py
    — PDF report generation from analysis JSON
  • references/uniformat_headings.csv
    ——完整的UniFormat II Level 1/2/3标题层级
  • references/bid-analysis-guide.md
    ——投标文档和合同条款提取指南
  • scripts/generate_csv.py
    ——从投标数据JSON生成电子表格(CSV或Excel格式)
  • scripts/generate_pdf.py
    ——从分析JSON生成PDF报告