三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

业务接 AI 前,先别急着调模型,先做输入脱敏层

业务接 AI 前,先别急着调模型,先做输入脱敏层

很多业务系统接 AI,第一步就错了。

不是模型选错,也不是 Prompt 写得不好,而是把原始数据直接丢给模型。

客户聊天记录,直接丢。
工单详情,直接丢。
合同内容,直接丢。
数据库日志,直接丢。
用户手机号、邮箱、订单号,也顺手带进去。

然后团队还会说一句:

“我们只是内部测试。”

这句话最危险。

因为 AI 接入业务后,真正的风险往往不是它答错,而是它看到了不该看的东西。

Google I/O 2026 之后,Google 把 AI 和 Agent 能力继续往搜索、开发工具和生产应用方向推进;开发者更新里也强调,从 prompt 到 production-ready application 的工具链正在变得更完整。

AI 越接近生产流程,输入层就越不能裸奔。

尤其是企业场景。

客服系统里有客户姓名、手机号、地址。
CRM 里有销售记录、报价、合同状态。
日志系统里可能有 token、cookie、内部接口。
财务系统里有订单金额、发票、付款信息。
代码仓库里有配置、密钥、内部域名。

这些东西不应该原样进入模型。

所以业务接 AI 前,第一层应该不是 Prompt,而是 Input Sanitizer,也就是输入脱敏层。

它要做三件事:

识别敏感信息。
替换敏感信息。
记录脱敏映射,但不要暴露给模型。

一个简单结构可以这样设计:

```python
from dataclasses import dataclass
from enum import Enum
from typing import Dict, List
import re
import uuid

class SensitiveType(str, Enum):
PHONE = "phone"
EMAIL = "email"
ID_CARD = "id_card"
TOKEN = "token"
ORDER_ID = "order_id"
API_KEY = "api_key"

@dataclass
class SensitiveMatch:
sensitive_type: SensitiveType
raw_value: str
placeholder: str
```

然后定义一些基础规则:

```python
PATTERNS = {
SensitiveType.PHONE: r"1[3-9]\d{9}",
SensitiveType.EMAIL: r"[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+",
SensitiveType.API_KEY: r"(sk|api|key)_[a-zA-Z0-9]{16,}",
SensitiveType.TOKEN: r"Bearer\s+[a-zA-Z0-9._-]+",
}
```

扫描文本:

```python
def scan_sensitive(text: str) -> List[SensitiveMatch]:
matches = []

for sensitive_type, pattern in PATTERNS.items():
for item in re.findall(pattern, text):
placeholder = f"[{sensitive_type.value}_{uuid.uuid4().hex[:8]}]"
matches.append(
SensitiveMatch(
sensitive_type=sensitive_type,
raw_value=item,
placeholder=placeholder
)
)

return matches
```

替换敏感信息:

```python
def sanitize_input(text: str) -> Dict:
matches = scan_sensitive(text)
sanitized = text

mapping = {}

for match in matches:
sanitized = sanitized.replace(match.raw_value, match.placeholder)
mapping[match.placeholder] = {
"type": match.sensitive_type.value,
"raw_value": match.raw_value
}

return {
"sanitized_text": sanitized,
"mapping": mapping
}
```

比如输入:

```text
客户手机号 13812345678,邮箱 test@example.com,反馈订单 ORDER_20260521001 无法支付。
```

脱敏后应该变成:

```text
客户手机号 [phone_xxxxxxxx],邮箱 [email_xxxxxxxx],反馈订单 ORDER_20260521001 无法支付。
```

这时模型仍然能理解问题:

这是一个客户反馈。
涉及手机号和邮箱。
问题是订单无法支付。

但模型不需要看到真实手机号和邮箱。

如果涉及订单号,也可以继续做占位:

```python
ORDER_PATTERN = r"ORDER_\d+"

def sanitize_order_id(text: str):
return re.sub(ORDER_PATTERN, "[order_id]", text)
```

输入脱敏层还要配合风险等级。

不是所有内容都只是替换一下就能送给模型。

可以分三层:

低风险:公开资料、普通文案、通用问题。
中风险:客户问题摘要、内部流程、非敏感业务数据。
高风险:身份证、银行卡、合同原文、密钥、生产日志、未脱敏客户数据。

高风险内容应该直接拦截,而不是脱敏后继续丢给模型。

```python
BLOCKED_TYPES = {
SensitiveType.API_KEY,
SensitiveType.TOKEN,
SensitiveType.ID_CARD,
}

def should_block(matches: List[SensitiveMatch]) -> bool:
return any(match.sensitive_type in BLOCKED_TYPES for match in matches)
```

完整处理:

```python
def prepare_ai_input(text: str) -> Dict:
matches = scan_sensitive(text)

if should_block(matches):
return {
"ok": False,
"reason": "blocked_sensitive_data",
"message": "输入包含高风险敏感信息,已阻止发送给 AI。"
}

result = sanitize_input(text)

return {
"ok": True,
"sanitized_text": result["sanitized_text"],
"mapping_count": len(result["mapping"])
}
```

注意,mapping 不应该传给模型。

mapping 只应该留在业务系统内部,用于必要的结果回填。

但这里还要补一句:真实工程里不能只靠正则。

正则适合识别手机号、邮箱、token、订单号这类格式稳定的字段,但很多敏感信息没有固定格式。

比如:

“客户住在台北信义区某某路附近”。
“这位客户是我们重点续约对象”。
“这段日志来自生产支付接口”。
“这个合同条款还没有对外公开”。
“这是内部报价,不要外传”。

这些内容不是简单正则能识别的。

所以更成熟的做法是三层组合:

第一层,规则识别。
用于手机号、邮箱、token、API key、身份证号、订单号。

第二层,模型分类。
让模型只判断“这段文本是否包含敏感业务信息”,而不是直接处理全文任务。

第三层,人工标注。
把误判和漏判样本沉淀成规则,让脱敏层不断迭代。

可以加一个分类结果:

```python
@dataclass
class RiskClassification:
risk_level: str
reason: str
suggested_action: str
```

例如:

```python
def classify_risk_with_model(text: str) -> RiskClassification:
# 这里实际工程中应调用内部合规模型或受控分类服务
# 返回 low / medium / high
return RiskClassification(
risk_level="medium",
reason="文本包含客户投诉内容,但未发现账号密码或密钥。",
suggested_action="sanitize_then_process"
)
```

这样系统就不是“只靠正则硬扫”,而是规则、分类、人工反馈一起工作。

这就是很多 Demo 和真实业务系统的区别。

Demo 只关心模型能不能回答。
业务系统要关心模型看到了什么。

前期比较不同模型对脱敏文本的理解能力,可以用 gpt57.com 跑同一批 sanitized input,看哪个模型在信息缺失的情况下仍然能准确分类、总结、生成回复草稿。但上线时,是否脱敏、是否拦截、是否记录审计,必须由自己的系统控制。

AI 接业务前,先别急着调模型。

先保证模型看不到不该看的东西。

这比 Prompt 更基础。

← 返回列表