以下情境为教学假设,人物与数字不代表经核实的真实案例。
卖方看自己的生意,看到的是一段经历:做了多久、解决了什么问题、用户怎么反馈。买方看到的是一组可验证的风险:收入明年还在不在、客户会不会走、创始人离开后谁能接手、代码能不能维护、授权和合规有没有硬伤。同一份资产,在两种视角下不是同一个价格。买方不是故意挑毛病,他是在用自己的钱为不确定的未来定价。
这一节把买方的视角拆成五个问题,每个问题对应一类证据和一种折价方式,再用三个案例各暴露一项:Tidecast 暴露收入可预测性,Nord 暴露客户集中度,LedgerLite 暴露创始人依赖。最后把五个问题合并成一个可计算的折价模型,用 LedgerLite 的 768,768 美元锚算出 561,969 美元的调整价,并说明 20% 的创始人依赖折扣是怎么来的。
五个问题不是并列的。收入可预测性和客户集中度决定「钱能不能继续进来」,创始人依赖和技术债决定「生意能不能被接手」,合规瑕疵决定「接手后会不会突然赔一笔」。买方通常按这个顺序问:先看收入,再看人,再看代码和文件。顺序反了,会在还没确认收入可持续时就开始谈技术细节,浪费双方时间。
五个问题,五张证据
| 关注点 | 买方在问什么 | 需要的证据 | 典型折价方式 | 案例反例 |
|---|---|---|---|---|
| 收入可预测性 | 明年的收入能不能重复 | 按月收入、流失率、续约率、季节性、渠道分布 | 用更低的倍数或更高的折现率 | Tidecast:买断制、Q4 占 38%、Steam 占 80% |
| 客户集中度 | 少数客户走了会不会伤筋动骨 | 前 5 大客户占比、合同期限、转介绍来源 | 对集中部分打折,或要求 earn-out | Nord:前 3 家 48%、转介绍 55% |
| 创始人依赖 | 创始人离开后业务会不会停 | 文档、账号权限、值班安排、交接计划 | 扣替换成本,或要求创始人留任 | LedgerLite:260 家客户、一人负责工程与支持 |
| 技术债 | 代码能不能被第二个人维护 | 代码审计、测试覆盖、部署流程、依赖清单 | 扣修复成本,或放入托管 | Tidecast:14 个月一人开发,平台 SDK 绑定 |
| 合规瑕疵 | 有没有会突然变成账单的硬伤 | 授权链、隐私政策、DPA、保险、主体资质 | 交割前 cure,或赔偿上限、专项托管 | Tidecast:音乐买断授权不得转授权 |
这张表的每一行都能变成一个问题、一份材料和一笔钱。买方不会因为「感觉不错」就放弃证据;他会在数据室里找对应的文件,找不到就按最坏情况假设。卖方觉得「大家都知道」的事情,在买方眼里等于没有发生。折价不是因为买方苛刻,而是因为无法验证的风险只能用价格来覆盖。
收入可预测性:Tidecast 的买断制
Tidecast 的年净得是 138,171 美元,年销 9,600 份,标价 19.99 美元,Steam 占销量 80%,Q4 占全年销量 38%,12 月一个月 2,400 份,是月均 800 份的 3 倍。买方看到这组数字,第一反应不是「年收入 138,171 美元」,而是「如果今年 Q4 少卖 20%,年收入会掉多少」。Q4 占 38%,少 20% 就是全年少 7.6%,约 10,500 美元;如果 Steam 同时调整推荐算法,跌幅会更大。
买断制游戏的收入不是合同收入,而是一次次销售的集合。买方会要求按月、按渠道、按退款率拆开看,还会问:Wishlist 转化率是多少、首发窗口占多少、有没有续作或 DLC 计划、平台分成和退款政策有没有变化。它不是在否定游戏的质量,而是在判断「明年的 138,171 美元有多少能重复」。对订阅生意,买方问的是流失率;对买断制游戏,买方问的是「下一款什么时候出」。没有下一款,收入曲线就是一条已经开始的衰减曲线。
这解释了为什么 Tidecast 的合理锚是 1.8× 收入,而不是 LedgerLite 的 3.2× ARR。倍数差不是游戏生意「低一等」,而是收入的可重复性不同:订阅收入有合同和续费,买断收入依赖每一次新销售。买方愿意为可重复的收入付更高的倍数,因为他在买未来;他为一次性收入付更低的倍数,因为他在买库存。
客户集中度:Nord 的前三家客户
Nord Studio 年收入 154,320 美元,咨询服务占 72.7%,前 3 家客户占 48%,转介绍占 55%。这三个数字放在一起,买方会看到一个高度依赖少数关系的生意:近一半收入来自三家公司,超过一半的新客户来自现有关系,而咨询合同大多按项目签、按验收付款。买方会问:这三家客户的合同还有多久、续约率是多少、如果最大的客户换采购负责人,收入会怎样、转介绍是书面协议还是口头默契。
客户集中度本身不是罪。早期服务生意几乎必然集中,问题在于集中度有没有被合同和流程接住。如果前 3 家客户有多年合同、明确续约条款、服务已经产品化,买方可以把集中度当成「深耕细分市场」的证据;如果客户关系挂在合伙人个人身上、没有书面转介绍协议、交付物归属不清,买方就会把 48% 的收入当成高风险收入,要求打折或 earn-out。Nord 的 4.5× SDE 标准锚被下调到 3.0× SDE = 102,960 美元,服务收入占 72.7% 和两位合伙人依赖是主要原因,客户集中度是同一件事的另一面。
买方处理集中度的方式通常不是「一刀切打五折」,而是分层:对前 3 家客户对应的收入用更低倍数,对分散的订阅收入用正常倍数。如果前 3 家占 48%,买方可能只对这部分收入打 30%–50% 的折扣,而不是对全部收入打折。这样算出来的价格比「整体打五折」高,但比「完全不折」低。卖方要做的不是否认集中度,而是把客户关系从「合伙人的关系」变成「公司的合同和流程」,让买方能看到续约的证据。
创始人依赖:LedgerLite 的一人公司
LedgerLite 有 260 家付费客户、ARR 240,240 美元、毛利率 84.2%,数字看起来像一台健康的订阅机器。但买方翻开组织架构,看到的是一个人:创始人写代码、做支持、谈销售、处理账单,外包只负责零散工作。买方会问:如果创始人明天不能工作,服务能撑几天、谁能部署、谁能回复工单、谁能处理退款和合规请求、代码和账号的权限在谁手里。这些问题的答案,决定买方是在买一门生意,还是在买一份需要创始人继续上班的工作。
创始人依赖的折价不是情绪化的。买方会算替换成本:招一个能接手全栈的工程师要多久、要多少钱、前三个月能承担多少工作、需要多少文档和交接、如果找不到人要不要让创始人留任。以 LedgerLite 为例,假设替换一名全栈工程师的年成本是 80,000–120,000 美元,招聘和 ramp-up 需要 3–6 个月,交接期还要创始人投入 20%–30% 的时间;这些成本加在一起,足以让买方在 768,768 美元的锚上要求两位数的折扣。下一节会把 20% 的折扣算出来。
创始人依赖也不是只能折价。卖方可以提前把「人」变成「系统」:写运行手册、把部署做成一条命令、把支持问题分成可路由的类别、把账号权限交给多人、找一名兼职运维或支持。这些动作不会让创始人变得不重要,但会让买方相信「换一个人也能转」。折价的大小,取决于买方相信的是「创始人必须留下」还是「创始人可以交接」。
技术债:三个人都绕不开的代码审计
三个案例都没有专门的工程团队,技术债的表现不同,买方的问法相同:这段代码第二个人能不能维护。Tidecast 是 14 个月的一人开发,代码、美术、音乐和平台 SDK 绑在一起,买方会问哪些模块依赖平台接口、升级平台 SDK 要多久、有没有自动化构建和存档兼容测试。LedgerLite 是一人 SaaS,260 家客户共用一套代码,买方会问测试覆盖、数据库迁移、支付回调、权限模型和备份恢复。Nord 是服务加产品混合,买方会问客户定制代码和产品代码有没有分开、交付物归属是否清晰、复用资产能不能从客户项目里拆出来。
技术债的折价方式通常是「修复成本 + 风险溢价」,而不是按代码行数算。买方会请第三方做代码审计,给出一个修复清单和估算工时,再把工时折算成钱。如果技术债集中在核心路径,买方可能要求放入托管或设置赔偿上限;如果技术债只是工具链老旧,买方可能只在价格上做小幅调整。对独立开发者,最容易被低估的技术债不是「代码写得丑」,而是「只有一个人知道怎么部署、怎么回滚、怎么恢复数据」。
合规瑕疵:Tidecast 的音乐授权
Tidecast 的 IP 组合包括代码、美术、音乐和商标,其中音乐是买断授权,不得转授权。买方在尽调时会问:这份授权能不能随资产一起转、授权方是否同意控制权变更、如果买方把游戏移植到新平台,授权覆盖不覆盖、如果原授权方破产,权利还在不在。如果答案是否定的,买方要么在交割前重新谈授权,要么把这块资产从交易里剔除,要么设置专项托管。合规瑕疵的特点是「二值」:能 cure 就是交割条件,不能 cure 就是价格调整或退出。
LedgerLite 在合规上相对干净:企业订阅协议、DPA、网络安全险 1,000,000 美元都有书面落点。这不代表它没有合规风险,而是风险可以被第三方复核:数据怎么处理、泄露怎么通知、赔偿上限在哪里、保险赔多少。Nord 的合规瑕疵不在隐私,而在治理:两位合伙人各 50%、无期权池、无书面退出条款,买方会问「如果一位合伙人不同意出售,交易还能不能完成」。合规问题不总是法律问题,有时是治理结构问题;买方买的不是一份合规证书,而是一个能完成交割的结构。
创始人依赖如何压价
把五个问题变成价格,需要一个可复算的模型。模型不需要预测真实买方的心理,只需要把「问题有多严重」和「这个问题最多值多少折扣」分开。前者是 severity,用 0–100% 表示;后者是权重,用基点表示。两者相乘得到每个问题的折扣贡献,五项相加得到总折扣,再设一个上限,防止折扣超过买方的承受范围。
先看创始人依赖。把「创始人完全不可替代」设为 severity 100%,权重设为 20%,那么单独这一项就贡献 20% 的折扣。LedgerLite 的锚是 768,768 美元,20% 折扣是 153,754 美元,调整价是 615,014 美元。这个数字的含义不是「买方一定会压 20%」,而是「如果创始人依赖是唯一问题,且严重程度拉满,买方在价格上需要看到 20% 的安全垫才会继续谈」。真实交易里,买方可能用留任协议、earn-out 或托管替代一部分折扣,但经济逻辑相同:创始人越难替代,卖方越要用价格或时间来补偿。
| 关注点 | LedgerLite 的 severity | 权重上限 | 折扣贡献 |
|---|---|---|---|
| 收入可预测性 | 25% | 8% | 2.0% |
| 客户集中度 | 30% | 8% | 2.4% |
| 创始人依赖 | 100% | 20% | 20.0% |
| 技术债 | 30% | 5% | 1.5% |
| 合规瑕疵 | 20% | 5% | 1.0% |
| 合计 | 46% 上限 | 26.9% |
五项合并后,LedgerLite 的总折扣是 26.9%,调整价是 768,768 × (1 − 26.9%) = 561,969 美元,折扣金额 206,799 美元。计算过程是:2.0% + 2.4% + 20.0% + 1.5% + 1.0% = 26.9%;768,768 × 26.9% = 206,798.6,四舍五入 206,799;768,768 − 206,799 = 561,969。这个价格仍然高于个人买家的 360,360 美元,也高于财务买方的 648,648 美元打 26.9% 后的 474,162 美元;它说明创始人依赖虽然重,但没有把 LedgerLite 打到「只能卖给个人」的区间。
模型里的权重是教学假设,不是行业标准。收入可预测性和客户集中度各 8%,创始人依赖 20%,技术债和合规各 5%,合计上限 46%,再设 40% 的总折扣上限。上限的作用是防止五项同时拉满时算出 46% 的折扣——现实中,买方在折扣超过 40% 时通常不会继续压价,而是直接放弃或要求重组交易。代码会返回「是否触顶」,让读者知道这个价格是模型算出来的,还是被上限截断的。
三案例的折价对照
把同一套权重套到三个案例,得到不同的折扣结构。三个案例的锚不同:LedgerLite 用 3.2× ARR = 768,768 美元,Tidecast 用 1.8× 收入 = 248,708 美元,Nord 用已经下调过的 3.0× SDE = 102,960 美元。Severity 是教学设定,用来展示「同样五个问题,在不同生意里重量不同」。
| 案例 | 锚 | 最高贡献项 | 总折扣 | 调整价 |
|---|---|---|---|---|
| LedgerLite | 768,768 | 创始人依赖 20.0% | 26.9% | 561,969 |
| Tidecast | 248,708 | 创始人依赖 18.0% | 32.7% | 167,380 |
| Nord | 102,960 | 创始人依赖 16.0% | 31.5% | 70,528 |
Tidecast 的总折扣 32.7% 高于 LedgerLite,主要因为五项 severity 分别是 80%、60%、90%、30%、40%:买断制加 Steam 80% 让收入的可重复性成为最大问题,音乐授权不得转授权又增加一层合规折价。Nord 的总折扣 31.5%,五项 severity 是 60%、90%、80%、40%、30%;客户集中度贡献 7.2%,是第二高项,仅次于创始人依赖的 16%。LedgerLite 的总折扣最低,但绝对折扣金额最大:206,799 美元,因为它的锚最大。百分比和金额要分开看,否则会误判「谁的资产更差」。
三个案例的最高贡献项都是创始人依赖,这不是巧合。独立开发者的资产天然与创始人绑定:一人公司没有第二个人能接手,两人公司少一个人就少一半产能。买方的第一反应不是「这家公司有什么」,而是「创始人走了还剩什么」。把创始人依赖从 100% 降到 50%,LedgerLite 的总折扣会从 26.9% 降到 16.9%,调整价从 561,969 美元升到 638,846 美元;这就是为什么交接文档、运行手册、第二负责人这些「不产生收入」的动作,在出售时能变成价格。
写成代码:buyer-view.ts
下面的 buyer-view.ts 把五个关注点、权重、severity 和折扣上限写成一个函数。evaluateBuyerView 要求恰好五个关注点,每个 severity 在 0–100% 之间,权重固定为 8%、8%、20%、5%、5%;五项贡献相加后与上限取小,再从中扣除。它返回调整价、折扣金额、总折扣、实际折扣、是否触顶,以及贡献最大的关注点。这样一张表就能回答两个问题:这个价格是被哪个问题压下来的,以及压价有没有触顶。
代码把「创始人依赖 20%」写成权重,不是写死一个折扣。如果 severity 是 50%,贡献就是 10%;如果 severity 是 100%,贡献才是 20%。这种写法让读者可以调整自己的判断,而不是接受一个拍脑袋的数字。权重和上限是教学假设,代码的注释里写明了这一点;真实交易中,买方会用尽调证据和自己的模型,不会用这本书的权重。
// file: src/capital/buyer-view.ts
// tier: L1
// verify: node --test test/capital/buyer-view.test.ts
import { type Cents } from "../core/money.ts";
import { type Bps, applyRate } from "../core/rate.ts";
import { type Result, fail, ok } from "../core/result.ts";
export type ConcernKey =
| "revenuePredictability"
| "customerConcentration"
| "founderDependence"
| "techDebt"
| "compliance";
export const CONCERN_ORDER: ConcernKey[] = [
"revenuePredictability",
"customerConcentration",
"founderDependence",
"techDebt",
"compliance",
];
/**
* Maximum discount contribution at full severity (10000 bps). These weights
* are teaching assumptions: they make the arithmetic explicit, not a claim
* about how any real buyer prices a business. Founder dependence is the
* single largest line because a one-person business cannot be separated from
* its operator by signing a document.
*/
export const CONCERN_WEIGHT_BPS: Record<ConcernKey, Bps> = {
revenuePredictability: 800,
customerConcentration: 800,
founderDependence: 2000,
techDebt: 500,
compliance: 500,
};
export const DEFAULT_CAP_BPS: Bps = 4000;
export type Concern = {
key: ConcernKey;
severityBps: Bps;
};
export type BuyerViewInput = {
anchorCents: Cents;
concerns: Concern[];
capBps: Bps;
};
export type BuyerView = {
anchorCents: Cents;
adjustedCents: Cents;
discountCents: Cents;
grossDiscountBps: Bps;
appliedDiscountBps: Bps;
capped: boolean;
topConcern: ConcernKey;
topConcernContributionBps: Bps;
};
function isConcernKey(value: string): value is ConcernKey {
return (CONCERN_ORDER as string[]).includes(value);
}
/**
* Applies the five buyer concerns to an anchor price. Severity is expressed
* in basis points so a partly mitigated concern can be scored without a new
* scale. The total discount is capped: beyond the cap the buyer usually walks
* away or restructures the deal instead of asking for a lower headline.
*/
export function evaluateBuyerView(
input: BuyerViewInput,
): Result<BuyerView> {
if (!Number.isInteger(input.anchorCents) || input.anchorCents <= 0) {
return fail("anchor price must be a positive integer amount in cents");
}
if (
!Number.isInteger(input.capBps) ||
input.capBps < 0 ||
input.capBps > 10000
) {
return fail("discount cap must be between 0 and 100%");
}
if (input.concerns.length !== CONCERN_ORDER.length) {
return fail(
`expected ${CONCERN_ORDER.length} concerns, got ${input.concerns.length}`,
);
}
const seen = new Set<ConcernKey>();
let grossDiscountBps = 0;
let topConcern: ConcernKey = CONCERN_ORDER[0];
let topConcernContributionBps = -1;
for (const concern of input.concerns) {
if (!isConcernKey(concern.key)) {
return fail(`unknown concern ${concern.key}`);
}
if (seen.has(concern.key)) {
return fail(`duplicate concern ${concern.key}`);
}
seen.add(concern.key);
if (
!Number.isInteger(concern.severityBps) ||
concern.severityBps < 0 ||
concern.severityBps > 10000
) {
return fail(`concern ${concern.key} severity must be between 0 and 100%`);
}
const contributionBps = Math.round(
(concern.severityBps * CONCERN_WEIGHT_BPS[concern.key]) / 10000,
);
grossDiscountBps += contributionBps;
if (contributionBps > topConcernContributionBps) {
topConcern = concern.key;
topConcernContributionBps = contributionBps;
}
}
for (const key of CONCERN_ORDER) {
if (!seen.has(key)) {
return fail(`missing concern ${key}`);
}
}
const appliedDiscountBps = Math.min(grossDiscountBps, input.capBps);
const adjustedCents =
input.anchorCents - applyRate(input.anchorCents, appliedDiscountBps);
return ok({
anchorCents: input.anchorCents,
adjustedCents,
discountCents: input.anchorCents - adjustedCents,
grossDiscountBps,
appliedDiscountBps,
capped: grossDiscountBps > input.capBps,
topConcern,
topConcernContributionBps,
});
}
把 LedgerLite 代进去:创始人依赖 severity 100%,单独贡献 20%,调整价 615,014 美元;五项 severity 分别为 25%、30%、100%、30%、20% 时,总折扣 26.9%,调整价 561,969 美元。Tidecast 的五项 severity 是 80%、60%、90%、30%、40%,总折扣 32.7%,调整价 167,380 美元。Nord 是 60%、90%、80%、40%、30%,总折扣 31.5%,调整价 70,528 美元。代码返回的 topConcern 在三案例里都是 founderDependence,capped 都是 false;如果五项全部拉满,总折扣 46%,会被 40% 的上限截断,capped 变成 true。
折价模型不能替代尽调。它只是把「买方在意什么」变成可计算的量,让卖方在谈判前知道自己最弱的一环值多少钱。真正的尽调会看合同、账、代码、授权和客户访谈,任何一项都可能推翻模型里的 severity。下一节会把尽调拆成财务、客户、技术三块,分别对应五个问题里的不同证据。财务尽调的清单见 6.1 财务尽调 ,客户尽调见 6.2 客户与合同尽调 ,技术与 IP 尽调见 6.3 技术与知识产权尽调 。
小结
- 买方看独立开发者资产,先看五个问题:收入可预测性、客户集中度、创始人依赖、技术债、合规瑕疵。
- Tidecast 的反例是收入可预测性:买断制、Q4 占 38%、Steam 占 80%,年收入不是合同收入。
- Nord 的反例是客户集中度:前 3 家占 48%、转介绍占 55%、服务收入占 72.7%,客户关系与合伙人绑定。
- LedgerLite 的反例是创始人依赖:260 家客户、一人负责工程与支持,买方买到的可能是一份需要创始人继续上班的工作。
- 技术债的折价按修复成本算,不按代码行数算;合规瑕疵是二值的,能 cure 就是交割条件,不能 cure 就是价格调整或退出。
- 创始人依赖单独就能压价 20%:LedgerLite 的 768,768 美元锚上折扣 153,754 美元,调整价 615,014 美元。
- 五项合并后 LedgerLite 折价 26.9%,调整价 561,969 美元;Tidecast 折价 32.7% 到 167,380 美元;Nord 折价 31.5% 到 70,528 美元。
- 权重、severity 与 40% 上限都是教学假设;模型的价值是让卖方知道最弱的一环值多少钱,不是预测真实报价。
阅读导航:上一节:4.1 战略买方、财务买方与个人买家 · 下一节:4.3 交易流程与时间表 。
常见错误与边界
- 把五个问题当成并列。 收入和人决定生意能不能接,技术债和合规决定接手后会不会出事;顺序错了,会在收入还没验证时先谈代码。
- 用「大家都知道」代替证据。 买方在数据室里找不到文档,就按最坏情况假设;没有书面记录等于没有发生。
- 把客户集中度一刀切。 对集中收入打折,对分散收入用正常倍数,比整体打五折更接近真实谈判;分层比一刀切准确。
- 把创始人依赖当成道德问题。 买方不是不信任创始人,而是在计算替换成本;留任协议、交接文档和第二负责人都能降低折价。
- 按代码行数算技术债。 修复成本和风险溢价才是买方关心的;代码丑但部署清楚,折价可能小于代码漂亮但只有一个人会部署。
- 把合规瑕疵留到交割后。 能 cure 的问题要在交割前 cure;不能 cure 的问题要进入赔偿上限或专项托管,不能只写一句承诺。
- 把 20% 当成固定折扣。 20% 是 severity 100% 时的权重;severity 50% 只贡献 10%,不要把上限当默认值。
- 忽略折扣上限。 五项拉满时总折扣 46%,但买方通常不会接受超过 40% 的折价,而是直接放弃或重组交易;触顶意味着交易结构要变。
- 只看百分比不看金额。 LedgerLite 的 26.9% 是 206,799 美元,Nord 的 31.5% 只有 32,432 美元;百分比说明结构,金额说明谈判空间。
- 把模型当尽调。 模型里的 severity 是拍的,尽调里的证据是查的;模型可以帮你排序,不能替代合同、账、代码和客户访谈。
本节的边界是「买方视角与折价模型」:只讨论收入可预测性、客户集中度、创始人依赖、技术债、合规瑕疵五个问题,以及它们如何转成价格折扣,不展开尽调清单、交易结构和合同条款。所有权重、severity、折扣上限和案例数字都是教学假设,不构成投资、税务或法律建议。买方在真实交易中会按自己的模型定价;卖方能用的是把证据准备好,让模型里的 severity 尽量低。估值区间的完整方法见 11.3 估值区间与调整项 ,下一节交易流程见 4.3 交易流程与时间表 。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。