☰
用 TaoToken 统一通道给 DeepSeek/ChatGPT 上传 Word 前做敏感信息识别与脱敏
2026/9/28 6:56:24 网站建设 项目流程

1. 上传 Word 到 DeepSeek/ChatGPT 前,敏感信息到底藏在哪

把一份 Word 合同、简历或者项目周报丢给 DeepSeek、ChatGPT 之前,你有没有停下来想过:这份文档里到底有多少手机号、身份证号、邮箱、银行卡号?我见过太多人直接把带客户名单的 docx 拖进对话框,问一句"帮我总结一下",然后就没然后了。问题在于,大模型平台拿到的不是你屏幕上看到的那几段文字,而是整份文档的正文加元数据,包括作者名、最后修改人、公司内网路径这些你根本没注意的东西。

这篇要解决的就是这个场景:在 Word 文档送进 DeepSeek 或 ChatGPT 之前,先在本地把手机号、身份证、邮箱等敏感字段识别出来并脱敏,脱敏后的文档语义不变,照样能让模型读懂、总结、改写。适合谁?经常用 AI 处理商务文档、法务材料、HR 简历、财务表格的人,以及任何对数据外发有顾虑的开发者。

核心思路分三步:先搞清楚 docx 的文件结构,知道敏感信息落在哪个 XML 里;再用脚本把正文和元数据提取出来做正则识别;最后把命中的敏感串替换成掩码,重新打包成 docx。整个过程在本地完成,不依赖任何在线服务。识别和脱敏做完之后,再通过 TaoToken 统一通道调用 DeepSeek 或 ChatGPT,一个 Key 走通多个模型,省去到处配密钥的麻烦。

下面我会给出可复制的 Python 脚本、TaoToken 的接入配置,以及上传前后的对比验证动作。你不需要是安全专家,只要能跑 Python 就能跟下来。

2. 为什么用 TaoToken 统一通道承接脱敏后的调用

脱敏只是前半程,后半程是把干净文档送进模型。这里有个现实问题:你可能同时想对比 DeepSeek 和 ChatGPT 的输出,或者今天用 DeepSeek 省钱、明天用 ChatGPT 处理复杂推理。如果每个平台单独注册、单独管 Key、单独记额度,光是密钥管理就够烦的。

TaoToken 的做法是提供一个统一通道,你用同一个 API Key 就能调用包括 DeepSeek、ChatGPT 在内的多种模型。对脱敏这个场景来说,好处很直接:脱敏脚本跑完,输出一份干净的 docx 或纯文本,然后你只需要维护一个 Key、一套调用代码,切换模型只改一个模型名参数。官网在 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 入口是 https://taotoken.net/api ,注意 API 地址不带 UTM 参数。

需要提前准备的东西不多:一个 TaoToken 账号、一个 API Key、本地 Python 3.8 以上环境。Key 在控制台的 API Keys 页面生成,地址是 https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 。生成后先存到环境变量里,别硬编码进脚本,后面配置章节会给具体写法。

提示:脱敏和调用是两件独立的事。脱敏在本地做,调用走 TaoToken。即使你暂时不调用模型,脱敏脚本本身也值得单独跑一遍,至少知道自己文档里有什么。

3. 可复制配置:docx 解析、敏感识别与脱敏脚本

3.1 理解 docx 结构,定位敏感信息所在

docx 本质上是个 zip 压缩包,把test.docx后缀改成.zip解压,会看到一堆 XML。其中两个文件最关键:word/document.xml装正文,docProps/core.xml装元数据(创建者、最后修改者、创建时间)。敏感信息基本就藏在这两处。正文里的手机号、身份证在document.xml的<w:t>标签里,作者名、修改人则在core.xml的<dc:creator>和<cp:lastModifiedBy>里。

所以脱敏要覆盖两块:正文文本和元数据。很多人只处理正文,结果作者名带着真实姓名就发出去了,这是常见的漏点。

3.2 安装依赖

pip install python-docx lxml

python-docx负责读写 docx,lxml用来处理 XML 解析。如果你要处理更复杂的结构,也可以直接用标准库zipfile加re,下面脚本两种方式都涉及。

3.3 敏感信息识别正则

先定义识别规则。身份证、手机号、邮箱、银行卡这几类是高频项:

import re PATTERNS = { "id_card": re.compile(r"(?<!\d)(\d{6})(\d{8})(\d{3})(\d|X)(?!\d)"), "phone": re.compile(r"(?<!\d)(1[3-9]\d)(\d{4})(\d{4})(?!\d)"), "email": re.compile(r"([A-Za-z0-9._%+-]+)@([A-Za-z0-9.-]+\.[A-Za-z]{2,})"), "bank_card": re.compile(r"(?<!\d)(\d{4})(\d{4,12})(\d{4})(?!\d)"), }

身份证保留前 6 位和后 4 位,中间打码;手机号保留前 3 位后 4 位;邮箱保留首字符和域名;银行卡保留前 4 后 4。这样既脱敏又不破坏语义,模型仍能理解"这里有个手机号"。

3.4 正文脱敏脚本

from docx import Document def mask_text(text): text = PATTERNS["id_card"].sub(r"\1**********\4", text) text = PATTERNS["phone"].sub(r"\1****\3", text) text = PATTERNS["email"].sub(lambda m: m.group(1)[0] + "***@" + m.group(2), text) text = PATTERNS["bank_card"].sub(r"\1********\3", text) return text def desensitize_docx(src, dst): doc = Document(src) for para in doc.paragraphs: for run in para.runs: if run.text: run.text = mask_text(run.text) for table in doc.tables: for row in table.rows: for cell in row.cells: for para in cell.paragraphs: for run in para.runs: if run.text: run.text = mask_text(run.text) doc.save(dst) print(f"已脱敏保存: {dst}")

注意run是 Word 里格式一致的最小文本单元,直接改run.text能保留原有加粗、字号等格式。表格里的内容也要遍历,很多敏感数据恰恰在表格里。

3.5 元数据脱敏

正文处理完,元数据不能漏:

import zipfile, shutil, os def clean_metadata(src, dst): tmp = dst + "_tmp" with zipfile.ZipFile(src, "r") as zin: with zipfile.ZipFile(tmp, "w", zipfile.ZIP_DEFLATED) as zout: for item in zin.infolist(): data = zin.read(item.filename) if item.filename == "docProps/core.xml": content = data.decode("utf-8") content = re.sub(r"<dc:creator>.*?</dc:creator>", "<dc:creator>anonymous</dc:creator>", content) content = re.sub(r"<cp:lastModifiedBy>.*?</cp:lastModifiedBy>", "<cp:lastModifiedBy>anonymous</cp:lastModifiedBy>", content) data = content.encode("utf-8") zout.writestr(item, data) shutil.move(tmp, dst)

这个函数把core.xml里的创建者和最后修改人替换成anonymous,其余文件原样保留,保证 docx 结构完整。

3.6 一键串联

if __name__ == "__main__": src = "原始文档.docx" mid = "正文已脱敏.docx" dst = "最终脱敏.docx" desensitize_docx(src, mid) clean_metadata(mid, dst) os.remove(mid) print("全流程完成")

跑完你会得到一份正文和元数据都处理过的 docx,用 Word 打开格式正常,敏感字段已变成掩码。

4. 验证请求:脱敏前后对比与 TaoToken 调用

4.1 脱敏前后对比

先做本地验证。写个小脚本把原文和脱敏后的文本都打印出来对比:

from docx import Document def dump(path): doc = Document(path) return "\n".join(p.text for p in doc.paragraphs if p.text.strip()) print("=== 脱敏前 ===") print(dump("原始文档.docx")[:500]) print("=== 脱敏后 ===") print(dump("最终脱敏.docx")[:500])

重点看三处:手机号中间四位是否变成****,身份证中间十位是否打码,邮箱@前是否只剩首字符。如果还有漏网的,检查是不是被拆到了多个run里——Word 有时会把一个手机号拆成几段,这种情况需要先合并段落文本再替换。

4.2 通过 TaoToken 调用模型

脱敏确认无误后,把干净文本送进模型。先配置环境变量:

export TAOTOKEN_API_KEY="你的Key"

调用示例(OpenAI 兼容格式):

import os from openai import OpenAI client = OpenAI( api_key=os.environ["TAOTOKEN_API_KEY"], base_url="https://taotoken.net/api" ) resp = client.chat.completions.create( model="deepseek-chat", messages=[ {"role": "system", "content": "你是文档摘要助手。"}, {"role": "user", "content": dump("最终脱敏.docx")} ] ) print(resp.choices[0].message.content)

想换 ChatGPT 就把model改成对应的模型名,Key 和 base_url 都不用动。这就是统一通道的价值:脱敏脚本输出一份干净文本,调用侧只改一个参数就能横向对比不同模型。

4.3 成功结果长什么样

模型返回的摘要里应该出现"某手机号 138****5678"这类掩码形式,而不是完整号码。如果模型能正常总结出文档要点,说明脱敏没有破坏语义;如果返回内容里出现了完整敏感串,说明脱敏有遗漏,回到 4.1 排查。

5. 本篇常见错排查

问题一:脱敏后 docx 打不开或提示损坏。多半是重新打包时目录结构错了。用zipfile重写时,writestr的item.filename必须保持原路径,不能加额外前缀。如果你用 7z 手动压缩,注意不要多套一层文件夹,压缩包根目录下应该直接是word/、docProps/这些。

问题二:手机号没被替换。Word 会把连续文本拆成多个run,比如"138"和"12345678"分属两个 run,单个 run 内匹配不到完整号码。解决办法是先合并段落文本再替换,或者用paragraph.text整体处理后再重建 run。简单做法:对每个段落,把para.text脱敏后清空所有 run,写入一个新 run。

问题三:元数据替换后 Word 提示修复。core.xml的命名空间前缀不能动,只替换标签内的文本内容。如果你把<dc:creator>整个标签删了,Word 会报错。用正则只替换标签中间的内容最安全。

问题四:调用返回 401。检查TAOTOKEN_API_KEY是否设置成功,base_url是否写成https://taotoken.net/api(不带 UTM)。Key 在 https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 生成,注意别把控制台地址和 API 地址搞混。

问题五:模型读不到文档内容。如果你直接把 docx 二进制传给模型,它读不懂。正确做法是先用脚本提取纯文本,或者把脱敏后的 docx 转成 txt 再传。本文的dump函数就是干这个的。

问题六:脱敏过度导致语义丢失。比如把所有数字都打码,模型就看不懂金额和日期了。正则要精确到敏感字段类型,别用宽泛的\d+一刀切。

6. 把脱敏接进你的日常 AI 工作流

整套流程跑通之后,你可以把它固化成一个命令行工具:python desensitize.py 输入.docx 输出.docx,处理完再调用模型。对于经常批量处理文档的人,可以加个目录遍历,一次脱敏整个文件夹。

如果你还在选模型阶段,想先对比 DeepSeek 和 ChatGPT 对同一份脱敏文档的理解差异,可以直接在模型对话页面测试,地址是 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite 。长期做编码或 Agent 类任务、需要稳定调用额度的,可以看 Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 。接入细节和参数说明在文档里:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 。

最后提醒一句:脱敏脚本的正则要根据你的实际文档调整。身份证有 15 位老格式,手机号有带国际区号的写法,邮箱有企业域名后缀,这些都需要你在PATTERNS里补充规则。跑之前先用几份样本测试,确认掩码位置正确、格式没坏,再批量处理。数据外发这件事,宁可多花五分钟本地验证,也别等发出去了才后悔。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询