前端智能编码工具部署前的配置核对把大模型代码审查接入 CI 后常见的两个问题是审查范围没有限制导致生成目录或大型依赖被送去分析构建变量边界不清导致本不该公开的配置进入客户端产物。它们与模型能力关系不大更多是交付链路缺少约束。本文把重点放在两件事构建时阻止敏感变量暴露以及为审查任务设置文件、时间和费用边界。具体阈值应根据仓库规模、CI 并发和模型计费方式调整。区分客户端变量与构建侧密钥前端项目需要区分构建侧变量与浏览器可读取的变量。接入大模型审查 SDK 时OPENAI_API_KEY或内部网关令牌应仅由 CI 的机密变量或服务端运行环境提供而不是进入前端可读取的配置。Vite 会把以VITE_开头的环境变量暴露给客户端。因此带有该前缀的变量不能存放密钥、内部令牌或数据库连接信息开发者可在浏览器产物和 Source Map 中读取这些值。可以在构建开始时校验客户端变量并在 CI 中配合密钥扫描。单靠命名规则不能代替密钥管理已泄露的值仍需要轮换。下面的 Vite 插件用来在打包前逐项审查环境变量。一旦发现敏感的前缀交叉或者缺漏 mandatory 字段立马挂断构建过程// vite-plugin-env-guard.ts import { Plugin } from vite; import z from zod; // 声明前端客户端可用的安全环境变量 Schema const clientEnvSchema z.object({ VITE_APP_TITLE: z.string().min(1), VITE_API_BASE_URL: z.string().url(), VITE_ENABLE_AI_ASSISTANT: z.enum([true, false]).transform(v v true), }); // 声明绝不允许暴露在客户端的前端构建期/Agent 密钥 Schema const sensitiveKeys [ OPENAI_API_KEY, LLM_GATEWAY_TOKEN, CODE_REVIEW_SECRET, DATABASE_URL ]; export function envGuardPlugin(): Plugin { return { name: vite-plugin-env-guard, configResolved(config) { const env config.env; // 1. 检查是否有敏感 Key 被赋予了 VITE_ 前缀 const leakedKeys Object.keys(env).filter(key { return key.startsWith(VITE_) sensitiveKeys.some(s key.includes(s)); }); if (leakedKeys.length 0) { throw new Error( [环境安全拦截] 检测到敏感密钥包含 VITE_ 前缀将被注入客户端 Bundle受影响字段: ${leakedKeys.join(, )} ); } // 2. 校验客户端变量合规性 const parseResult clientEnvSchema.safeParse(env); if (!parseResult.success) { console.error([环境安全拦截] 客户端环境变量校验失败:, parseResult.error.format()); throw new Error([环境安全拦截] 环境变量格式错误终止打包); } console.log(✅ [环境安全拦截] 环境变量隔离校验通过无密钥泄露风险); } }; }为审查任务限制输入和执行时间审查程序不宜默认扫描整个仓库。构建产物、锁文件、压缩资源和生成代码通常不适合作为模型输入先基于 Git diff、文件类型和大小过滤能降低等待时间也便于控制费用。审查节点应独立设置超时、并发和预算。超过限制时是否允许构建继续应由仓库的风险等级决定安全门禁可以失败并阻断提示型检查则可退回到常规 lint 结果。下方的代码展示了如何在 Node.js 端封装带超时控制与文件过滤的 Agent 调用器// agent-runner-guard.ts import fs from fs; import path from path; import { glob } from glob; interface ReviewOptions { maxFileSizeKb: number; timeoutMs: number; maxTokenBudget: number; ignorePatterns: string[]; } export class CodeReviewAgentRunner { private config: ReviewOptions; constructor(options: PartialReviewOptions {}) { this.config { maxFileSizeKb: options.maxFileSizeKb ?? 100, timeoutMs: options.timeoutMs ?? 15000, maxTokenBudget: options.maxTokenBudget ?? 50000, ignorePatterns: options.ignorePatterns ?? [**/node_modules/**, **/dist/**, **/*.min.js, **/pnpm-lock.yaml] }; } async filterSourceFiles(targetDir: string): Promisestring[] { const allFiles await glob(**/*.{ts,tsx,vue,js}, { cwd: targetDir, ignore: this.config.ignorePatterns, nodir: true }); const validFiles: string[] []; for (const file of allFiles) { const fullPath path.join(targetDir, file); const stats await fs.promises.stat(fullPath); const sizeKb stats.size / 1024; // 超过指定大小的文件直接忽略不传给 LLM if (sizeKb this.config.maxFileSizeKb) { validFiles.push(fullPath); } else { console.warn([Agent 过滤] 跳过大文件: ${file} (${sizeKb.toFixed(2)} KB)); } } return validFiles; } async executeReviewWithTimeout(filePaths: string[], reviewTask: (files: string[]) Promisestring): Promisestring { const controller new AbortController(); const timer setTimeout(() { controller.abort(); }, this.config.timeoutMs); try { console.log([Agent 进程] 开始审查 ${filePaths.length} 个前端源文件...); // 竞争执行超时降级 const reviewPromise reviewTask(filePaths); const result await Promise.race([ reviewPromise, new Promisenever((_, reject) { controller.signal.addEventListener(abort, () { reject(new Error([Agent 异常] 代码审查超时 (${this.config.timeoutMs}ms)触发自动降级)); }); }) ]); clearTimeout(timer); return result; } catch (err: any) { clearTimeout(timer); console.error(⚠️ [Agent 警告] ${err.message}); // 超时或报错后降级返回本地 ESLint 结果替代 return 审查 Agent 执行失败降级为常规 CI 通行卡。; } } }发布前的三个检查点第一尽早划分变量边界。敏感 API Key 放在 GitLab CI、GitHub Actions 或部署平台的机密配置中仅供需要它的服务端任务读取发布前检查静态产物和 Source Map。第二为 Token、文件数和耗时设上限。模型审查适合辅助发现风险点不应替代静态检查、测试或人工评审超大 Diff 和生成文件可先交给规则工具处理。第三明确失败策略。外部 LLM 服务会超时或不可用CI 应记录失败原因并按检查级别降级或阻断避免把不可控的网络调用变成发布流程的单点风险。