
在聊 Aileaks 之前我想起一个常见的开发场景。做 LLM 应用时为了排查 Agent 的工具调用异常团队习惯把模型的完整输出导成 JSON存到 debug 或 eval 目录。有些输出是全链路 trace记录从用户输入、检索结果、模型思考过程到最终回复的每一步。直到某天有人在一个提交里看到一段不该出现的内部密钥字符串才发现这些推理轨迹reasoning trace已经不只是一份调试材料更像一份泄密材料。这里先给出一个判断Aileaks 这类工具解决的核心问题不是“代码里有没有密钥”而是“密钥和敏感信息混在模型思考过程中被当成普通日志提交进了代码仓库”。它的价值不只是多一个扫描器而是在工程流程里确立一个观念——模型输出尤其是推理轨迹本身就应该被当成敏感产物来管理。1. 推理轨迹正在变成一种“新型敏感文件”1.1 什么是 LLM 推理轨迹推理轨迹英文通常叫 reasoning trace指的是模型在生成最终回答之前产生的中间推理信息。过去我们调用一个聊天模型往往只关心最终输出但从具备复杂推理能力的模型流行开始模型会先产生一段内部思考过程再基于这段思考给出答案。与此同时Agent 应用的兴起让“思考”不只在模型内部完成而是外化成了可见的步骤用户输入、任务拆解、工具选择、工具返回、结果整合、最终回答。每一步都会被框架记录下来形成一条很完整的 trace。这类 trace 的常见载体包括Agent 框架的日志文件比如 LangChain、LlamaIndex 或自研 Agent 框架写出的 JSON 日志。调试目录下保存的outputs.json、step_result.jsonl。评估集里的输入输出对通常会连带保存完整的检索上下文和工具返回。在线可观测性平台导出的 trace 快照用于本地做问题复现。压测或回归测试时留存的全量会话记录。这些文件有一个共同特点它们看起来像结构化日志但内容远比普通日志更“密”。普通日志记录的是系统状态和错误码而推理轨迹记录的是模型看到了什么、模型决定怎么办、工具又返回了什么。这相当于把你应用内部的逻辑链完整暴露在文件系统里。1.2 敏感信息是怎么混进推理轨迹的敏感信息进入推理轨迹的路径通常有三条。第一条是上下文复述。如果系统提示或检索到的上下文里包含 token、数据库连接字符串、内部域名模型在推理时完全可能把相关段落转述进输出甚至原样带出。第二条是工具调用回显。Agent 调用一个内部接口获取数据HTTP 响应头或响应体里带着鉴权信息、内部 IP、真实用户 ID而 trace 在记录工具返回时不知道过滤直接把原始结果写进去。第三条是模型记忆或参数污染。模型在测试环境或预训练语料里见过真实配置推理时基于记忆生成了一些“看似真实”的敏感字段即使不准确也可能给阅读者提供有用线索。更麻烦的是这类信息很少以标准密钥格式出现。它可能是“admin_user: service_account / password: xxxxx”这样的自然语言段落也可能是一段自定义 base64 编码的 token。规则引擎很难提前写出对应的模式和熵阈值。如果你看过真实 Agent 的 trace 文件会发现里面经常混着加密哈希、请求 ID、会话 token、内部 URL、甚至一些看起来像是临时密码的字段。每一个单独看都不像“密钥”但拼接在一起已经足够让人还原出一套内部系统的地图。1.3 最容易踩中这个坑的开发阶段这类泄露并不是偶发而是有明确的高发期。最典型的是 Agent 开发早期。这个阶段团队为了调试 prompt 和工具链会把完整 trace 保存下来反复对比稍不注意就会把文件提交进仓库。其次是做评估集和回归测试的时候。为了保证可复现开发者会把某次运行的所有输入、检索结果、输出结果都存成 JSON 快照然后放进tests/或eval/。还有一个不太容易察觉的阶段写文档和写博客的时候。为了说明某个 Agent 流程开发者会把一段去掉了名字但保留内部信息的 trace 片段贴到 Markdown 文件里。对阅读者来说这段内容只是示例对安全来说这可能就是一次内部信息外传。注意不要因为文件是 JSON 格式且有日志字样就默认它可以公开。推理轨迹需要和源代码同等对待。2. 传统密钥扫描工具为什么拦不住这类泄露2.1 它们的检测逻辑建立在“格式已知”之上GitLeaks、TruffleHog、detect-secrets 这类工具解决的是另一个问题代码里硬编码了密钥且密钥有固定格式。比如 AWS Access Key 的AKIA开头、GitHub token 的ghp_前缀、私钥文件里的BEGIN RSA PRIVATE KEY标记。这类扫描器通常先用正则或熵检测找出候选片段再调用对应服务验证是否有效。这套逻辑在传统代码仓库里很有效但面对推理轨迹文件时会有三个明显局限。第一它对自定义无前缀密钥基本无能为力。如果某个内部 token 是一串 32 位随机十六进制字符没有业务前缀扫描器很难判断它到底是不是敏感字段。第二它对纯文本上下文中夹带的敏感字段不敏感。正则扫描是按模式匹配不会理解“The users password is ...”示例这句话里的语义。第三它不会判断“当前文件是不是模型输出”因此无法利用模型输出的语义特征做判断。比如推理轨迹里出现The tool returned auth: e2b4f91a-8d6c-4f1b-9c3c-813df2a1... (valid until 2026-05-30)这不是任何已知密钥格式。普通扫描器大概率会放过。但如果你知道这是模型推理轨迹就会意识到这段 auth 值很可能来自于真实工具返回值得进一步确认。2.2 缺少“文件是推理轨迹”这个判断维度传统扫描器的核心假设是“我扫的是代码密钥以字符串形式嵌入代码里”。而推理轨迹文件的形态完全不同它本身可能是 JSON、JSONL、Markdown 或普通文本模型输出会包含自然语言、代码块、结构化字段和工具返回。密钥不是“嵌入”在代码里而是“生长”在模型对上下文的理解里。如果扫描器能先判断“当前文件可能是推理轨迹”它就可以做两件事。第一把整个文件的“信息敏感度”当作检查对象而不仅仅是匹配字符串。第二在发现异常时给出更高的置信度因为推理轨迹是模型输出的中间产物里面的异常字段往往是从真实上下文或工具返回里带出来的很可能就是有效风险。这就是 Aileaks 这类工具和传统扫描器的最大差异。它想扫描的不只是“这些字符串长得像不像密钥”而是“这一段模型思考过程里是否携带了不应被提交的内部信息”。换一个说法传统工具在找字符串这类工具在找上下文风险。2.3 规则越多噪音越大越容易失去信号密钥扫描工具在大型仓库里还有一个体验问题命中模式很多但真正需要处置的风险很少。尤其当推理轨迹文件被提交后里面会有大量看似随机的字符串比如模型生成的 ID、会话引用、工具返回的请求参数。传统扫描器会把这些都标记为高熵字符串然后开发者看多了就会把扫描结果当成噪音。真正有效的做法是先缩小检查范围。比如只检查“可能是推理轨迹”的文件或者只在模型输出上下文中做敏感字段检测。范围缩小之后误报率会大幅下降扫描结果才值得被认真对待。这个“先识别范围再做精细判断”的思路也正是 Aileaks 这类工具在定位上区别于传统扫描器的原因。3. Aileaks 的定位扫描的不是密钥而是推理轨迹的风险3.1 从项目标题看它的切入点Aileaks 是一个出现在 Show HN 上的项目。它的标题很简短扫描代码仓库检测泄露的 LLM 推理轨迹敏感信息。翻译过来它瞄准的场景非常具体代码仓库里存在 LLM 推理轨迹文件而文件里藏着不该出现的敏感信息。这个切入点有两个好处。第一它把问题从“所有密钥泄露”缩小到“推理轨迹相关泄露”扫描范围可控。第二它把检查对象从“密钥格式”扩展到了“模型输出的敏感度”能覆盖传统工具无法识别的自定义 secret。这类工具和传统 secret scanner 可以形成互补。传统工具仍然负责防守.env、硬编码密钥、配置文件等常规风险而 Aileaks 类工具专门处理模型输出时代的灰色地带。3.2 这类工具的典型处理流程由于我目前没有拿到它的完整 README 和源码下面这段是基于同类工具的通用做法做出的推断。实际使用时请先阅读项目文档确认命令、参数和支持范围。一个合理的处理流程通常是输入一个仓库路径或一个 diff 范围。遍历文件先按目录名、扩展名、内容特征筛选出可能是推理轨迹的文件。对候选文件做敏感信息检测既做模式匹配也做高熵和上下文分析。输出报告文件路径、疑似泄露片段、泄露类型、置信度。可选地在 CI 中通过 exit code 控制构建失败。筛选推理轨迹文件时常见的目录特征可能包括debug/、traces/、eval/、outputs/、logs/、runtime/内容特征可能包括reasoning、steps、tool_call、assistant、messages、role等字段。检测的敏感信息类型通常包括常见 API key、token 前缀。高熵字符串比如自定义 token、密码、加密哈希。内部域名、IP、端口组合。数据库 DSN 或连接字符串。关键字上下文比如password、secret、auth、token、Bearer附近的高风险字符串。专有提示词模板或系统提示词。这只是一个通用画像。具体项目支持哪些检测器、能否自定义规则、性能如何都要以 README 为准。3.3 它真正改变的是什么传统密钥扫描器告诉你如果仓库里有一个固定格式的密钥我就标记它。Aileaks 类工具想做的是如果模型思考过程里携带了不应该出现的敏感信息我就把它暴露出来。这个转变看起来不大但影响的是开发习惯。以前团队处理泄露的方式是“删掉这个文件重新提交”。现在正确的处理方式变成了在模型输出落盘之前就做脱敏防止敏感内容进入仓库。这背后的思维变化是把推理轨迹当作可复制的敏感产物来管理而不是一坨可以随手丢进 git 的调试日志。我甚至觉得这种工具更大的价值不在扫描本身而在于它会在 CI 里“红一次”。那一次红灯会让团队真正意识到模型输出不是无价值的日志而是需要遵守安全约束的产物。4. Agent、RAG 和日常开发里最容易泄露的几种文件4.1 Agent 调试日志Agent 开发中的一次会话可能有几千行 trace。为了定位 prompt 效果差异很多人会把完整输出保存成 JSON 放进项目仓库。这类文件里系统提示词、检索结果、工具返回、模型内部步骤全部集中在一起。如果本地开发时配置里带了真实 API key并且这些配置被工具返回读取过trace 中就会原样出现。处理建议在本地调试时不要把带敏感上下文的 trace 写到项目根目录更不要直接提交。保存前先做一个简单的过滤脚本把 Authorization 头、密钥字段、内部域名替换成占位符。4.2 评估集和基准数据评测集看起来最无辜因为开发者只是为了验证效果。但一个典型的 RAG 评估集会包含 query、retrieved context、generated answer。如果 retrieved context 是从真实生产环境抓取的内部文档就可能包含内部 API 文档、配置示例、甚至数据库 schema。更麻烦的是评测集往往会被长期保存在仓库里成为“看起来合理但实际涉密”的文件。4.3 向量库导出文件团队为了调试 embedding 效果会把向量库导出成 JSONL 用于分析。向量库中的原始分块文本如果来自内部知识库那这个导出文件就相当于一份内网文档全集。它可能不包含密钥但泄露的业务细节和内部逻辑往往比密钥更敏感。这类文件建议放到单独的对象存储或内部共享目录做好访问控制不要直接放进代码仓库。4.4 提示词版本管理目录为了管理提示词迭代有些团队会在仓库里建prompts/目录这本身是好事。但要注意一个问题如果 debug 时保存的“带上下文的完整 prompt 展开结果”也被放进这个目录就可能出现真实用户名、真实密钥和内部策略。提示词目录应当只保存模板本身不要保存运行时展开后的完整内容。4.5 云端日志与本地导出在线可观测性平台会把 trace 持久化并提供下载接口。开发者为了排查问题会把云端 trace 导出到本地再手工分析。这类导出文件一旦解压到项目目录同样会成为仓库里的“隐藏敏感文件”。如果团队有这份导出习惯建议在导出后立即做脱敏或者设置导出文件默认不进入 git 跟踪。5. 怎么把这类检查落地到自己的工作流5.1 先做小范围盘点不要一上来全量扫描无论是 Aileaks 还是类似工具第一次使用时都不建议直接扫整个 git 历史。历史提交里可能积累了大量 trace 文件全量扫描的结果只会让你不知所措。更稳妥的做法是先选最近 20 个 commit 或最近的 pull request diff跑一次 scan-only。看看报告输出的内容是否合理有没有大量误报再决定下一步。小样本验证可以帮你理解工具的规则和默认行为也能在正式启用前先和团队对一下预期。5.2 CI 接入的稳妥顺序把扫描工具接入 CI 时我建议按照这个顺序来先只输出报告不设置非零退出码。这样它只是一个只读观察者不会打断开发。连续跑一两周统计命中数量和误报比例。把明显不是问题的片段加入 ignore 白名单。确认稳定后再把高风险类型设置为失败条件。最后再决定是否对所有提交强制拦截。这个顺序的核心是一条经验如果一个安全工具刚上线就频繁让 CI 变红团队很快会把它关掉或者学会忽略红灯。先让它“有结果、低打扰”再逐步收紧安全工具才能真正活下来。注意先以 scan-only 模式运行不要一上来就阻塞 merge。你要先给团队留出修正误报的时间。5.3 和传统 secret scanner 并行使用Aileaks 类工具是现有密钥扫描的补充不是替代。两者的关注对象不同适合同时运行扫描器类型关注对象典型场景传统 secret scanner.env、硬编码、密钥文件、固定格式 token开发者把 credentials 提交到代码仓库Aileaks 类工具推理轨迹、模型输出、trace 文件模型思考过程中夹带敏感信息传统 secret scanner 可以继续解决“原格式密钥泄露”Aileaks 类工具解决“语义上下文中的敏感字段泄露”。两者并行才能覆盖 AI 应用开发里的大多数风险点。5.4 从源头减少模型输出进入仓库扫描工具做得再好也比不上流程层面的预防。我建议在你的项目里做这几件事# .gitignore 示例忽略常见推理轨迹产物 debug/ traces/ eval_outputs/ *.trace.json *.trace.jsonl在.gitignore里明确忽略推理轨迹相关目录这是第一层防线。如果某些文件必须提交可以先运行一个脱敏脚本把 Authorization 头、密码字段、内部域名替换成占位符。此外可以在CONTRIBUTING.md里写清楚模型输出必须脱敏后才能提交。如果团队使用了 pre-commit 钩子也可以对新增的 JSON、JSONL 文件做一次快速检查阻止明显的 trace 文件进入提交。5.5 一个可复用的引入新扫描器判断框架不管是 Aileaks、还是未来出现的类似工具当你决定在项目里引入一个新的安全扫描器时都可以用下面这个四步框架先明确它要解决的问题边界。它到底检测哪一类风险覆盖不了哪些风险用小样本验证。不要全量扫描不要只靠 README 上的宣传做判断。评估误报率和维护成本。没有人维护的扫描规则最终只有两种结局被关掉或者天天被忽略。再决定是否进入 CI 强制检查。进入强制之前确保团队有处理误报的路径。这个框架同样适用于 Aileaks。它能帮你避免“装了一个看起来很安全、实际没人看的工具”这种假安全感。6. 边界、局限和更长期的事情6.1 它不解决哪些问题Aileaks 类工具的有效性是有限度的。下面这几类问题它基本管不到如果模型在对话过程中已经把密钥输出给用户但没有持久化到仓库里仓库扫描器无法检测。如果密钥是在运行时从环境变量读取不存在于任何文件中它也无能为力。如果团队把 trace 存在外部可观测性平台没有同步到本地仓库仓库扫描器看不到平台内部数据。如果提示词本身不含密钥但包含高度机密的业务逻辑、未公开策略或潜在敏感的个人信息工具只能给出启发式警告最终仍需要人做判断。所以在使用这类工具时要保持一个清醒的预期它是你安全防御链上的一环不是全部。6.2 把推理轨迹纳入安全策略我见过不少团队在第一次遇到 trace 泄露问题时第一反应是把这个文件删掉、重新提交然后不再深究。但真正值得做的是把“推理轨迹”这个产物纳入安全策略保存时即脱敏在 trace 落盘之前过滤掉高风险的 header、参数、密钥字段。区分 debug 输出和正式产物debug 输出默认不进入版本控制。建立定期审计每隔一段时间扫一遍历史 commit排查是否有 trace 悄悄进入。明确告警接收人扫描结果不能只发给一个机器人要有真人定期处理。如果团队在开发 AI 应用却没有考虑过“模型输出落在哪里、谁能读取、是否会进入 git”那其实是在用传统软件的思维方式应对新的安全风险。推理轨迹和源代码一样是需要被权限、版本、审计和清理共同约束的产物。6.3 回到主判断Aileaks 这类工具的价值不在于它比传统密钥扫描器更会找 API key而在于它提出了一个更准确的问题模型思考过程中到底携带了多少你不希望公开的信息这个问题在以前很少被追问因为大家默认密钥只会出现在.env或配置文件中。但 AI 应用开发改变了这种局面。模型能够读取大量上下文然后把上下文中的内容揉进输出里。推理轨迹作为“最容易原样保留上下文信息的产物”正在成为一个新的泄露窗口。如果你已经开始在 CI 里跑这类扫描那说明你已经意识到模型输出和代码一样是需要被约束的工程产物。这个意识往往比工具本身更能避免下一次泄露。以后我在评审 AI 应用代码时也会多看一眼debug/和traces/目录。这倒不是不信任同事而是这类问题太隐蔽了。工具能帮你拦截一部分风险但更关键的习惯是不要假设模型输出只属于模型自己。它一旦落盘、提交、被 clone 出去就是你项目的另一份源代码。