Bối cảnh: X.aladDin.vn — công cụ trợ lý môi giới thi công xây dựng
Yêu cầu Diamond (21 năm KN): “Phải ước tính bằng nhiều phương pháp rồi tổng hợp lại để giảm thiểu sai số”
| Hạng mục | Phạm vi | Ghi chú |
|---|---|---|
| Xây mới Hà Nội | 15tr/m² sàn (phổ thông) × 1.2 (khá) × 1.5 (cao cấp) | Đơn giá cơ sở |
| Hệ số cấu trúc | Mái tôn 0.85, Bê tông 1.10, Thái 1.25 | Nhân vào đơn giá cơ sở |
| Hệ số móng | Băng 1.0, Đơn giản 0.85, Cọc 1.25 | Nhân vào đơn giá cơ sở |
| Sửa chữa | Nhẹ 2.5tr/m², Vừa 5tr/m², Lớn 9tr/m² | Theo m² sàn |
| Dự phòng | 12% (xây mới), 25% (sửa cũ) | % giá trị thi công |
| Thiết kế KTS | 200k–450k/m² sàn | Phổ thông → Cao cấp |
| Xin phép | 15tr–100tr | Tùy loại giấy phép |
| Giám sát | 3–8% giá trị TH | % giá trị thi công |
| Nội thất | 2tr–8tr/m² sàn | Phổ thông → Cao cấp |
| Phá dỡ | 30tr–50tr | Gói trọn |
| Hạ tầng | 30tr–50tr | Điện/nước/kết nối |
| # | Phương pháp | Tên VN | Tên EN | Cốt lõi |
|---|---|---|---|---|
| 1 | Đơn giá/m² sàn | Đơn giá sàn | Unit Rate per m² | Đơn giá cơ sở × hệ số × diện tích |
| 2 | Phân tích tỷ trọng | Tỷ trọng hạng mục | Elemental Cost Analysis | Chia %: Thô / Hoàn thiện / M&E / Thiết kế / Phép / Dự phòng |
| 3 | So sánh benchmark | Công trình tương tự | Comparative / Benchmarking | Tra cứu DB công trình đã thi công gần nhất |
| 4 | Bottom-up (BOQ) | Phân tích từng hạng mục | Bottom-up / Bill of Quantities | Vật tư + Nhân công + Máy thi công từng hạng mục |
| 5 | Parametric / Regression | Tham số / Hồi quy | Parametric Estimation | Mô hình toán: Chi phí = f(diện tích, tầng, cấu trúc, vị trí, v.v.) |
| Tiêu chí | 1. Đơn giá/m² | 2. Tỷ trọng | 3. Benchmark | 4. Bottom-up (BOQ) | 5. Parametric |
|---|---|---|---|---|---|
| Độ chính xác | ±25–35% | ±15–25% | ±20–30% | ±5–15% | ±10–20% |
| Dữ liệu đầu vào | Diện tích, loại hình, cấp độ | Diện tích + % tỷ trọng chuẩn | DB ≥20 công trình tương tự | Bản vẽ KTS + CTKT + vật liệu | Dữ liệu lịch sử đa biến |
| Thời gian tính | <1 giây (client) | <1 giây (client) | 1–5 giây (cần DB) | 30–120 phút (cần BOQ) | <1 giây (model trained) |
| Khi nào dùng | Giai đoạn ý tưởng, khái quát | Giai đoạn tiền thiết kế | Có DB công trình gần | Có bản vẽ kỹ thuật chi tiết | Đã có ≥100 mẫu train |
| Sai số phổ biến | Bỏ qua: phép, thiết kế, GTGT, lạm phát, rủi ro địa chất | Tỷ trọng cố định ≠ thực tế từng dự án | Công trình tham chiếu khác vị trí/thời gian | Sai số đo lượng, giá vật liệu biến động | Overfitting, thiếu biến môi trường |
| Chi phí triển khai | 0 (đã có) | Thấp (logic % cố định) | Trung (cần crawl DB) | Cao (cần BOQ tool, vật liệu API) | Cao (ML pipeline, retrain) |
Sai số giảm khi nhiều phương pháp độc lập hội tụ (Wisdom of Crowds). Nếu 3 phương pháp cho 520, 590, 680 → khoảng 520–680 tr có ý nghĩa hơn bất kỳ số đơn lẻ nào.
| Giai đoạn | Phương pháp 1 (m²) | Phương pháp 2 (Tỷ trọng) | Phương pháp 3 (Benchmark) | Phương pháp 4 (BOQ) | Phương pháp 5 (Parametric) |
|---|---|---|---|---|---|
| Ý tưởng / Khảo sát | 0.40 | 0.30 | 0.20 | 0.00 | 0.10 |
| Tiền thiết kế | 0.25 | 0.35 | 0.25 | 0.00 | 0.15 |
| Kỹ thuật / Xin phép | 0.15 | 0.30 | 0.20 | 0.25 | 0.10 |
| Chuẩn bị thi công | 0.10 | 0.20 | 0.10 | 0.50 | 0.10 |
Trọng số điều chỉnh động: Nếu có bản vẽ KTS → tăng BOQ. Nếu có DB benchmark tốt → tăng Benchmark. Nếu chỉ có diện tích → lệch về m² + Tỷ trọng.
# Pseudocode
estimates = {
"unit_rate": calc_unit_rate(area, type, grade, struct_coef, foundation_coef),
"elemental": calc_elemental(area, type, grade), # % thô/hoàn thiện/MEP/...
"benchmark": query_benchmark_db(area, location, type, grade), # median ± IQR
"boq": calc_boq(drawings) if drawings else None,
"parametric": ml_predict(features) if model_ready else None
}
# Loại None
valid = {k:v for k,v in estimates.items() if v is not None}
# Weighted median (robust hơn mean)
weights = get_weights(project_stage)
weighted_values = []
for method, value in valid.items():
weighted_values.extend([value] * int(weights[method] * 100))
# Kết quả
median_est = median(weighted_values)
p10, p90 = percentile(weighted_values, 10), percentile(weighted_values, 90)
output = f"Ước tính: {p10:,.0f}–{p90:,.0f} triệu (median: {median_est:,.0f} triệu)"
detail = ", ".join([f"{k}: {v:,.0f}tr" for k,v in valid.items()])
┌─────────────────────────────────────────────────────────────┐
│ ƯỚC TÍNH CHI PHÍ TỔNG HỢP │
├─────────────────────────────────────────────────────────────┤
│ Khoảng tin cậy 80%: 520 – 780 triệu VNĐ │
│ Giá trị trung vị: 640 triệu VNĐ │
├─────────────────────────────────────────────────────────────┤
│ Chi tiết từng phương pháp: │
│ • Đơn giá/m² sàn: 580 triệu │
│ • Tỷ trọng hạng mục: 620 triệu │
│ • Benchmark (3 CT gần): 650 triệu │
│ • Bottom-up (BOQ): 710 triệu ← có bản vẽ │
│ • Parametric (ML): 590 triệu │
├─────────────────────────────────────────────────────────────┤
│ ⚠️ Lưu ý: Sai số thực tế ±15–20%. Chưa bao gồm: GTGT 10%, │
│ lạm phát năm thi công, rủi ro địa chất, thay đổi thiết kế. │
└─────────────────────────────────────────────────────────────┘
| Phương pháp | Chạy client-side (JS) | Cần Server/AI | Lý do |
|---|---|---|---|
| 1. Đơn giá/m² | ✅ Đã có | ❌ | Toán học đơn thuần, 0 token |
| 2. Tỷ trọng | ✅ Dễ thêm | ❌ | Chỉ cần bảng % cố định + logic nhân |
| 3. Benchmark | ❌ | ✅ Cần API/DB | Cần DB ≥200 công trình, search fuzzy |
| 4. Bottom-up | ❌ | ✅ Cần BOQ Engine | Cần parse bản vẽ, giá vật liệu real-time |
| 5. Parametric | ❌ | ✅ Cần ML Model | Cần model trained, feature engineering |
| Phase | Mục tiêu | Phương pháp kích hoạt | Công nghệ | Thời gian |
|---|---|---|---|---|
| Phase 1 (Tuần 1-2) | Ensemble client-side cơ bản | 1 + 2 | React + TypeScript, 0 backend | 2 tuần |
| Phase 2 (Tuần 3-6) | Benchmark API + Cache | 1 + 2 + 3 | Supabase/PostgreSQL + Edge Function | 4 tuần |
| Phase 3 (Tuần 7-12) | BOQ Lite + Parametric MVP | 1-5 (full) | Python/FastAPI + ONNX model + vector DB | 6 tuần |
Input component mở rộng:
// Thêm vào form hiện tại
interface ExtendedInput {
// Hiện có
area: number; // m² sàn
type: 'new' | 'renovate';
grade: 'basic' | 'standard' | 'premium';
structure: 'steel' | 'concrete' | 'thai';
foundation: 'strip' | 'simple' | 'pile';
// Mới bổ sung
floors: number; // Số tầng
hasDesign: boolean; // Đã có bản vẽ KTS?
designTier: 'basic' | 'standard' | 'premium';
needPermit: boolean; // Cần xin phép?
permitType: 'simple' | 'full';
needSupervision: boolean; // Có giám sát?
supervisionTier: 'basic' | 'full';
fitoutTier: 'none' | 'basic' | 'standard' | 'premium';
hasDemolition: boolean; // Có phá dỡ?
infraScope: 'none' | 'basic' | 'full';
location: 'hanoi' | 'hcmc' | 'other'; // để benchmark
}
Logic tính client-side (Pure TS, 0 token):
// /src/lib/estimation/ensemble-client.ts
const ELEMENTAL_RATIOS = {
new: {
basic: { shell: 0.45, finishing: 0.30, mep: 0.15, design: 0.03, permit: 0.02, contingency: 0.12 },
standard: { shell: 0.42, finishing: 0.33, mep: 0.15, design: 0.03, permit: 0.02, contingency: 0.12 },
premium: { shell: 0.38, finishing: 0.38, mep: 0.15, design: 0.04, permit: 0.02, contingency: 0.12 },
},
renovate: {
light: { shell: 0.30, finishing: 0.40, mep: 0.15, design: 0.05, permit: 0.00, contingency: 0.25 },
medium: { shell: 0.35, finishing: 0.35, mep: 0.15, design: 0.05, permit: 0.00, contingency: 0.25 },
heavy: { shell: 0.40, finishing: 0.30, mep: 0.15, design: 0.05, permit: 0.00, contingency: 0.25 },
}
};
const FIXED_COSTS = {
design: { basic: 200, standard: 325, premium: 450 }, // k VNĐ/m²
permit: { simple: 15, full: 100 }, // triệu VNĐ
supervision: { basic: 0.03, full: 0.08 }, // % construction value
fitout: { none: 0, basic: 2, standard: 5, premium: 8 }, // triệu/m²
demolition: 40, // triệu (mid)
infrastructure: 40, // triệu (mid)
};
function estimateUnitRate(input: ExtendedInput): number {
// Logic hiện tại của X.aladDin.vn
let base = 15; // tr/m²
if (input.grade === 'standard') base *= 1.2;
if (input.grade === 'premium') base *= 1.5;
if (input.structure === 'concrete') base *= 1.10;
if (input.structure === 'thai') base *= 1.25;
if (input.foundation === 'simple') base *= 0.85;
if (input.foundation === 'pile') base *= 1.25;
return base * input.area;
}
function estimateElemental(input: ExtendedInput): number {
const ratios = input.type === 'new'
? ELEMENTAL_RATIOS.new[input.grade]
: ELEMENTAL_RATIOS.renovate[input.grade === 'basic' ? 'light' : input.grade === 'standard' ? 'medium' : 'heavy'];
const construction = estimateUnitRate(input);
let total = construction;
// Thiết kế
total += FIXED_COSTS.design[input.designTier] * input.area / 1000; // tr
// Phép
if (input.needPermit) total += FIXED_COSTS.permit[input.permitType];
// Giám sát
if (input.needSupervision) total += construction * FIXED_COSTS.supervision[input.supervisionTier];
// Nội thất
total += FIXED_COSTS.fitout[input.fitoutTier] * input.area;
// Phá dỡ
if (input.hasDemolition) total += FIXED_COSTS.demolition;
// Hạ tầng
if (input.infraScope !== 'none') total += FIXED_COSTS.infrastructure;
// Dự phòng (đã có trong ratios nhưng tính riêng cho các chi phí thêm)
const extraCosts = total - construction;
total += extraCosts * ratios.contingency;
return total;
}
function ensembleClient(input: ExtendedInput): EnsembleResult {
const method1 = estimateUnitRate(input);
const method2 = estimateElemental(input);
// Method 3,4,5 = null ở client
const valid = { "Đơn giá/m²": method1, "Tỷ trọng hạng mục": method2 };
const values = Object.values(valid);
// Weighted median với trọng số phase 1
const weights = { "Đơn giá/m²": 0.4, "Tỷ trọng hạng mục": 0.6 };
const weighted = [];
for (const [method, val] of Object.entries(valid)) {
const count = Math.round(weights[method] * 100);
for (let i = 0; i < count; i++) weighted.push(val);
}
weighted.sort((a,b) => a-b);
const median = weighted[Math.floor(weighted.length/2)];
const p10 = weighted[Math.floor(weighted.length * 0.1)];
const p90 = weighted[Math.floor(weighted.length * 0.9)];
return {
range: { min: p10, max: p90, median },
breakdown: valid,
confidence: 0.65, // Chỉ 2 phương pháp
methodsUsed: Object.keys(valid),
note: "Chưa có benchmark/BOQ/ML. Sai số ước lượng ±25-30%."
};
}
| Hành động | Ưu tiên | Người làm | Thời gian |
|---|---|---|---|
| 1. Mở rộng form input (thêm 10 field mới) | 🔴 CAO | @coder | 2h |
2. Viết ensemble-client.ts logic 2 phương pháp |
🔴 CAO | @coder | 3h |
| 3. Cập nhật UI hiển thị range + breakdown | 🔴 CAO | @coder | 2h |
| 4. Test với 5 case thực tế Diamond cho | 🟡 TRUNG BÌNH | @reasoner + Diamond | 1h |
| 5. Thiết kế schema Benchmark DB (phase 2) | 🟢 THẤP | @architect | 1 ngày |
“Khách hàng môi giới chỉ cần khoảng tin cậy để báo giá nhanh. Không cần chính xác 100% — cần ít sai hơn đối thủ. Hiện tại đối thủ chỉ báo 1 con số. Chúng ta báo khoảng + giải thích sai số → khác biệt cạnh tranh.”
“Phase 1 làm xong ngay hôm nay. Phase 2 crawl data từ các trang thầu, sàn BĐS, hồ sơ công trình công khai. Phase 3 sau khi có ≥200 mẫu train parametric.”
Tài liệu tạo bởi @reasoner — Reasoning Specialist
Phiên bản: 1.0 | Ngày: 2026-09-03