bid-leveling
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBid 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 and
recommendationsfromoverlap_comparisonentirely. The PDF will not render a Recommendation section.analysis.json - No scope overlap matrix — omit from
scope_overlap. The PDF page 1 will show project info and the bid summary table only.analysis.json - 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字段,PDF报告也不会显示推荐章节overlap_comparison - 无范围重叠矩阵—— 在中省略
analysis.json字段,PDF第1页仅显示项目信息和投标摘要表格scope_overlap - 仍会生成电子表格和PDF—— 电子表格展示单个投标方按UniFormat分类的成本明细,PDF则详细说明该投标的合同条款、范围、资质和除外责任
当用户希望在收到更多投标前分析单个提案、将其结构提取至UniFormat分类并记录相关条款时,此模式非常实用。
Workflow
工作流程
- Collect project info and output format preference
- Read and extract data from each bid document
- Assess scope overlap and comparability (skip for single document)
- Determine unit of comparison
- Assign line items to UniFormat codes; decide granularity
- Build structured JSON data
- Generate spreadsheet (run )
generate_csv.py - Generate PDF (run )
generate_pdf.py
- 收集项目信息和输出格式偏好
- 读取并提取每份投标文档的数据
- 评估范围重叠度和可比性*(单文档场景跳过此步骤)*
- 确定对比单位
- 将分项条目分配至UniFormat编码;确定粒度
- 构建结构化JSON数据
- 生成电子表格(运行)
generate_csv.py - 生成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 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 .
.xlsxgenerate_csv.py如果用户正在使用Excel文档(提及文件、引用电子表格或处于电子表格操作场景),则将找平数据添加至现有工作簿的新工作表中,而非创建新文件。将现有文件作为第三个参数传递给。
.xlsxgenerate_csv.pyStep 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 ()
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).
.pdfImage (, , , 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:
.png.jpg.heic- 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 (, , )
Read with the Read tool. Spreadsheet bids often have the clearest structure — look for:
.xlsx.xls.csv- 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 (, )
Read with the Read tool. Word documents are common for formal proposals and contracts. Cost information may appear as:
.docx.doc- 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,按页面范围读取(每次请求最多20页)。投标文档通常以表格形式呈现——提取分项条目时需特别注意列对齐。如果PDF包含扫描/基于图像的内容而非可选文本,则将其视为图像处理(见下文)。
.pdf图像(, , 等)
使用多模态读取工具读取。从图像中提取所有可见文本、表格和分项条目。图像常用于手写投标的照片、电子邮件截图或扫描文档。需特别注意:
.png.jpg.heic- 手写数字——通过交叉核对总计金额确认模糊数字(例如:1与7、5与6)
- 部分内容被截断——若文档部分内容缺失,向用户索要缺失部分
- 低分辨率——标记所有无法自信读取的数值
Excel(, , )
使用读取工具读取。电子表格形式的投标通常结构最清晰——需关注:
.xlsx.xls.csv- 价值明细表或包含描述+成本列的分项制表
- 汇总/总计标签页或行
- 可能包含额外细节的隐藏工作表或列
- 用于计算小计的命名区域或公式
如果投标位于用户正在操作的Excel文件中,同样属于Excel上下文场景——请参考步骤1的输出处理方式。
Word(, )
使用读取工具读取。Word文档常用于正式提案和合同。成本信息可能以下列形式呈现:
.docx.doc- 嵌入式表格(价值明细表、成本 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 to break down to actual summarized line item descriptions for an apples-to-apples comparison. Build the 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.
granularity: "line_items"detail_rows当对比具有高度相似的分项范围的投标时(例如:窗户明细表、设备套餐、预制系统、固定装置清单),需检查:
- 是否有超过60%的分项条目具备可直接对比的单位定价?
- 能否在不同投标间匹配等价条目?
如果是,则使用模式,分解为实际汇总的分项条目描述,进行一对一对比。在数组(见步骤6)中尽可能匹配不同投标间的等价条目。仅当条目在单位层面真正具备可比性时,才使用此模式。
granularity: "line_items"detail_rowsStep 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 type | Unit | Rationale |
|---|---|---|
| Plumbing, electrical, appliance quotes | | Count of fixtures is the natural quantity |
| HVAC quotes | | Zones are the natural unit |
| Insulation, drywall, painting, flooring | | Area of the specific scope being quoted |
| Framing material purchases, mixed-unit material quotes | | No single unit; whole-house SF is the fallback |
| Whole-building / GC bids spanning many UniFormat categories | | Broad scope; house SF is appropriate |
| Window or door schedules | | Per-window or per-door |
| Roofing | | 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 (total construction square footage) — use this when no scope-specific unit can be determined
$/SF - 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 in :
unit_of_comparisonbid_data.jsonjson
"unit_of_comparison": {"label": "$/fixture", "quantity": 14}选择最有意义的单位进行单位成本对比。输出中所有分项条目需使用相同的单位。
| 范围类型 | 单位 | 理由 |
|---|---|---|
| 管道、电气、设备报价 | | 设备数量是自然计量单位 |
| HVAC报价 | | 区域是自然计量单位 |
| 保温、石膏板、粉刷、地板 | | 所报价特定范围的面积 |
| 框架材料采购、混合单位材料报价 | | 无单一合适单位;整栋房屋面积作为 fallback |
| 涵盖多个UniFormat分类的整栋建筑/总承包投标 | | 范围广泛;房屋面积是合适的选择 |
| 窗户或门明细表 | | 按每扇窗户或门计算 |
| 屋顶工程 | | 屋顶工程专用单位 |
规则:
- 切勿使用$/lump或$/lumpsum——这并非有意义的对比单位,总有更合适的选择
- 尽可能从投标本身推导单位和数量
- 默认 fallback 始终为(总建筑面积)——当无法确定范围特定单位时使用此选项
$/SF - 如果投标报价特定范围面积(例如:“1200平方英尺瓷砖”),使用该面积而非整栋房屋面积
- 输出中所有行的单位必须保持一致
在中设置:
bid_data.jsonunit_of_comparisonjson
"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.csvRules:
- Always assign the most specific Level 3 code (e.g., not
D2010) — the script handles roll-upD20 - 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)
使用将每个分项条目映射至UniFormat Level 3编码。
references/uniformat_headings.csv规则:
- 始终分配最具体的Level 3编码(例如:而非
D2010)——脚本会自动处理汇总D20 - 如果分项条目跨多个分类,分配至主要分类;若金额明确,可拆分
- 一般条件、管理费用、利润、保证金、许可证 = 未分类(不进行映射)
Choosing Output Granularity
选择输出粒度
| Scope type | Granularity | When |
|---|---|---|
| Single-trade subcontract | | Plumbing, electrical, HVAC — fine-grained comparison is valuable |
| Multi-trade or partial scope | | Kitchen remodel, TI — roll up to sub-group level |
| Whole-building / GC bids | | Ground-up build — L2 categories give a clear picture |
| Highly similar itemized quotes (>60% overlap) | | Window schedules, appliance packages, fixture lists |
| 范围类型 | 粒度 | 使用场景 |
|---|---|---|
| 单一工种分包 | | 管道、电气、HVAC——细粒度对比具有较高价值 |
| 多工种或部分范围 | | 厨房翻新、租户改善——汇总至子组层面 |
| 整栋建筑/总承包投标 | | 新建建筑——Level 2分类可清晰呈现整体情况 |
| 高度相似的分项报价(重叠度>60%) | | 窗户明细表、设备套餐、固定装置清单 |
Step 6: Build Structured JSON
步骤6:构建结构化JSON
Create two JSON files in the working directory.
在工作目录中创建两个JSON文件。
bid_data.json
(for spreadsheet generation)
bid_data.jsonbid_data.json
(用于生成电子表格)
bid_data.jsonjson
{
"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", or"level3""line_items" - :
unit_of_comparison— the label and divisor for per-unit cost{"label": "$/fixture", "quantity": 14} - : required only when
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}
}
]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.jsonanalysis.json
(用于生成PDF报告)
analysis.jsonAll 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 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.
overlap_comparison所有明细字段均为简洁项目符号字符串数组,而非段落。
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_comparisonScope Overlap Matrix
范围重叠矩阵
The 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_overlapscope_overlapRecommendation 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)
权重(针对重叠范围)
- Apples-to-apples price — cost for overlapping categories only
- Scope completeness — additional coverage reduces separate procurement
- Contractual clarity — clear terms, reasonable conditions, adequate insurance
- 一对一价格——仅重叠分类的成本
- 范围全面性——额外覆盖可减少单独采购需求
- 合同清晰度——条款清晰、条件合理、保险充足
Step 7: Generate Spreadsheet
步骤7:生成电子表格
CSV:
bash
uv run scripts/generate_csv.py bid_data.json bid_level.csvNew Excel file:
bash
uv run scripts/generate_csv.py bid_data.json bid_level.xlsxAdd sheet to existing Excel file:
bash
uv run scripts/generate_csv.py bid_data.json bid_level.xlsx existing_workbook.xlsxOutput format is detected from file extension. The script reads automatically.
references/uniformat_headings.csvCSV格式:
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.csvStep 8: Generate PDF
步骤8:生成PDF报告
bash
uv run scripts/generate_pdf.py analysis.json bid_level.pdfThe 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.pdfPDF报告结构如下:
- 第1页:项目信息、推荐意见、投标摘要表格、带勾选标记的范围重叠矩阵
- 第2页及以后:每个投标方的详细信息,以简洁的项目符号列表呈现(范围差异、进度计划、前置条件、完工要求、留置权豁免要求、资质、除外责任)
Resources
资源
- — Full UniFormat II Level 1/2/3 heading hierarchy
references/uniformat_headings.csv - — Extraction guide for bid documents and contractual terms
references/bid-analysis-guide.md - — Spreadsheet generation (CSV or Excel) from bid data JSON
scripts/generate_csv.py - — PDF report generation from analysis JSON
scripts/generate_pdf.py
- ——完整的UniFormat II Level 1/2/3标题层级
references/uniformat_headings.csv - ——投标文档和合同条款提取指南
references/bid-analysis-guide.md - ——从投标数据JSON生成电子表格(CSV或Excel格式)
scripts/generate_csv.py - ——从分析JSON生成PDF报告
scripts/generate_pdf.py