简介:《2023 生成式人工智能发展与监管白皮书》由南财合规科技研究院与观韬中茂律师事务所联合出品,面向关注AI产业、合规治理与政策研究的从业者、研究者及公众,系统梳理生成式AI的发展现状、政策导向、应用风险与各国监管路径,重点呈现中国在发展与安全之间的治理思路。资源包为1个PDF文件,约4.22MB,按“发展—风险—借鉴—实践”四部分展开,涵盖算力、大模型与应用市场,知识产权侵权、算法黑箱与歧视、数据安全与个人信息保护、伦理道德风险,以及美国、欧盟和中国的治理框架与商业化实践思考。目前已有153人学习下载,适合快速建立生成式AI监管议题的全景认知,也可作为报告写作、合规研判、课堂研讨与政策比较的参考资料。内容兼顾产业观察与法律合规视角,对理解生成式AI落地中的风险边界和治理工具具有较高参考价值。
1. 生成式人工智能落地评审的三个追问:这份白皮书到底能当什么用
做人工智能功能上线评审的团队,多半被这三句话问住过:训练语料从哪来、有没有授权凭证、用户输入会不会被拿去继续训练。问的人不一定懂模型,答的人常常只剩一句"行业里都这么做"。这份《2023 生成式人工智能发展与监管白皮书》的价值,不在于给你一份标准答案,而在于它把"发展现状、风险清单、域外观察、落地实践"四块拆得足够细,细到你能把里面的条目直接翻译成需求池里的检查项。适合三类人看:要拍板上不上生成式功能的产品负责人、负责语料和日志的后端与算法同学、以及需要在评审会上拿出证据的合规同学。翻完不一定能直接抄,但能少走不少弯路。
2. 四段骨架拆开看:发展、风险、域外观察、实践各喂给工程侧什么
很多人拿到这种几十页的材料,第一反应是从头读到尾,读完记住几个数字就放下了。实际用起来更高效的方式是把它当四份不同的输入:发展篇喂给你模块边界和成本量级,风险篇喂给你验收线,域外观察篇喂给你分级方法,实践篇喂给你研发与上线之间的那条界线。四份材料用途不同,读法也不该一样。
2.1 发展篇:数据、算力、模型、应用四层,正好对应四个模块边界
白皮书把生成式人工智能的产业链拆成数据层、算力层、模型层、商业化应用层,这个拆法对工程侧最大的好处是它天然对应了责任边界。数据层负责语料来源、清洗、标注;算力层负责训练与推理的容量;模型层负责选型、微调、评测;应用层负责交互形态和兜底。一个常见的翻车场景是:项目上线出了问题,大家围着模型层吵,最后发现是数据层的抓取没留授权凭证。按四层划分责任人,比按"前后端"划分更贴合这类系统的实际结构。
白皮书里给了几个可以拿来定量的锚点。它提到某个早期大模型的训练语料在 45TB 文本量级、包含 8000 亿词、模型参数 1750 亿;也给了算力口径:训练一次 13 亿参数规模的模型大约需要 27.5 PFlop/s-day,而单月运营所需的算力在数千 PFlop/s-day 量级。这两个数字放在一起看,结论很直接——推理侧的量级远高于训练侧,容量规划如果只按训练峰值买卡,上线一个月就会被打爆。
卡时换算的方法我一般这么走:把 PFlop/s-day 乘 86400 换成总浮点运算量,再除以单卡有效算力。单卡有效算力等于峰值乘利用率,训练场景利用率取 0.35 到 0.45 比较稳,推理场景因为批处理波动大,取 0.2 到 0.3 更保守。以主流训练卡 FP16 峰值 300 TFLOPS 为例,27.5 PFlop/s-day 折合约 5500 卡时,差不多是 229 张卡跑一天,这个量级对多数团队来说是要提前排队的。
| 产业链层 | 白皮书给的事实锚点 | 工程侧应产出的东西 |
|---|---|---|
| 数据层 | 语料规模可达 45TB 量级 | 语料台账、授权凭证目录、清洗版本记录 |
| 算力层 | 训练 27.5 PFlop/s-day、月运营数千 PFlop/s-day | 容量模型、卡时预算表、降级预案 |
| 模型层 | 通用模型与垂直模型两条路线 | 选型决策记录、模型卡、评测集与基线分数 |
| 应用层 | 办公、文娱、营销、家庭、金融等场景 | 交互形态说明、人工兜底流程、抽检方案 |
模型层那一节提到通用模型和垂直模型的分野,这个判断对选型很关键。垂直模型成本低、部署灵活,但它对行业语料的质量要求反而更高,而且要能接进企业自己的知识库才能持续迭代。如果业务场景窄、数据又在自己手里,走垂直路线通常更划算;如果场景宽、迭代快、团队没有持续预训练的资源,接成熟接口再叠加检索增强是更现实的做法。选型时我会强制写一页决策记录,把"为什么不选自研"写清楚,评审会上这一页比任何 PPT 都好使。
2.2 风险篇:四类风险其实是四条验收线
风险章节罗列了知识产权侵权、算法风险、数据安全与个人信息保护、伦理道德四类。单看标题很容易滑过去,真正有用的是它把每一类下面的具体形态都点到了:输入端语料复制、输出端与原作品实质性近似、员工把内部资料贴进对话框导致商业秘密外泄、算法黑箱导致无法向用户解释结论、训练数据本身有偏导致分群体验不一致、模型在关键决策上给出错误判断。这些不是法律问题,是设计问题。
我的做法是把四类风险翻译成四条验收线,每条线配一个可检查的证据物。知识产权线看两个东西:语料授权覆盖率,以及输出端与原作品的近似检测报告。算法线看三样:决策留痕是否可回溯、分群评测集上各组的通过率差异、高风险场景是否有人工复核节点。数据与个人信息线看脱敏覆盖率、留存期限配置、以及有没有把用户输入默认纳入训练。伦理线看内容分级策略和生成内容标识。这四条线跑完,评审会上大部分追问都能当场翻到对应文件。
| 风险类 | 典型现象 | 可落地的控制点 | 验收证据 |
|---|---|---|---|
| 知识产权 | 输出与某段已有文本高度重合 | 语料授权台账 + 输出近似检测 | 授权覆盖率报表、重合度抽检记录 |
| 算法 | 同一问题对不同人群给出不同质量答案 | 分群评测集 + 决策留痕 | 分组通过率差异表、trace 样本 |
| 数据与个人信息 | 用户对话原文进了训练集 | 输入侧脱敏 + 训练开关默认关闭 | 脱敏日志、开关配置快照 |
| 伦理 | 生成内容缺少标识、被二次传播 | 显式标识 + 内容分级 | 标识覆盖率、拦截记录 |
这里有个容易忽略的点:白皮书在知识产权那一节特别提到,模型训练的语料越匮乏,输出内容侵权风险越高;提示词写得越精准、越限缩,生成结果越容易贴近某个具体作品。这条对做提示词模板的团队是直接的警告——把模板写得过于具体,等于在帮模型复现某个来源。我的习惯是模板里保留风格描述,去掉具体作品名、角色名和段落引用。
2.3 域外观察篇:借的是分级方法,不是条文
域外观察那一章讲了两个法域在立法和风险治理框架上的进展,读的时候容易陷进条文对比里出不来。对工程团队真正有用的只有一件事:它们都在用"按风险分级"而不是"按技术分级"的思路。也就是说,判断一个功能该被多严格地对待,看的是它面向谁、处理什么数据、输出会不会被直接使用,而不是它用了多大的模型。
把这套方法搬到自己的项目上,我一般列五个判断项:是否面向公众开放注册、是否涉及未成年人、是否处理敏感个人信息、输出内容是否直接对外发布不经人工、是否用于影响个人权益的决策。五项里命中两项及以上,走高强度评审;命中一项,走常规评审;一项不中,登记备案即可。这套打分表写进需求模板后,产品同学提需求时自己就先分好级了,省掉大量来回。
要注意的是,域外框架里的具体条目和阈值是跟着当地立法走的,直接搬过来做合规判定会闹笑话。白皮书本身也是观察性质,不是规范性文件,条文口径必须以正式发布的文本为准。这一点在后面避坑那章还会展开。
3. 把风险章翻成风险登记表:九个字段、一套分级口径、一个生成脚本
风险清单如果只停留在文档里,三个月后一定没人看。让它活着的方式是变成一张可查询、可派工、可统计的表。这一章讲的是怎么把白皮书的风险条目落成登记表,以及怎么用一个小脚本把它变成评审会上能直接投屏的清单。
3.1 登记表的九个字段
字段设计的原则是:任何一个风险条目,扫一眼就知道谁负责、什么时候必须闭环、闭环的判据是什么。字段太少会变成一句空话,太多没人填。九个字段是我试过之后比较稳的一组。
| 字段 | 说明 | 填写要求 |
|---|---|---|
| id | 全局唯一编号 | 形如 R-001,按模块分段 |
| category | 风险大类 | 只能取知识产权、算法、数据与个人信息、伦理四值 |
| scene | 触发场景 | 写到具体功能点,如"客服问答自动回复" |
| risk | 风险描述 | 一句话,包含触发条件和后果 |
| likelihood | 可能性 | 1 到 5,按 3.2 的口径打 |
| impact | 影响 | 1 到 5,按 3.2 的口径打 |
| control | 现有控制措施 | 写已有的,没有就写"无" |
| owner | 责任人 | 必须是具体的人,不接受团队名 |
| status | 状态 | 待处理、缓解中、已闭环、已接受 |
likelihood和impact是全表唯一需要主观判断的地方,也是唯一容易吵架的地方。解决办法是把打分口径写死在表头注释里,谁打分谁负责解释。owner字段强烈建议做成必填校验,一张没有责任人的风险表,最后一定烂在共享盘里。
3.2 分级口径:可能性乘影响,落到处置时限
分级不用加权平均,加权平均的权重永远吵不完。直接用可能性乘影响,最高 25 分,然后按分数段映射到处置动作和时限。这个口径粗暴但好用,因为任何人都能在十秒内复算出结果。
| 分值区间 | 处置等级 | 动作要求 | 时限 |
|---|---|---|---|
| 15 到 25 | 阻断 | 上线前必须闭环,或降级功能范围 | 0 天 |
| 8 到 14 | 缓解 | 提交缓解方案并排期,允许带条件上线 | 14 天 |
| 1 到 7 | 接受 | 登记观察,纳入季度复核 | 90 天 |
打分的锚点要具体,否则每个人心里的"3 分"都不一样。我的锚点是这样:可能性 5 代表在当前流量下每天都会出现,3 代表每月出现若干次,1 代表理论上可能但从未观测到;影响 5 代表会直接导致对外内容错误或个人信息外泄,3 代表影响单个用户的体验但可人工纠正,1 代表内部可感知、用户无感。锚点写进模板,争议能少一半。
3.3 一个脚本把登记表跑成评审清单
登记表用 JSON 存,方便进版本库做 diff。下面这个脚本读取登记表,算出分值、等级和截止日期,渲染成一张 Markdown 表,直接贴进评审文档。
# risk_register.py —— 把风险登记表渲染成评审用的 Markdown 清单 import json from datetime import date, timedelta # 分级口径:score = 可能性 × 影响,最高 25 分 # 三元组含义:(分数下限, 处置等级, 时限天数) BANDS = [ (15, "阻断", 0), # 上线前必须闭环 (8, "缓解", 14), # 两周内提交缓解方案 (0, "接受", 90), # 登记观察,季度复核 ] def band_of(score): """按分值返回处置等级与时限,BANDS 必须按门槛从高到低排列""" for threshold, level, sla_days in BANDS: if score >= threshold: return level, sla_days return "接受", 90 def load(path): with open(path, encoding="utf-8") as f: data = json.load(f)["items"] # 无主风险直接拦截,避免登记表演变成许愿池 missing = [it["id"] for it in data if not it.get("owner")] if missing: raise ValueError(f"以下条目缺少责任人: {missing}") return data def render(items): rows = [] for it in items: score = it["likelihood"] * it["impact"] level, sla = band_of(score) due = date.today() + timedelta(days=sla) # 阻断级即时到期 rows.append( f"| {it['id']} | {it['scene']} | {it['risk']} | " f"{it['likelihood']} | {it['impact']} | {score} | " f"{level} | {it['owner']} | {due} |" ) head = ("| 编号 | 场景 | 风险描述 | 可能性 | 影响 | 分值 | 处置 | 责任人 | 截止 |\n" "|---|---|---|---|---|---|---|---|---|") return head + "\n" + "\n".join(rows) if __name__ == "__main__": print(render(load("risk_register.json")))配套的登记表片段长这样,直接放进仓库跟代码一起走评审:
{ "items": [ { "id": "R-001", "category": "数据与个人信息", "scene": "客服问答自动回复", "risk": "用户输入含手机号时被原样写入训练样本", "likelihood": 4, "impact": 4, "control": "无", "owner": "某后端同学", "status": "待处理" } ] }脚本逻辑很直白:likelihood乘impact得到分值,band_of按门槛从高到低匹配第一个满足的档位,所以BANDS的顺序不能乱,写反了会把阻断级降成接受级。时限用timedelta从当天起算,阻断级是 0 天即当天到期,这是刻意的——阻断级条目本来就不该有缓冲期。
参数上有三处可以按团队情况调。BANDS的门槛值,团队风险偏好保守可以调成 12 就阻断;sla_days按迭代周期调整,两周一个迭代的团队把缓解期设成 14 天刚好压在一个迭代内;owner校验从必填改成"必填且必须在通讯录里存在",能进一步减少无效填写。缺责任人就抛异常这个设计,是从一次事故里学来的——当时一张表里七条风险有五条责任人写的是"研发组",出事之后没人认。
4. 上线前卡三道闸:语料脱敏、交互留痕、输出抽检的落地参数
风险表和脚本解决的是"知道有什么风险",这一章解决"每天怎么防"。三道闸分别卡在数据进入模型之前、用户与模型交互之中、模型输出流向业务之后。三道都做成本会很高,但每道都有低成本的最小实现,关键是先有,再谈全。
4.1 第一道闸:输入侧的 PII 预处理
用户输入里带手机号、身份证号、邮箱、银行卡号是常态,这些东西一旦进了日志和训练样本,后面很难收场。最小实现是一个统一的脱敏入口,所有进入模型服务、日志系统和样本池的文本都先过一遍。
import re ID_CARD = re.compile(r"(?<!\d)(\d{17}[\dXx])(?!\d)") PHONE = re.compile(r"(?<!\d)(1[3-9]\d{9})(?!\d)") EMAIL = re.compile(r"([\w.+-]{1,64})@([\w-]+\.[\w.-]+)") BANK = re.compile(r"(?<!\d)(\d{16,19})(?!\d)") ID_W = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2] ID_CHECK = "10X98765432" def valid_id(s): """校验身份证末位,避免把 18 位订单号误判成身份证""" total = sum(int(c) * w for c, w in zip(s[:17], ID_W)) return ID_CHECK[total % 11] == s[17].upper() def luhn(s): """银行卡 Luhn 校验,同样用于降低误杀""" total, alt = 0, False for ch in reversed(s): d = int(ch) if alt: d *= 2 if d > 9: d -= 9 total += d alt = not alt return total % 10 == 0 def mask(s, head=3, tail=3): if len(s) <= head + tail: return "*" * len(s) return s[:head] + "*" * (len(s) - head - tail) + s[-tail:] def scrub(text): text = ID_CARD.sub(lambda m: mask(m.group(1)) if valid_id(m.group(1)) else m.group(1), text) text = PHONE.sub(lambda m: mask(m.group(1)), text) text = BANK.sub(lambda m: mask(m.group(1)) if luhn(m.group(1)) else m.group(1), text) text = EMAIL.sub(lambda m: m.group(1)[0] + "***@" + m.group(2), text) return text重点不在正则本身,而在两个细节。(?<!\d)和(?!\d)是前后边界,防止从一串长数字中间截取出 11 位当成手机号,没有这对断言,日志里一半的流水号都会被误掩。校验位判断是第二道过滤,身份证和银行卡都先验后掩,不合法就原样放行——这一步牺牲了一点漏检率,换回来的是排障时不用面对满屏星号。实际参数上,head和tail各留 3 位是我试出来的平衡点:留太少无法定位用户,留太多等于没掩。
如果业务需要"能还原",掩码就不够了,得用加盐哈希。做法是对原始值拼一个固定的盐再做 SHA-256,盐存在密钥管理里,不落代码库。代价是哈希后无法做模糊匹配,只能精确比对,所以通常只对身份证和银行卡这类强标识符用,手机号还是掩码更方便客服排查。
4.2 第二道闸:交互留痕的最小字段集
留痕不是把所有东西都记下来。全量记录对话原文,等于把个人信息风险从模型里搬到了日志里,风险没消失只是换了地方。最小字段集的原则是:能还原"谁在什么时候问了什么类型的问题、系统怎么响应的",但不保留可识别到人的原文。
| 字段 | 是否必存 | 说明 |
|---|---|---|
| trace_id | 必存 | 单次请求唯一标识,用于串联上下游 |
| 用户标识 | 必存 | 用内部 uid,不用手机号或邮箱 |
| 时间戳 | 必存 | 精确到毫秒,方便对齐告警 |
| 输入摘要 | 必存 | 脱敏后的前 N 字符,N 建议 200 |
| 输入哈希 | 必存 | 用于去重和相同问题聚类 |
| 输出摘要 | 必存 | 脱敏后内容,命中拦截规则时存全文片段 |
| 命中规则 | 必存 | 规则编号列表,空表示未命中 |
| 模型版本 | 必存 | 版本号加提示词模板版本 |
| 原始输入 | 条件存 | 仅命中高风险规则且进入人工复核时存 |
| 用户反馈 | 选存 | 点赞点踩,用于抽检加权 |
留存期限要跟业务场景挂钩,一般对话日志 90 天,进入人工复核的样本 180 天,训练样本池单独走审批。这组数字不是拍脑袋,是按"能不能在用户投诉的有效期内查到"倒推的。字段定完之后,落盘入口必须收敛成一个函数,任何绕过入口直接写日志的行为都要在代码评审里拦下来——我见过最典型的翻车是某个 SDK 自带的 debug 日志把完整请求打到了本地文件,上线三个月后才被发现。
4.3 第三道闸:输出抽检的分层方案
抽检的意义是给模型行为做持续采样,不是找茬。分层维度至少三个:场景、输出长度、是否命中敏感话题。每个层按固定比例抽,总量控制在人工可承受的范围内。
| 分层维度 | 分层方式 | 抽样比例 | 判定重点 |
|---|---|---|---|
| 场景 | 客服、营销文案、内部助手 | 客服 5%,其余 2% | 事实性、承诺性表述 |
| 长度 | 短于 100 字、100 到 500 字、长于 500 字 | 短 1%,中 3%,长 10% | 长文本更易出现自相矛盾 |
| 敏感话题 | 命中规则库的请求 | 30% | 拒答是否恰当、有无越权建议 |
| 用户负反馈 | 点踩或投诉 | 100% | 必须逐条归因 |
抽检样本的随机种子要固定并记录,否则每周抽出来的样本没法比较,趋势图全是噪声。判定维度建议只留四项:事实是否可溯源、有无侵权近似、有无歧视性表述、有无超出业务范围的承诺。四项各打通过或不通过,不搞五分制,五分制的评分者一致性太差,最后没人信。
抽检发现的问题要回流到两个地方:一是规则库,把新发现的高频问题变成拦截规则;二是评测集,把确认的坏案例加进回归测试。这条回流路径不通,抽检就变成每周写一份没人看的报告。
5. 避坑记录:拿这份材料做落地时翻车的五个瞬间
5.1 把观察性材料当条文逐条对照
现象是评审会上有人拿着白皮书里的某句话问"这条我们算不算违反",然后全场沉默。原因是把行业观察材料当成了规范性文本,白皮书本身是研究性质,它描述的是趋势和框架,条文口径要以正式发布的文本为准。解决办法很简单:白皮书只用来做风险识别和分级,凡是涉及"是否合规"的判断,一律回到正式文本,并且把引用出处写进评审记录。
5.2 只做输出端过滤,输入端一本糊涂账
现象是上线两个月后被追问语料来源,翻遍仓库只有一个data_final_v3.zip。原因是团队把精力全放在输出审核上,输入端只留了一个文件名。解决方式是建语料台账,字段至少包含来源标识、获取方式、授权凭证路径、抓取时间、页面条款快照、是否含个人信息、清洗版本号。抓取时同步存一份条款快照这件事特别容易被跳过,等条款改了再回头找证据,基本找不回来。
5.3 把研发豁免理解成"内测随便搞"
现象是小范围灰度被认定为对外提供服务,团队一脸懵。原因是"研发"和"对外提供"之间没有定义边界。资源在实践部分记录的那条边界值得抄进内部规范:不向公众提供服务的研发、测试场景与正式对外服务要分开。落到工程上就是三件事——灰度环境走白名单邀请、不开放公开注册、输出内容加水印和"测试中"标识。这三件事做了,边界就清楚了。
5.4 脱敏脚本一把梭,把业务字段也掩了
现象是线上排障时日志里订单号全变星号,客服没法核对。原因是正则只卡了长度没做校验,把 18 位订单号当成身份证掩了。解决办法是第 4 章那套"先校验后掩码",再加一层字段白名单:明确列出哪些字段永不脱敏,比如内部订单号、trace_id。上线前用一周真实日志跑一遍,人工抽查 200 条,统计误杀率和漏检率,两个数字都写进验收报告。
5.5 抽检只挑好案例,坏案例进不了评测集
现象是抽检报告每周都是"整体良好",上线后投诉集中爆发。原因是抽检样本来自手工挑选,天然避开了长尾场景。解决办法是固定随机种子、按场景分层抽样、把点踩和投诉样本 100% 纳入。更进一步,把确认的坏案例回流成回归测试用例,每次模型或提示词变更都跑一遍,这一条比任何流程文档都管用。
6. 进阶:攒一页合规证据包,把评审会一次过掉
评审会开到第三轮还在扯皮的团队,问题通常不是没做,而是拿不出证据。我的做法是给每个生成式功能配一个"证据包"目录,跟代码仓放在一起,按版本归档。目录结构固定成六项,每项对应一个验收人,缺项就不允许提评审。
| 证据项 | 内容 | 对应验收人 |
|---|---|---|
| 语料台账 | 来源、授权凭证、条款快照、清洗版本 | 数据负责人 |
| 模型卡 | 选型理由、版本号、评测集与基线分数 | 算法负责人 |
| 风险登记表 | 分值、处置等级、责任人、闭环记录 | 项目负责人 |
| 留痕样本 | 脱敏后的请求响应样本各 20 条 | 后端负责人 |
| 抽检报告 | 分层抽样结果、四项判定通过率 | 质量负责人 |
| 处置记录 | 拦截规则变更、坏案例回流清单 | 合规对接人 |
这六项不需要一次做全,第一版可以只做台账、模型卡、登记表三项,剩下的随版本补齐。关键是每项都要有版本号,能回答"上个版本是什么样"这个问题。评审会上最有说服力的一句话不是"我们做了",而是"这是上周三的抽检报告,通过率 94%,两个不通过项已经进了回归集"。
验证这套东西有没有真的跑起来,有个很土但有效的办法:随机挑一个上周的用户投诉,从 trace_id 一路查到语料来源和当时的模型版本,全程不超过十分钟,说明链路是通的;超过半小时或者中间断了一环,说明证据包只是摆设。我一般每个季度做一次这样的反向抽查,抽查记录本身也归档。
说个自己的教训。早前做一个内部问答助手,风险表填得很漂亮,二十多条风险一个不落,责任人也都写了。上线前一周我把表拉出来复核,发现"已闭环"那一列里,有六条的控制措施写的是"提示词里加了约束"。提示词当然算控制措施,但它不是可验证的控制措施——没人知道约束有没有生效,也没人测过绕过的情况。从那以后我每次填风险表,只要控制措施里出现"提示词"三个字,就强制要求补一条对应的评测用例,跑不出结果的当未闭环处理。这个习惯后来救过两次场,都是模型换了版本、约束悄悄失效的情况。
希望帮到你。
本文还有配套的精品资源,点击获取