5.5 KiB
工作经历 AI:正式环境配置与调用保护
日期:2026-10-26。面向后端与运维;A7 候选的部署操作说明,不代表已发布或合规审批通过。
1. 正式环境配置
不再要求 dev,也不要为启用 AI 改动现有服务的数据库、JWT、短信等 profile。保持原 profile,显式设置以下非秘密项:
AI_WORK_EXPERIENCE_MODE=deepseek
AI_WORK_EXPERIENCE_REAL_ENABLED=true
DEEPSEEK_MODEL=deepseek-flash
DEEPSEEK_TIMEOUT_SECONDS=20
AI_WORK_EXPERIENCE_LIMITS_USER_PER_MINUTE=3
AI_WORK_EXPERIENCE_LIMITS_USER_PER_DAY=20
AI_WORK_EXPERIENCE_LIMITS_GLOBAL_PER_DAY=200
AI_WORK_EXPERIENCE_LIMITS_GLOBAL_CONCURRENCY=4
上述环境变量由 Spring Environment 解析;等价属性为 ai.work-experience.mode、ai.work-experience.real-enabled、ai.work-experience.limits.user-per-minute/user-per-day/global-per-day/global-concurrency。
默认 off,只设置真实 Key 不会启用功能。deepseek 缺少显式 real-enabled、Key 或配置非法时启动失败,不偷偷降级 stub。off/stub 不创建真实客户端;旧 stub-enabled 兼容保留。不得在公开端点、请求参数或前端控制模式/模型/地址/Key。
告知版本升级为 work-experience-external-processing-v2,developmentOnly=false 表示取消开发 profile 限制,不是生产合规审批标志。旧 v1 必须重新获取告知并确认,否则 POST 400。优化仍然只生成建议,不写简历、不改变 revision。既有前端须完成告知、同意、预览与手动保存。
2. Key 安全注入
应用仅从进程环境的 DEEPSEEK_API_KEY 读取;不增加配置文件明文默认值,不接受前端 Key。由服务器的凭据管理或受保护服务环境注入,不把真实值放到 Git、JAR、前端、命令行参数、Jenkins 控制台或聊天截图。
Linux/systemd 可使用仓库外的 /etc/mydreamjob/ai.env 作为 EnvironmentFile,仅管理员及必要服务管理进程可读(例如 root 所有、0600),由管理员在无命令回显的安全渠道填写 Key。保留既有服务配置,使用受限 drop-in 引用该文件,不输出文件内容来“验证”。进程环境并非对 root/同权限诊断进程保密;服务器权限、转储、APM 另行管控。
本批不写入真实 Key,不修改服务器,不触发真实调用。部署时只记录“是否配置”,不要记录值或长度摘要。此前在聊天中暴露的 Key 建议轮换后再注入。
3. 限流、并发、超时及错误处理
只有学生 Access Token 可优化;企业、管理员、失效/禁用会话拒绝。输入、敏感字段、原生 true 和当前版本验证在额度门禁前。GET 告知、stub 和本地信息不足路径不消耗外呼额度。
Redis Lua 在一次原子操作中检查并增加用户分钟/日、全局日额度及并发租约,所有键使用 {work-experience} 同槽。默认每账号 3/分钟、20/天,全局 200/天,同账号 1 并发、全局 4 并发;所有应用实例必须使用同一 Redis DB、相同配置。Redis TIME 决定固定分钟及 UTC 日窗口,边界附近不是严格滚动窗口。次数上限不是货币预算;已有 1500 最大输出 token 也不是费用精确预测。
允许范围:user-per-minute 1..100、user-per-day 1..10000、global-per-day 1..1000000、global-concurrency 1..100;0/负数/越界不能关闭保护。生产按预期流量调整,不要用超大上限绕开保护。
成功接受的外呼尝试即计次,供应商失败、超时也不退回;被门禁拒绝不计次。全局和用户并发只在请求期间持有,完成/异常均释放;进程崩溃或释放时 Redis 断连,75 秒租约到期回收。释放携带随机所有者 token,旧请求不能释放新租约。75 秒大于最大 60 秒请求超时。进程重启不清除 Redis 配额;Redis 重建/清库/驱逐可能重置计数,部署需监控并配置持久化和不随意驱逐,不能宣称绝对账单上限。
Redis 未配置、断连、脚本异常或无效结果返回 503,不使用进程内后备放行。额度/并发满返回 429、code=429、Retry-After: 60;这是最早重新检查提示,不承诺 60 秒后必定有日额度,前端不得自动重试。503 为关闭/不可用,502 为模型结构错误,504 为超时,400 为输入/同意版本问题。
DEEPSEEK_TIMEOUT_SECONDS 默认20、范围1..60,连接超时5秒,整体响应等待有硬超时并取消未完成 Future;不自动重试、不跟随重定向,官方 HTTPS 地址不变,64KiB 响应上限保留。应用日志仍只保留安全元数据,JDK HTTP 报文诊断开启时失败关闭。不承诺已经审计网关、APM、JVM 转储等外层设施。
4. 验证与回滚边界
本批新增代码不能沿用 A6 的全量/JAR PASS:以 A7 清单为新身份,先隔离定向回归与真实 Redis 验证,再全量 clean verify 和同次 JAR 黑盒、契约及重启。离线测试禁止开启两项 Live 开关,不调用真实模型。上线前由授权人员完成服务器真实连通和前端闭环。
回滚配置可设 AI_WORK_EXPERIENCE_MODE=off 后重启;需要回滚代码时用备份 JAR/配置,不清库、不清 Redis。关闭只影响 AI,不影响手动编辑保存。旧 JAR 不识别新告知版本,回滚须同步前端刷新告知,不能假定请求向后兼容。
第三方留存/训练政策、正式告知细节和前端实际展示仍需上线负责人确认;代码允许正式环境启用不等于这些事项已验证。无需数据库迁移,没有新依赖,不更改前端、不提交、不推送、不发布。