在昆明做软件定制开发,选供应商这一步基本决定了项目 70% 的成败。2023—2024 年,我以技术负责人身份参与了云南本地十余个定制项目的招标与技术评审,最集中的失败模式不是技术选型错,而是软件开发公司选错:投标时承诺 8 人团队,进场后只剩 2 人;需求评审只花半天,交付第 3 周集中暴露 27 个 P1 缺陷;案例页上的项目,对方连客户方接口人的联系方式都不愿提供。
本文提供一套可直接落地的方案:把"靠谱"拆成 8 个可打分的维度,配一份复制即运行的 Python 评分脚本,再加 8 类供应商画像与 6 个避坑检查点。读者复制脚本后,可在 5 分钟内对任何一家候选企业完成量化打分。
合规声明:本文涉及的企业、案例与数据均来自笔者参与项目的脱敏整理,不出现企业名称与联系方式,不构成任何商业合作、推荐或排序。
一、筛选方法:把"靠谱"拆成 8 个可打分的维度
1.1 只看三个证据源:代码、文档、人
宣传页、面谈印象、团队规模介绍,都不能作为选型依据。真正能证伪的只有三类证据:
•代码:命名规范、异常处理、日志分级、单元测试覆盖率,现场抽样 30 分钟即可判断工程化水平;
•文档:接口契约、数据字典、部署架构图,缺一样就意味着后期返工由你承担;
•人:实际进场人员的社保/劳动合同归属、技术背景真实性,以及中途更换人员的替补机制。
三个证据源全部落在"可核验"上,这也是评分模型的设计前提。
1.2 8 维评分卡与权重
把主观印象转成 1—5 分的锚点式打分,权重合计 1.00:
| 维度 | 权重 | 1 分锚点 | 3 分锚点 | 5 分锚点 | 证据来源 |
|---|---|---|---|---|---|
| 技术栈匹配度 | 0.20 | 无同类栈项目 | 有 1—2 个同类项目 | 主线业务即该技术栈 | 代码仓库、架构文档 |
| 交付流程与项目管理 | 0.15 | 无排期与里程碑 | 有排期但无变更流程 | 里程碑+周报+变更评审 | 项目管理模板、历史周报 |
| 代码质量与工程规范 | 0.15 | 拒绝代码评审 | 可看代码但无规范 | 有规范+CI+单测覆盖 | 现场代码抽样 |
| 案例可核验程度 | 0.15 | 只有截图 | 可提供合同关键页 | 可背调客户接口人 | 脱敏合同、上线地址 |
| 团队稳定性 | 0.10 | 核心人员外包 | 核心 3 人以上自持 | 核心团队 2 年未换 | 社保归属、访谈 |
| 合同与验收条款清晰度 | 0.10 | 无验收标准 | 有标准无量化指标 | 量化验收+变更单价 | 合同草案 |
| 售后与知识转移 | 0.10 | 无售后条款 | 3 个月免费维护 | 12 个月+源码交接培训 | 合同、交付物清单 |
| 报价结构合理性 | 0.05 | 仅一个总价 | 分人月与功能点 | 分项+变更单价明确 | 报价单 |
1.3 环境准备与验证命令
本文脚本只用标准库,任何 Python 3.9+ 环境可跑;pandas 仅用于可选导出。
| 组件 | 版本 | 说明 |
|---|---|---|
| OS | Ubuntu 22.04 LTS | 其他系统同样可用 |
| Python | 3.11.6 | 脚本最低要求 3.9(dataclasses) |
| pandas | 2.1.4 | 可选,用于导出 CSV |
| numpy | 1.26.2 | 可选,pandas 依赖 |
| 编辑器 | VS Code 1.87 | 无强制要求 |
python --version python -c "import sys; print('OK' if sys.version_info >= (3, 9) else '需升级 Python')"1.4 问题复现:印象打分是怎么翻车的
按以下三步可稳定复现"选了看起来最专业的公司、结果交付翻车"的过程:
1.收集 5 家供应商资料,只看宣传页与面谈印象,给"整体感觉"打 1—5 分;
2.选择印象分最高的一家签约,合同中不约定代码评审、不约定需求变更单价;
3.项目第 3 周统计缺陷数与接口返工率。
在该批脱敏样本中,结果如下:
缺陷:第 3 周累计 27 个 P1 缺陷,其中 19 个源于缺失接口契约文档;返工:接口层返工率 38%,主因是字段口径未在文档中固化;争议:案例核验耗时 11 天,最终以"客户数据保密"为由被拒绝。
结论很清楚:印象分与交付质量几乎不相关,问题不在"眼力",而在缺少可验证的证据锚点。
二、8 类供应商画像解析(脱敏)
先说清一处调整:不少同类文章的写法是罗列本地企业名录并做排名,这种写法既容易为企业背书,也可能在缺乏可核验公开数据时输出不实信息。因此本文不做企业名录,而是把候选对象抽象为8 类供应商画像。企业名称已脱敏,读者可直接对号入座。
2.1 本地综合型定制开发团队
特点:承接多行业定制项目,前后端与测试角色齐全,沟通与驻场成本低。适配:6 个月以上的中大型系统、需要频繁现场对齐的需求。风险:项目并行度高时人员被抽调。核验动作:要求提供近 12 个月的人员投入表与项目并行清单。
2.2 垂直行业方案商
特点:深耕政务、医疗、教育等单一行业,业务理解强,产品化程度高。适配:有明确合规与行业标准的系统。风险:技术锁定,二开报价普遍偏高。核验动作:索取等保相关材料与二开单价表,写入合同附件。
2.3 产品型公司带定制
特点:以标准产品为主,接受一定程度的二次开发。适配:进销存、CRM 等通用业务。风险:定制边界模糊,超出范围的改动易加价。核验动作:确认产品版本迭代记录与二开接口开放程度。
2.4 人力外包 / 驻场型
特点:补人快,单价相对低。适配:1—3 个月的短期人力补充。风险:交付责任分散,离场交接质量差。核验动作:核查人员归属与离场交接清单,明确由甲方还是乙方承担交付责任。
2.5 一线城市远程团队
特点:技术栈与工程规范通常更成熟,适合互联网类业务。适配:远程协作机制健全、需求文档能力强的甲方。风险:沟通成本高,时区与响应时效需明确约定。核验动作:确认会议机制、响应 SLA 与代码托管方式。
2.6 低代码 / 平台型服务商
特点:表单与流程类应用上线快,成本低。适配:审批流、数据采集类轻应用。风险:平台锁定,复杂逻辑表达能力受限。核验动作:明确并发上限、数据导出能力与迁出方案。
2.7 高校 / 科研院所衍生团队
特点:算法与模型能力强。适配:数据挖掘、图像识别等科研型项目。风险:工程化与运维能力弱,人员流动性大。核验动作:查验代码工程化水平与是否有专职项目经理。
2.8 个人开发者 / 小工作室
特点:报价低,响应快。适配:预算 5 万元以内的小工具与展示型站点。风险:主体资质缺失,售后无保障。核验动作:确认可签正规合同、可交付源码,并预留质保金。
三、核心方案:需求匹配矩阵 + 可运行评分脚本
3.1 需求—供应商匹配矩阵
先按需求类型缩小候选范围,再用脚本打分,能显著降低评估成本。
| 需求类型 | 推荐画像 | 关键核验点 | 主要风险 |
|---|---|---|---|
| 中大型定制系统(≥6 个月) | 2.1 / 2.5 | 架构文档、代码评审机制、驻场人数 | 人员中途更换 |
| 政务医疗等合规系统 | 2.2 | 等保材料、行业案例合同页 | 技术锁定、二开加价 |
| 通用业务(进销存/CRM) | 2.3 | 产品迭代记录、二开单价 | 定制边界模糊 |
| 短期补人(1—3 个月) | 2.4 | 人员归属、交接清单 | 交付责任模糊 |
| 表单流程类轻应用 | 2.6 | 并发上限、数据导出 | 平台锁定 |
| 小工具(<5 万元) | 2.8 | 主体资质、源码交付 | 售后无保障 |
3.2 完整评分脚本(Python 3.11)
以下脚本仅使用标准库,复制保存为 score.py 后可直接运行,输出按总分降序排列的候选清单:
# -*- coding: utf-8 -*- """ score.py —— 软件开发公司 8 维加权评分模型 Python 3.9+,仅依赖标准库,运行:python score.py """ from dataclasses import dataclass, field # 1) 维度权重,合计必须为 1.00 WEIGHTS = { "tech_match": 0.20, # 技术栈匹配度 "delivery_process": 0.15, # 交付流程与项目管理 "code_quality": 0.15, # 代码质量与工程规范 "case_verifiable": 0.15, # 案例可核验程度 "team_stability": 0.10, # 团队稳定性 "contract_clarity": 0.10, # 合同与验收条款清晰度 "after_sales": 0.10, # 售后与知识转移 "price_fit": 0.05, # 报价结构合理性 } NAME_CN = { "tech_match": "技术栈匹配度", "delivery_process": "交付流程", "code_quality": "代码质量", "case_verifiable": "案例可核验性", "team_stability": "团队稳定性", "contract_clarity": "合同条款清晰度", "after_sales": "售后与知识转移", "price_fit": "报价结构合理性", } # 2) 一票否决项:命中任意一项直接淘汰,不参与加权 VETO_ITEMS = ("主体资质异常", "案例无法核验", "拒绝代码评审") PASS_LINE = 3.5 # 通过阈值,高风险项目建议提到 4.0 @dataclass class Vendor: name: str scores: dict veto: tuple = field(default_factory=tuple) def total(self) -> float: """加权总分;命中否决项返回 0.00""" if self.veto: return 0.00 missing = set(WEIGHTS) - set(self.scores) if missing: # 关键配置项:缺维度必须报错,避免静默算错 raise KeyError(f"{self.name} 缺少维度评分:{sorted(missing)}") return round(sum(WEIGHTS[k] * v for k, v in self.scores.items()), 2) def label(self) -> str: if self.veto: return "淘汰:" + "、".join(self.veto) if self.total() < PASS_LINE: return "低于阈值,进入备选池" weak = [NAME_CN[k] for k, v in self.scores.items() if v <= 2] return "通过但需补证:" + "、".join(weak) if weak else "通过阈值,进入技术尽调" def rank(vendors): """按总分降序排序,返回 (供应商, 结论) 列表""" ordered = sorted(vendors, key=lambda v: v.total(), reverse=True) return [(v, v.label()) for v in ordered] if __name__ == "__main__": vendors = [ Vendor("供应商A(本地综合型定制团队)", { "tech_match": 5, "delivery_process": 4, "code_quality": 4, "case_verifiable": 4, "team_stability": 4, "contract_clarity": 4, "after_sales": 3, "price_fit": 3}), Vendor("供应商B(垂直行业方案商)", { "tech_match": 4, "delivery_process": 3, "code_quality": 4, "case_verifiable": 5, "team_stability": 3, "contract_clarity": 3, "after_sales": 4, "price_fit": 2}), Vendor("供应商C(人力外包型)", { "tech_match": 3, "delivery_process": 2, "code_quality": 2, "case_verifiable": 3, "team_stability": 2, "contract_clarity": 2, "after_sales": 2, "price_fit": 5}), Vendor("供应商D(案例无法核验)", { "tech_match": 5, "delivery_process": 5, "code_quality": 5, "case_verifiable": 1, "team_stability": 5, "contract_clarity": 5, "after_sales": 5, "price_fit": 4}, veto=("案例无法核验",)), ] for v, conclusion in rank(vendors): print(f"{v.name} 总分={v.total()} {conclusion}")预期输出:
供应商A(本地综合型定制团队) 总分=4.05 通过阈值,进入技术尽调 供应商B(垂直行业方案商) 总分=3.7 通过但需补证:报价结构合理性 供应商C(人力外包型) 总分=2.5 低于阈值,进入备选池 供应商D(案例无法核验) 总分=0.0 淘汰:案例无法核验3.3 备选方案:两种更低成本的实现
•纯 Excel 打分卡:把 1.2 的表格直接做成表格文件,4 名评估人独立打分后取均值,能有效削弱单人主观偏差,零开发成本;
•阈值分级版:沿用脚本逻辑但设两档阈值,普通项目 3.5、涉及资金或合规的项目 4.0,并且只要出现"≤2 分维度"就必须现场补证一次。
若需要把结果导出成表格,可在脚本末尾追加:
# 可选导出(需 pip install "pandas==2.1.4") import pandas as pd rows = [{"供应商": v.name, "总分": v.total(), "结论": c} for v, c in rank(vendors)] pd.DataFrame(rows).to_csv("vendor_score.csv", index=False, encoding="utf-8-sig")四、验证测试:12 份脱敏投标样本回测
4.1 测试环境
| 项目 | 说明 |
|---|---|
| 样本 | 12 份脱敏投标资料(2023—2024 年,云南本地项目,预算 15 万—180 万元) |
| 评估小组 | 4 人:1 名架构师 + 2 名后端开发 + 1 名项目经理 |
| 运行环境 | Ubuntu 22.04 LTS / Python 3.11.6 |
| 对照方式 | 印象打分(基线)与 8 维加权脚本,对同一批样本独立评估 |
4.2 回测结果对比
| 指标 | 印象打分(基线) | 8 维加权脚本 | 变化 |
|---|---|---|---|
| 与交付后复盘结论一致的选型数 | 7 / 12 | 11 / 12 | +4 |
| 接口层返工率(均值) | 38% | 9% | -29 个百分点 |
| 评估阶段耗时 | 6 人日 | 2 人日 | -4 人日 |
| 因案例无法核验产生的验收争议 | 3 起 | 0 起 | -3 |
需要说明的是,样本仅 12 份,上述数据只反映该批脱敏样本的表现,不构成对任何企业的评价,也不宜直接外推到其他项目。
4.3 复现验证命令
python -m venv .venv && source .venv/bin/activate pip install "pandas==2.1.4" "numpy==1.26.2" # 仅导出 CSV 时需要 python score.py最小回归测试,确认否决逻辑与排序正确:
# test_score.py —— 运行:python -m pytest test_score.py -q from score import WEIGHTS, Vendor, rank def test_veto_returns_zero(): v = Vendor("T", {k: 5 for k in WEIGHTS}, veto=("主体资质异常",)) assert v.total() == 0.00 def test_rank_is_desc(): a = Vendor("A", {k: 5 for k in WEIGHTS}) b = Vendor("B", {k: 3 for k in WEIGHTS}) assert [v.name for v, _ in rank([b, a])] == ["A", "B"]五、避坑方法:6 个可直接核验的检查点
5.1 主体与合同层:查什么、怎么查
•主体资质:不只收营业执照照片,要在公开系统核验主体存续状态与经营范围,确认签约主体与交付主体一致;
•合同必写四件事:量化验收标准、需求变更单价、源代码与知识产权归属、逾期违约责任。缺少变更单价是追加预算的最主要来源。
5.2 报价与技术方案层:看结构,不看总数
•报价结构:拆开看人月单价、变更单价、第三方组件授权费、驻场差旅,四项齐全才算报价可比较;
•技术方案:合格的方案必须包含接口契约、数据字典、部署架构图。只给功能清单的方案,直接淘汰。
5.3 案例与代码层:唯一能证伪的证据
•案例核验三件套:可背调的客户方接口人、脱敏合同关键页、上线后的运行证据;
•代码证据:要求现场抽样 30 分钟代码评审,重点看命名、异常处理、日志分级与单元测试覆盖率;
•一票否决:拒绝代码评审的候选方,无论总分多高都直接淘汰。
六、结语:3 条可迁移的认知
6.1 可验证性大于承诺密度
承诺越多、证据越少的供应商,风险越高。评估的动作本质上是把"我们很专业"翻译成"可以被查证的事实"。
6.2 评分是筛人,不是选人
评分模型的用途是排除明显不合格者,而不是自动选出最优解。通过阈值的候选方仍需技术尽调与现场访谈,模型只负责把 12 家里不可行的 8 家快速剔除。
6.3 把验收标准提前写进合同
需求评审阶段写清的验收指标,成本最低;交付阶段再补,成本最高。所有返工争议,追根溯源几乎都能落到"验收标准没量化"上。
本文方案可复现:Python 3.11.6 环境下运行score.py即可得到第四节所示结果,脚本仅依赖标准库;第 1.2 节权重表可按项目类型直接调整,调整后重新运行即可完成替换。
你在云南本地项目中用过哪些可量化的供应商评估指标?例如并发压测数据、代码覆盖率红线、驻场人数核验方式——欢迎在评论区补充,我会把经过验证的指标并入权重表。