单元三 做一个网络服务 · 第 13 课

周报助手·AI 版

给周报助手接上 AI:同样的工作记录,写出来的周报会通顺得多。这一课也会学到服务端程序最重要的一条规矩:密钥只放在服务器上。

本课目标

  • 让服务器调用 API 生成周报。
  • 理解为什么 Key 只能放在服务器端,并且放在环境变量里。
  • 处理 AI 失败和超时:自动退回规则版。
  • 确认 Key 没有出现在代码和存档里。

先懂概念:为什么由服务器去调用 AI

网页上的代码会被下载到访问者的浏览器里,任何人按 F12 都能看到。如果把 Key 写在网页里,等于把钱包挂在门口。

所以正确的做法是:

浏览器 ──提交工作记录──▶ 你的服务器 ──带着 Key 调用──▶ AI 接口
浏览器 ◀──返回周报────── 你的服务器 ◀──返回结果──────── AI 接口

Key 只存在于服务器的环境变量里,浏览器自始至终看不到它。

另外,网络会断、接口会超时、余额会用完。好的程序要考虑失败的情况:AI 不可用时,自动用规则版生成,并告诉用户发生了什么。

跟着做

1. 确认 Key 还在

第 6 课已经把 Key 永久设置在 XAI_API_KEY 里了:

$env:XAI_API_KEY.Length
echo ${#XAI_API_KEY}

显示一个数字即可。

2. 写需求,交给 AI

cd ~/ai-course/weekly-report
codex
请给周报助手加上 AI 生成功能,保留现有的规则版。

接口与配置(全部从环境变量读取,代码里不能出现任何 Key):
- XAI_API_KEY:API Key。没有设置时只用规则版,并在返回结果里提示“没有设置 XAI_API_KEY,已使用规则版”。
- XAI_BASE_URL:默认 https://api.zairouter.com。
- MODEL:默认 gpt-5.6-sol。
- 调用 {XAI_BASE_URL}/v1/chat/completions,请求头 Authorization: Bearer {XAI_API_KEY},用 Node.js 自带的 fetch。

生成要求(写在 system 提示词里):把零散的工作记录整理成中文周报,用 Markdown,包含本周完成、进行中(写明进度)、问题与风险、下周计划四部分;语气客观,不夸大,记录里没有的事情不要编造;缺少日期或负责人时,在末尾列出需要确认的问题。

可靠性:
- 请求超时 60 秒。
- 接口报错、超时或返回空内容时,退回规则版,并在返回结果里说明原因,例如“AI 暂时不可用(AI 接口返回 HTTP 401),已使用规则版”。
- 输入超过 5000 字时返回 413 和中文提示。
- 日志里不要打印工作记录的内容和 Key。

页面:在结果上方显示这次是 AI 生成还是规则版,以及上面那句说明。

另外创建 .gitignore,忽略 .env、node_modules 和日志文件。

先告诉我你的计划,等我确认后再改。

审查计划,确认后让它动手,完成后退出 Codex。

3. 启动并试用

npm start

刷新 http://localhost:3000,贴上第 12 课的测试数据,点“生成周报”。

你应该看到

等几秒到十几秒后,出现一份由 AI 写的周报:语句更完整,可能还会在末尾列出“需要确认的问题”。页面上标明这是 AI 生成的。

照例要验收:AI 写的周报里,有没有测试数据里没有的内容?如果它编造了事实,在需求里把“不要编造”强调得更明确,让它改提示词。

故意弄坏它

验证失败处理是否真的有效。先停止服务器,然后新开一个终端,在里面临时把 Key 设成错的:

cd ~/ai-course/weekly-report
$env:XAI_API_KEY = "sk-wrong"
npm start
cd ~/ai-course/weekly-report
XAI_API_KEY=sk-wrong npm start

再生成一次。这次应该看到规则版的结果,以及“AI 暂时不可用(……401)”之类的说明。试完停止服务器,关掉这个终端,错误的 Key 就随它消失了,你永久设置的 Key 不受影响。

确认 Key 没有泄露

git grep --untracked -l "sk-"

--untracked 让它连还没存档的新文件一起搜(被 .gitignore 忽略的 .env 不在其中,本来也不会被存档);-l 只列出文件名,不把内容打在屏幕上。没有输出最好;如果列出了文件,打开看看:只是 sk-你的Key 这类示例文字就没有关系;如果是真正的 Key,说明它被写进了文件,让 AI 改成从环境变量读取,并且去账户后台更换这个 Key。

确认无误后存档:

git add -A
git commit -m "周报助手 AI 版"

花费和隐私

  • 每点一次“生成周报”就调用一次 API,按 Token 计费。想省钱可以换更便宜的模型:在模型页挑一个,启动前用环境变量 MODEL 指定。
  • 工作记录会发送给 AI 服务商处理。不要贴客户隐私、公司机密等不该外传的内容。

常见问题

一直显示规则版? 看页面上的说明:如果是“没有设置 XAI_API_KEY”,说明启动服务器的终端里没有这个变量,重开终端再启动;如果是 401,Key 不对;如果是超时,检查网络。

等了很久才出结果? 大模型写长文本需要时间,十几秒是正常的。超过 60 秒会自动退回规则版。

返回 404? 检查 XAI_BASE_URL 有没有多写 /v1,正确的值是 https://api.zairouter.com。

自检

  • 我能解释为什么 Key 不能写在网页里。
  • 周报助手能用 AI 生成周报。
  • 用错误的 Key 启动时,会自动退回规则版并说明原因。
  • git grep --untracked -l "sk-" 没有找到含真正 Key 的文件,AI 版已经存档。