你筹备了整整三年的“云端小馆”终于要开业了。后厨里堆满了从开源市场采购来的“代码食材”——几十个开源组件东拼西凑,才做成这道招牌菜。可品控总监拦住了你:每包食材的质检标签都看过了吗?有的标签写着“放心用,随便加工随便卖”;有的写着“用了我的食材,你的整道菜谱都得公开”;还有的藏在包装背面的小字里:“专利费条款,详情咨询法务”。这就是商用合规审查:在产品交给顾客之前,把依赖清单里每个组件的许可证类型、传染风险和专利条款逐项查清,避免开业当天收到法院传票,或者被逼着把祖传秘方贴满大街。本文就用这家小馆的故事,带你走一遍商用合规审查的全流程。

岗位关联

对 AI 从业者的价值:当你的 AI 产品直接引用 HuggingFace 模型、开源框架与工具链时,一次许可证审查的疏忽就可能让核心代码被迫开源或陷入专利诉讼。掌握商用合规审查,等于给商业化落地装上法律安全气囊。

目录
  1. 可视化演示
  2. 协议类型速览
  3. 传染性风险
  4. 专利版权条款
  5. 依赖链审查
  6. 风险应对策略
  7. 审查落地流程
  8. 商用决策权衡
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

动态演示深入理解商用合规审查的核心机制,通过输入/处理/存储/输出四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

深入理解商用合规审查:商用合规 商用合规审查的流程与范围 SBOM工具与依赖链协议扫描 核心机制可视化 深入理解商用合规审查整体架构与关键组件

协议类型速览

你筹备三年的“云端小馆”终于要开业了。采购部搬回一箱箱代码食材——实际上是一堆开源组件。后厨墙上贴着品控总监的三条规矩:“第一,每包食材必须看清质检标签;第二,标签决定它能进哪口锅;第三,标签看不懂的,一律不许下锅。”开源世界里,这张质检标签就是许可证。它不写生产日期和营养成分,只写清楚了一件事:这份代码,你能不能用、怎么用、用了之后要付出什么。

许可证分三大门派。第一派叫“宽松型”,代表人物 MIT、BSD、Apache-2.0,口头禅是“随便用,记得提我名字就行”——你可以自由修改、闭源、商用甚至收费。第二派叫“弱传染型”,代表 LGPL、MPL,它们像可以拌进菜的酱料包:你的菜可以保留秘方,但酱料包自己的配方必须公开,且允许顾客自带替换。第三派叫“强传染型”,代表 GPL、AGPL,它们最难缠——一旦被揉进面团,整块面包都得跟着公开配方。

实际审查中,团队会把每个组件的许可证映射成一个“传染系数”,作为风险台账的第一列。系数越高,后厨的警戒级别就越高。可商用性、修改自由度、再分发义务,全都浓缩在这个数字里。

品控总监最欣慰的时刻,就是台账上所有标签都归了类。创业团队做商用合规审查,第一步永远是同一件事:把依赖清单里的每一个名字,翻译成绿、黄、红三种颜色。颜色定了,后面的风险、策略、流程才有讨论的坐标。

C={0,宽松型(MIT / BSD / Apache-2.0)0.5,弱传染(LGPL / MPL)1.0,强传染(GPL / AGPL)\displaystyle C = \begin{cases} 0, & \text{宽松型(MIT / BSD / Apache-2.0)} \\ 0.5, & \text{弱传染(LGPL / MPL)} \\ 1.0, & \text{强传染(GPL / AGPL)} \end{cases}
传染系数 C 把“质检标签”翻译成 0、0.5、1 三档,值越高,越容易把开源义务传染给整份产品。
  1. C(传染系数)代表许可证的“传播力度”,值越高,越容易把自己的开源义务传播给整体作品,是后续所有风险计算的基础。
    C∈{0, 0.5, 1.0}\displaystyle C \in \{0,\ 0.5,\ 1.0\}
  2. 宽松型取 0像普通食材,放进任何菜里都不会改变整道菜的属性,商用风险直接清零。
    C=0⇒无传染义务C = 0 \Rightarrow \text{无传染义务}
  3. 弱传染取 0.5像酱料包,只要求酱料自身的配方公开、可被替换,不要求整道菜开源,风险折半。
    C=0.5⇒仅组件自身开源C = 0.5 \Rightarrow \text{仅组件自身开源}
  4. 强传染取 1.0像霸王酵母,只要揉进面团,整块面包都要按它的规矩来,风险直接拉满。
    C=1.0⇒衍生作品整体开源C = 1.0 \Rightarrow \text{衍生作品整体开源}

传染性风险

后厨有个传说:有一种“霸王酵母”,只要一勺揉进面团,整块面包都必须按它的配方工艺对外公开。更微妙的是,酵母只在“把面包卖给食客”时才发威——如果只是自己试菜,它不会强迫你公开任何东西。这就是 GPL 的传染性机制:开源义务的触发,需要两个条件同时成立。

法律上,这两个条件是:M(是否修改了 GPL 代码)和 D(是否把修改后的作品分发给了第三方)。两者都为真,你的衍生作品就必须以 GPL 开源;任何一条不满足,义务不触发。这个理解直接决定了“GPL 组件能不能用”的答案——答案不是“绝不能”,而是“看你怎么用”。

关键在于耦合方式。静态链接或直接改写源码,等于把酵母揉进面团,传染无可避免;把 GPL 组件放进独立进程、通过接口通信,等于酵母被装在密封调料罐里,碰不到面团。而 AGPL 更严格,它把“通过网络提供服务”也视作分发——相当于远程食客通过网络端点餐,也算把面包端上了桌。

后厨的结论因此非常朴素:强传染食材要么单独开一个小灶(进程隔离),要么干脆不进菜单(替换或剔除)。每次引入新依赖时,先问一句“它是被揉进面团,还是装进密封罐”,比背一百条法律条文都管用。

开源义务(M,D)={1,M=1∧D=10,其他情况\displaystyle \text{开源义务}(M, D) = \begin{cases} 1, & M = 1 \wedge D = 1 \\ 0, & \text{其他情况} \end{cases}
开源义务是“修改”与“分发”的逻辑与:两个开关同时按下,义务才成立;只按一个,面团仍是你的面团。
  1. M(修改标记)是否对 GPL 组件的代码做了修改,或将其代码直接并入自己的模块。取 1 表示“酵母已揉进面团”。
    M∈{0,1}M \in \{0, 1\}
  2. D(分发标记)是否把修改后的作品交付给第三方,包括销售、预装设备、提供服务等场景。
    D∈{0,1}D \in \{0, 1\}
  3. 合取判断两个标记同时为 1,义务成立;其余三种组合(只修改不分发、只分发不修改、两者皆无)都不触发。
    M=1∧D=1⇒义务成立M = 1 \wedge D = 1 \Rightarrow \text{义务成立}

专利版权条款

食材里藏着一个行业潜规则:“隐形代言费”。有些供应商在质检标签背面用小字写着:你用了我的食材,等于同意日后我可能向你的顾客主张专利费——除非食材本身自带“专利不追究承诺”。开源许可证对专利的态度同样天差地别,而这恰恰是新手最容易忽略的维度。

Apache-2.0 明确授予每位使用者一份“专利许可”:贡献者承诺,不因你使用了其代码中涉及的专利而起诉你。这是给商用产品的“免战金牌”。GPL 则采用“专利报复”条款:如果你对贡献者提起专利诉讼,你的 GPL 使用权将自动终止——相当于“你敢告我,我就不让你用我的配方”。MIT 和 BSD 则保持沉默,既不授予也不剥夺,专利风险需要自己评估。

综合风险评分把多个维度乘在一起:组件是否进入商用(I)、许可证传染能力(C)、代码耦合方式(E)、专利条款是否有保护(P)。四项相乘,得到每个组件的合规风险度,红色组件必须在发布前清零。

这就像品控台账上的第四列“专利风险”。三项零分不代表零风险,四项拉满则必须上报。记住一个朴素的道理:食材越便宜,越要看清背面小字——开源不等于放弃专利权。

Risk=∑i=1nIi×Ci×Ei×Pi\displaystyle \text{Risk} = \sum_{i=1}^{n} I_i \times C_i \times E_i \times P_i
综合风险度是四个维度的乘积:任意一项为 0,总风险归零;四项都是最高值,风险爆表。
  1. I_i(商用标识)值为 1 表示该组件进入商用发布范围,0 表示仅内部使用或已剔除。内部自用不触发分发义务,风险直接清零。
    Ii∈{0,1}I_i \in \{0, 1\}
  2. C_i(传染系数)来自协议分级的结论:宽松型 0、弱传染 0.5、强传染 1.0,衡量“拉人下水”的力度。
    Ci∈{0, 0.5, 1.0}C_i \in \{0,\ 0.5,\ 1.0\}
  3. E_i(耦合度)组件与产品的结合方式——静态链接或改写源码取 1.0,动态链接取 0.5,独立进程通信取 0.2。
    Ei∈{0.2, 0.5, 1.0}E_i \in \{0.2,\ 0.5,\ 1.0\}
  4. P_i(专利条款风险)许可证是否包含专利授权或报复条款,完全没有保护则取 1,取值通常由法务确认。
    Pi∈{0, 1}P_i \in \{0,\ 1\}

依赖链审查

你以为只查直接采购的食材就够了,直到品控总监拿出溯源码:每一包半成品酱料,都还有自己的原料供应商,供应商还有供应商。一道菜真正的安全边界,是整条供应链的边界。软件依赖同样如此——你直接引用的库只是冰山一角,库自己所依赖的“传递依赖”,可能悄悄引入一个 GPL。

SBOM(软件物料清单)就是整棵依赖树的完整进货台账,记录每个节点的名字、版本、许可证和来源。审查团队做的第一件事,就是让工具递归扫描整棵依赖树,把每个叶子节点都记进台账。缺少 SBOM 的合规审查,等于进货时不开单据,出事时无从追溯。

工具层面,Snyk、FOSSA、Black Duck、ORT 都能自动生成 SBOM 并递归扫描传递依赖;人工则需要核对“冲突协议组合”——例如某个 Apache-2.0 组件静态链接了一个 GPL 库,它的宽松身份就失效了。审查覆盖率不足,就等于进货台账缺页,而缺页的那一行往往是出事的根源。

覆盖率=NidentifiedNtotal×100%\displaystyle \text{覆盖率} = \frac{N_{\text{identified}}}{N_{\text{total}}} \times 100\%
覆盖率 = 已识别清许可证的组件数 ÷ 依赖树总组件数,100% 才是“账实相符”。
  1. N_total(总节点数)依赖树中所有组件之和,包括直接依赖与全部传递依赖。
    Ntotal=Ndirect+NtransitiveN_{\text{total}} = N_{\text{direct}} + N_{\text{transitive}}
  2. N_identified(已识别节点数)许可证类型已被确认的组件数量,可能小于总数。
    Nidentified≤NtotalN_{\text{identified}} \le N_{\text{total}}
  3. 比值与百分化两者相除再乘以 100%,得到台账完整度;低于 100% 意味着还有“不明标签”的食材,不能开火。
    覆盖率=100%⇒依赖台账账实相符\text{覆盖率} = 100\% \Rightarrow \text{依赖台账账实相符}

风险应对策略

查出了问题食材,该怎么处理?换厨师不如换方案。后厨有四个经典应对:换原料、拆酱料包、买原厂授权、隔离小灶。每个方案都有代价,也有适用场景。

第一是替换:寻找许可证更宽松、功能等价的开源替代库,成本是重构与回归测试。第二是剔除或自研:高风险组件功能简单时,直接删掉或自己写几十行代码。第三是商业授权:许多开源项目采用双许可证模式——开源版带 GPL 义务,商业版付费后免除传染,相当于花钱买“原厂配方豁免”。第四是隔离:把 GPL 组件封装成独立进程,通过 REST 或消息队列通信,让酵母永远待在密封罐里。

四种方案像后厨的四把刀:替换最干净但最贵,隔离最便宜但有解释空间,商业授权是花钱买安心,剔除自研则考验团队功力。没有绝对正确的方案,只有“成本—风险—时间”三角上的最优点。

Ctreat=Creplace+Cverify+Clicense\displaystyle C_{\text{treat}} = C_{\text{replace}} + C_{\text{verify}} + C_{\text{license}}
整改总成本 = 替换成本 + 验证成本 + 授权成本,四个方案各自报价后,再决定用哪把刀。
  1. C_replace(替换成本)重构与修改代码的人力工时乘以人力单价,替换越深,成本越高。
    Creplace=Thours×RrateC_{\text{replace}} = T_{\text{hours}} \times R_{\text{rate}}
  2. C_verify(验证成本)替换后的回归测试、安全扫描与兼容性验证费用,是“菜换料”后的试吃环节。
    Cverify=Ttest×RrateC_{\text{verify}} = T_{\text{test}} \times R_{\text{rate}}
  3. C_license(授权成本)购买商业授权或法律咨询的外部支出,通常一次付清或按年订阅。
    Clicense=PquoteC_{\text{license}} = P_{\text{quote}}
  4. 方案比价三个子项相加得到整改总成本,比较替换、自研、商业授权、隔离四条路,选总成本最低且风险可接受的一种。
    Cplan=Creplace+Cverify+ClicenseC_{\text{plan}} = C_{\text{replace}} + C_{\text{verify}} + C_{\text{license}}

审查落地流程

品控不只是一个人,而是一本《后厨品控手册》:谁负责、标准是什么、检查关卡在哪、放行门槛多高。商用合规审查落在流程上,同样是这套“治理流水线”。

成熟团队通常分四步走:第一步,成立开源治理委员会,明确法务、技术、安全三方的责任分工;第二步,制定开源政策,写清楚公司允许哪些协议、禁止哪些协议、例外由谁审批;第三步,在 CI/CD 流水线中接入自动化扫描,每次代码提交自动比对许可证白名单;第四步,发布前设人工评审关卡,核查扫描报告、SBOM 归档与声明保留。

后厨的每一道新菜都必须过了品控关卡才能进菜单,软件公司也一样:没走过合规闸门的版本,不能上线。把审查嵌进流水线,比临时抱佛脚高效十倍——因为合规审查不是一次性的验收,而是每天重复的日常动作。

Release={通过,Nhigh=0∧SBOM 完整∧声明保留拦截,其他情况\displaystyle \text{Release} = \begin{cases} \text{通过}, & N_{\text{high}} = 0 \wedge \text{SBOM 完整} \wedge \text{声明保留} \\ \text{拦截}, & \text{其他情况} \end{cases}
发布绿灯是三重条件同时满足:高风险组件清零、SBOM 完整、版权声明保留;任一缺失,版本被拦在门外。
  1. N_high = 0(高危清零)所有高风险组件要么被替换,要么获得商业授权,与产品再无耦合。
    Nhigh=0N_{\text{high}} = 0
  2. SBOM 完整依赖树的每个节点都有许可证记录,覆盖率达成 100%,账实相符。
    SBOM 覆盖率=100%\text{SBOM 覆盖率} = 100\%
  3. 声明保留所有许可证要求的版权声明、免责声明都被正确保留在分发物中,一个都不能少。
    NOTICE 文件完整\text{NOTICE 文件完整}
  4. 合取判定三项条件同时满足才放行,否则发布闸门关闭——合规不是“尽量做到”,而是“缺一不可”。
    Release={1,A∧B∧C0,其他\text{Release} = \begin{cases} 1, & A \wedge B \wedge C \\ 0, & \text{其他} \end{cases}

商用决策权衡

没有零风险的餐厅,只有风险定价。越是核心的祖传秘方,越不能因为一勺霸王酵母被拖下水;越是外围的通用工具,越可以大胆使用宽松组件。商用合规审查的终点,不是“清零一切风险”,而是“在风险、成本与收益之间找到平衡点”。

权衡时有三个维度:法律风险(不整改可能面临的诉讼与强制开源)、合规成本(替换、授权、隔离的工程代价)、商业收益(快速上线的机会成本、社区口碑、战略价值)。把三个维度折算成分数,再用权重加权,就能得到“该不该用这个组件、该花多大力气整改”的量化答案。

如果产品主打闭源 SaaS,AGPL 组件就是红线,必须隔离或替换;如果项目本来就要构建开放生态,主动选择 GPL 甚至是一种以“公开配方”换“社区共建”的战略。合规审查从来不是为了把风险清零,而是确保每一分风险都明码标价、由你主动选择。

S=w1×Rlegal+w2×Ctreat−w3×Bbiz\displaystyle S = w_1 \times R_{\text{legal}} + w_2 \times C_{\text{treat}} - w_3 \times B_{\text{biz}}
决策评分 = 法律风险分 + 合规成本分 − 商业收益分,分数越低越值得推进,反之则要重新选型。
  1. R_legal(法律风险)未处置的传染性与专利风险得分,可由第三节的风险公式汇总得到。
    Rlegal=∑RiskiR_{\text{legal}} = \sum \text{Risk}_i
  2. C_treat(合规成本)整改与授权采购的总成本,来自第五节的成本模型。
    Ctreat=Creplace+Cverify+ClicenseC_{\text{treat}} = C_{\text{replace}} + C_{\text{verify}} + C_{\text{license}}
  3. B_biz(商业收益)快速上线、社区红利、生态兼容等带来的收益,主动开源还可能创造战略价值。
    Bbiz=机会收益+战略收益B_{\text{biz}} = \text{机会收益} + \text{战略收益}
  4. 加权求和用权重 w 把三个维度折算成统一的决策分,结合团队风险偏好给出最终结论。
    S=w1Rlegal+w2Ctreat−w3BbizS = w_1 R_{\text{legal}} + w_2 C_{\text{treat}} - w_3 B_{\text{biz}}

AI 应用场景

AI 产品依赖合规扫描

阶段:模型部署与产品发布

解决的问题:AI 工程师习惯 pip install 一装一大把,几十个开源库瞬间进入依赖树,其中可能藏着一个 GPL 组件。传统做法靠人肉翻 requirements.txt,既慢又漏;AI 时代的合规扫描工具自动生成 SBOM、递归识别传递依赖,并在 CI 中标记风险组件。

具体案例:某 AI 视频生成创业公司要发布 SaaS 产品,依赖清单里有一个基于 LGPL 的 ffmpeg 封装库。团队没有直接剔除,而是把它封装进独立转码进程,通过消息队列通信,既保留功能又避免传染;同时用开源工具 ORT 扫描从 GitHub 引入的每个仓库,发布前风险组件清零。

开源大模型商用选型

阶段:模型选型与微调前评估

解决的问题:开源大模型许可证五花八门——Llama Community License、CreativeML OpenRAIL-M、MPL-2.0 等,不能简单当“开源免费”处理。盲目集成商用,轻则违反“月活超 7 亿需单独授权”等附加条款,重则被迫下架产品。

具体案例:算法团队想在商用产品中集成 Stable Diffusion 生态,审查发现其 OpenRAIL-M 许可证包含“禁止军事用途、需保留限制性使用条款”等约束。最终团队在条款允许的范围内以 API 网关方式接入,并在法务确认后归档 SBOM,避免把模型直接捆绑进无限制的商用 SDK。

CI/CD 自动化合规门禁

阶段:持续集成与交付

解决的问题:人工审查赶不上每周数次发版的节奏,依赖变更往往在合并后才被发现。把合规检查做成流水线关卡,每次 Pull Request 自动触发许可证扫描,高危组件直接阻断合并,把“事后追责”变成“事前拦截”。

具体案例:某团队在 Jenkins 流水线中加入 license-check 步骤,策略文件维护公司级许可白名单与黑名单。一次 PR 中开发者引入了 GPL 的 pygraphviz,流水线立即标红并附上“替换建议列表”,开发者 10 分钟完成换库,合规人员只需每周复核一次报告。

Python 演示

python65 行
# -*- coding: utf-8 -*-# 商用合规审查助手: 扫描依赖清单并输出处置建议 PERMISSIVE = {"MIT", "BSD-3-Clause", "BSD-2-Clause", "Apache-2.0"}WEAK_COPYLEFT = {"LGPL-2.1", "LGPL-3.0", "MPL-2.0"}STRONG_COPYLEFT = {"GPL-2.0", "GPL-3.0", "AGPL-3.0"} RISK_TABLE = {    "permissive": (0.0, "通过"),    "weak": (0.5, "隔离"),    "strong": (1.0, "替换"),    "unknown": (1.0, "人工确认")}  def classify(license_id):    if license_id in PERMISSIVE:        return "permissive"    if license_id in WEAK_COPYLEFT:        return "weak"    if license_id in STRONG_COPYLEFT:        return "strong"    return "unknown"  def scan_dependencies(deps, distributed=True):    report = []    risky = []    for name, license_id in deps:        level = classify(license_id)        risk, action = RISK_TABLE[level]        if not distributed and risk > 0:            action = "内部使用可暂缓"        row = (name, license_id, level, risk, action)        report.append(row)        if action == "替换" or action == "人工确认":            risky.append(row)    return report, risky  def render_report(report, risky):    print("=" * 52)    print(" 开源组件商用合规审查报告")    print("=" * 52)    for name, license_id, level, risk, action in report:        print("- {:<16} {:<12} {:<10} -> {}".format(            name, license_id, level, action))    print("-" * 52)    if risky:        print("发现 {} 个待处置组件, 发布前必须整改".format(len(risky)))    else:        print("全部合规, 可以进入发布流程")  if __name__ == "__main__":    deps = [        ("requests", "Apache-2.0"),        ("numpy", "BSD-3-Clause"),        ("pillow", "HPND"),        ("ffmpeg", "LGPL-2.1"),        ("coreutils", "GPL-3.0"),        ("libyaml", "MIT"),    ]    report, risky = scan_dependencies(deps)    render_report(report, risky)
目的:模拟商用产品发布前的依赖清单审查——每个组件按其许可证归入三级风险,输出处置建议与整改清单。
  1. PERMISSIVE = {...}维护宽松许可证白名单,后续分类都靠它。
  2. def classify(license_id)把 SPDX 许可证标识符翻译成“绿黄红”三级。
  3. RISK_TABLE[level]查表得到风险系数和默认处置动作,一条数据驱动整个逻辑。
  4. if not distributed and risk > 0:仅内部使用且未对第三方分发时,传染义务不触发,可暂缓整改。
  5. ("pillow", "HPND")故意放入一个不在白名单里的老许可证,触发“人工确认”路径。
  6. risky.append(row)自动收集需要处置的组件,形成发布前整改清单。

常见误区

误区网上都说 GPL 有传染性,所以我统一规定:凡是 GPL 的库一律不许用。反正开源库多的是,少它地球照样转,何必冒法律风险?

正解GPL 的传染义务只在“修改 + 分发”同时成立时触发。内部使用、独立进程调用、不修改地聚合(aggregate)都是合法场景。一刀切禁用会把 Linux、Git、FFmpeg 生态等大量优秀组件挡在门外。正确做法是分级管理:能换则换,不能换就隔离,必要时购买商业授权。合规审查的目的是“用得明白”,而不是“用得最少”。

为何常见:“传染性”这个词被传得过于吓人,加上技术博主常一句话总结“用了 GPL 就必须开源”,初学者就把“可能触发”误解成“必然触发”。

误区我们要做商用产品,选 MIT 协议的一定没错,MIT 就是最宽松的许可证,用起来零风险。

正解MIT 确实允许任意使用、修改、再分发,但它没有明确的专利授权条款。如果贡献者持有的专利覆盖了你的产品功能,MIT 不会给你任何保护;而 Apache-2.0 自带专利授权与专利报复条款,商用角度反而比 MIT 更“稳妥”。此外 MIT 也不授予商标使用权,你不能暗示作者为你的产品背书。

为何常见:人们只盯着“宽松”两个字,忽略了专利维度。“宽松”指使用条件少,不等于“法律保护全”——这是两个完全不同的概念。

误区我只要把 `requirements.txt` 里直接引用的库都查一遍许可证,不就合规了吗?传递依赖太深了,查起来没完没了。

正解直接依赖只是冰山一角。你引用的库内部又依赖了别的库,其中可能藏着一个 GPL。必须递归扫描整棵依赖树,用 SBOM 记录所有节点,还要关注构建期工具链——一个 GPL 的代码生成器生成的代码被静态链接进产物,同样可能触发传染。

为何常见:requirements.txt 一眼能看完,看起来“可控”;传递依赖深不见底,初学者难以建立“依赖树”的心智模型,于是想当然地缩小了审查边界。

误区开源软件不要钱,我直接集成到付费产品里,省下一大笔授权费,这不是天经地义吗?

正解“开源”指源代码开放,不等于放弃版权与专利。许多许可证专门约束商用方式:GPL/AGPL 要求开源衍生作品,OpenRAIL 系列限制军事与超大规模用户场景,部分模型许可还有月活上限。商用前必须逐条阅读附加条款,“免费”成立的前提是“合规”。

为何常见:“免费、开源、自由使用”三个概念被混为一谈,媒体的“开源免费”宣传强化了错觉,直到收到律师函才发现许可证不是免责声明。

面试题

Q1. 以下哪个许可证属于“宽松型”,允许自由修改并闭源商用?

单选题 · easy

  • A.GPL-3.0 许可证,强传染
  • B.AGPL-3.0 许可证,强传染
  • C.MIT 许可证,宽松且可商用← 正确答案
  • D.LGPL-3.0 许可证,弱传染

答案:C。MIT 属于宽松型许可证,使用、修改、商用、闭源都自由。GPL 和 AGPL 是强传染型,LGPL 是弱传染型。类比质检标签:只有绿色标签(宽松型)才能随手进任何一口锅。

Q2. GPL 协议的“开源义务”在什么条件下被触发?

单选题 · mid

  • A.仅内部使用,未对外分发
  • B.修改代码,并向客户分发← 正确答案
  • C.独立进程调用,不修改源码
  • D.下载源码,但从不进行分发

答案:B。开源义务需要“修改”与“分发”两个条件同时成立,就像霸王酵母要同时满足“揉进面团”和“面包卖给食客”才会发威。仅内部使用、独立进程调用或只下载不分发,都不触发义务。

Q3. AGPL 与 GPL 最核心的区别是什么?

单选题 · mid

  • A.AGPL 允许商用产品闭源交付
  • B.AGPL 对再分发不加任何限制
  • C.通过网络提供服务也视为分发← 正确答案
  • D.AGPL 禁止修改后重新发布

答案:C。AGPL 把“通过网络提供服务”也视作分发,相当于远程食客通过网络端点餐也算端上了桌。GPL 只约束传统的“分发”行为(拷贝、销售、预装),而 AGPL 堵住了 SaaS 模式绕开开源的漏洞。

Q4. 下列哪个许可证在文本中明确包含“专利授权”条款?

单选题 · easy

  • A.MIT 许可证,仅声明版权
  • B.BSD 许可证,要求保留声明
  • C.Apache-2.0,含专利授权← 正确答案
  • D.Unlicense 许可证,放弃版权

答案:C。Apache-2.0 明确授予使用者专利许可,贡献者承诺不因专利起诉使用者,像一份“免战金牌”。MIT、BSD、Unlicense 对专利保持沉默,既不授予也不保护,专利风险需要自行评估。

Q5. 商用产品以动态链接方式使用 LGPL 库,需要满足哪些条件?

多选题 · hard

  • A.允许用户替换成自研版本← 正确答案
  • B.修改库本身需开源该修改← 正确答案
  • C.必须将产品整体开源
  • D.只允许个人学习使用

答案:AB。LGPL 的核心设计是“酱料包”逻辑——你的菜可以保留秘方,但酱料包自身必须可替换:用户能自行更换库文件,而你若修改了 LGPL 库本身,改动部分仍要开源。整体开源(C)是 GPL 级的要求,D 则完全误解了“商用可用”的初衷。

Q6. 风险公式 Risk = Σ I×C×E×P 中,E 代表什么?

单选题 · hard

  • A.组件的许可证传染系数
  • B.代码的耦合度与调用方式← 正确答案
  • C.组件所在国法律环境
  • D.产品的商业定价策略

答案:B。E 是耦合度——组件以什么方式揉进产品:静态链接取 1.0,动态链接取 0.5,独立进程通信取 0.2。类比酵母:揉进面团(静态链接)传染最强,密封在罐里(独立进程)几乎无风险。A 对应 C 系数,C、D 与公式无关。

Q7. 发现依赖链中存在 GPL 组件且无法直接替换,可采用哪些处置策略?

多选题 · mid

  • A.独立进程隔离,进程外调用← 正确答案
  • B.购买该组件的商业授权← 正确答案
  • C.忽略风险,直接打包发布
  • D.删除依赖,自研同等功能← 正确答案

答案:ABD。规范的处置策略包括进程隔离(密封罐)、商业授权(买原厂豁免)、剔除自研(换配方)。C 是典型的作死行为——带着高风险组件直接发布,等于把法院传票和强制开源的风险一起交付给客户。

Q8. SBOM(软件物料清单)在合规审查中的核心作用是什么?

单选题 · mid

  • A.提升代码运行的速度
  • B.记录全部依赖节点信息← 正确答案
  • C.加密软件的安装包
  • D.自动修复安全漏洞

答案:B。SBOM 是依赖树的完整进货台账,记录每个组件的名字、版本、许可证和来源,让“账实相符”成为可能。它不加速运行、不加密安装包、不修复漏洞,而是为合规审计提供“查得到、对得上”的基础。

Q9. 某 Apache-2.0 组件的构建过程会调用 GPL 工具生成代码,并静态链接进产物,以下说法正确的是?

多选题 · extreme

  • A.构建工具生成的代码可能受影响← 正确答案
  • B.仅在运行时调用则风险较低← 正确答案
  • C.生成代码绝对不受许可证约束
  • D.静态链接后传染边界需评估← 正确答案

答案:ABD。构建期工具链的传染性是极端场景:GPL 工具生成的代码被静态链接进你的产物,可能被视为衍生作品,需逐案评估(A、D 正确)。如果工具只在运行时被调用、不参与产物生成,风险低得多(B 正确)。“绝对不受约束”低估了 copyleft 的边界争议,是不严谨的说法(C 错误)。

Q10. 商用合规审查中,发现高风险组件后最稳妥的第一步是什么?

单选题 · easy

  • A.立即发布并抢占市场
  • B.隐藏组件记录继续上线
  • C.暂停发布并评估处置方案← 正确答案
  • D.删除审查记录以避免追责

答案:C。发现高危组件后,正确做法是暂停发布、对照替换/隔离/授权/自研四套方案评估处置。A、B、D 都是在掩盖问题,只会把“可能的法律风险”变成“确定的违规事实”。合规审查的价值就是让你在上市前发现问题,而不是上市后被问题找上门。