当 AI 从演示环境进入生产系统,团队面对的已经不只是模型效果问题。输入数据能否发送给外部模型、提示词是否可以进入日志、代理能否修改认证代码、生成的补丁由谁批准,这些都必须成为明确且可审计的工程决策。
材料介绍的两个线上认证 cohort,分别聚焦生产 AI 系统中的安全与隐私决策,以及编码代理进入现有代码库后所需的验证。两者看似分属安全治理和软件工程,实质上解决的是同一个问题:不能因为 AI 输出看起来合理,就默认它可以被信任。
生产 AI 的边界不只在模型 API
生产系统中的风险往往发生在模型调用前后,而不只是模型本身。一次普通请求可能经过用户界面、业务服务、检索数据库、模型供应商、日志平台和人工审核系统。每增加一个节点,就增加一次数据泄露或权限扩大机会。
团队至少需要回答以下问题:
| 决策点 | 需要明确的内容 |
|---|---|
| 数据分类 | 哪些数据属于公开、内部、机密或受监管数据 |
| 模型边界 | 哪类数据允许发送给外部模型,哪些只能由私有部署处理 |
| 数据留存 | 提示词、响应、向量和工具调用记录保存多久 |
| 工具权限 | 模型可以查询什么、修改什么、触发什么外部操作 |
| 失败方式 | 模型不可用、拒答或输出异常时,系统如何降级 |
| 审计责任 | 谁批准策略,谁能查看日志,谁处理安全事件 |
尤其要警惕“为了调试而记录全部内容”。原始提示词可能包含姓名、访问令牌、客户文档或内部源码。更稳妥的做法是默认只记录请求 ID、模型版本、耗时、令牌数量、策略结果和经过脱敏的错误摘要;需要临时查看原文时,再通过限时授权和审计流程开放。
还要把提示注入视为权限问题,而不只是内容问题。如果模型可以调用搜索、数据库、邮件或部署工具,那么恶意文本就可能诱导它越权操作。防线应放在工具执行层:校验参数、限制资源范围、使用最小权限凭据,并对不可逆操作要求人工确认。
编码代理交付的是候选变更,不是可信结论
编码代理可以快速浏览仓库、修改多个文件并运行测试,但它并不了解所有隐含约束。现有代码库通常包含历史兼容要求、部署惯例、权限边界和未写进测试的业务规则。
因此,代理生成的代码应被视为一个不受信任的拉取请求。验证至少分为四层:
- 变更范围验证:代理是否只修改了任务允许的目录,是否碰触认证、迁移、基础设施或 CI 配置。
- 静态验证:格式化、类型检查、依赖审计和常见危险模式扫描是否通过。
- 行为验证:单元测试、集成测试、契约测试以及关键回归测试是否覆盖了变更。
- 人工验证:审查者是否理解变更目的、失败路径、权限影响和回滚方式。
测试通过不等于变更正确。如果代理修改了测试,使错误实现与错误断言同时通过,流水线仍会显示绿色。关键测试应由仓库维护者掌控;对于高风险模块,可以禁止代理直接修改基准测试,或者要求单独审批。
可以这样实践:给代理补丁增加本地验证门禁
下面是一个可改造的最小验证脚本。它并非材料所指定的工具,而是一种实践示例:扫描新增代码中的疑似密钥和危险调用,识别高风险文件,然后运行 Python 编译检查与测试。
将脚本保存为 tools/verify_agent_change.py:
#!/usr/bin/env python3
import fnmatch
import os
import re
import subprocess
import sys
def run(args):
return subprocess.run(args, text=True, capture_output=True)
base = os.getenv('VERIFY_BASE')
target = f'{base}...HEAD' if base else 'HEAD'
diff_result = run(['git', 'diff', '--unified=0', target])
files_result = run(['git', 'diff', '--name-only', target])
if diff_result.returncode != 0 or files_result.returncode != 0:
print('Unable to read the Git diff.', file=sys.stderr)
sys.exit(1)
changed_files = [line for line in files_result.stdout.splitlines() if line]
added_lines = '\n'.join(
line[1:]
for line in diff_result.stdout.splitlines()
if line.startswith('+') and not line.startswith('+++')
)
high_risk_patterns = [
'.github/workflows/*',
'auth/*',
'infra/*',
'migrations/*',
]
high_risk_files = [
path
for path in changed_files
if any(fnmatch.fnmatch(path, pattern) for pattern in high_risk_patterns)
]
rules = {
'possible hard-coded secret': re.compile(
r'''(?i)(api_key|secret|token|password)\s*[:=]\s*['"][^'"]{8,}'''
),
'shell execution enabled': re.compile(r'shell\s*=\s*True'),
'dynamic eval call': re.compile(r'\beval\s*\('),
}
failed = False
for label, pattern in rules.items():
if pattern.search(added_lines):
print(f'BLOCKED: {label}')
failed = True
if high_risk_files and not os.getenv('REVIEWED_BY'):
print('BLOCKED: high-risk files require human review:')
for path in high_risk_files:
print(f' - {path}')
failed = True
if failed:
sys.exit(2)
checks = [
[sys.executable, '-m', 'compileall', '-q', '.'],
[sys.executable, '-m', 'pytest', '-q'],
]
for check in checks:
print('+', ' '.join(check))
result = subprocess.run(check)
if result.returncode != 0:
sys.exit(result.returncode)
print('Verification passed.')
运行前安装测试依赖,并指定要比较的基线分支:
python -m pip install pytest
git fetch origin main
VERIFY_BASE=origin/main python tools/verify_agent_change.py
如果变更涉及高风险目录,应先由相应负责人审查,再显式记录审核者:
REVIEWED_BY=alice VERIFY_BASE=origin/main \
python tools/verify_agent_change.py
REVIEWED_BY 只是示例中的本地信号,不应直接当作可靠的审批机制。在真实 CI 中,可以把它替换为受保护环境、CODEOWNERS、合并审批规则或内部变更管理系统提供的不可伪造状态。脚本中的正则也只是启发式检查,不能代替专门的密钥扫描、静态分析和依赖漏洞工具。
对于 JavaScript、Go 或 Java 仓库,可以保留变更范围检查,将最后的命令替换为项目已有的 npm test、go test ./...、mvn verify 等命令。关键不是统一技术栈,而是让代理无法绕开仓库原有的验证路径。
把安全策略和开发流程连起来
生产 AI 安全与编码代理验证不应由两个团队各自维护一套孤立文档。更有效的方式是把策略落到同一条交付链上:
- AI 功能提交设计时,记录数据分类、模型供应商、留存期限和工具权限。
- 代理开始工作前,声明允许修改的目录、禁止触碰的文件和必须执行的测试。
- 拉取请求中保留代理提示、关键假设、验证命令和测试结果,但不要记录敏感提示原文。
- 涉及认证、支付、数据迁移、基础设施或隐私策略时,自动提升风险等级并要求领域负责人审批。
- 上线后监控拒绝率、异常工具调用、数据泄露告警和回滚情况,而不是只看模型准确率。
采用这类流程时,不必一开始就建设庞大的治理平台。可以先选择一个真实 AI 功能和一个代理辅助仓库,定义数据边界、高风险目录、最低测试集与审批人,再观察哪些门禁真正拦截了问题。自动化适合验证可重复的事实;涉及业务意图、隐私取舍和不可逆操作的判断,仍应保留清晰的人类责任边界。