# n8n Google Sheets AI：教学材料与真实连接分开

资料核对：2026-10-08。节点格式参考 n8n 2.42.3 官方 tag：Manual Trigger v1、Code v2。没有安装或执行完整 n8n 实例，不能把这里的离线检查当作导入验收。

## 离线教学

`offline-n8n-workflow.json` 只有手动触发和两个 Code 节点。节点无 credentials、HTTP、Google Sheets、计划触发器或写入。

`fixture.json` 的 model_output 都是人工写的模拟值，不是 API 返回。A 等待人工审核，B 拦截过期输入，C 跳过已完成版本；所有 write_allowed 均为 false。

Code 节点用 Run Once for All Items，返回结果包含 pairedItem。同一 qr_id 重复、来源 ID 错配、额外输出字段、非法分类会停止本次检查。示例上限 100 行、4000 字符输入是教学限制，不是 n8n 或模型的最大值。

## 自己实例上的真实流程

1. 建独立测试表，导入 sample-sheet.csv；保留唯一且不可修改的 qr_id。不要把表格排序后的物理行号作为业务 ID。
2. 通过 n8n Google Sheets 凭据连接自己的 Google 账户，或给服务账户单独共享该测试表。控制台 API Key 不等于 Google OAuth 凭据。
3. Google Sheets Get Row(s) 读取待处理行。将每行的 qr_id、input_revision、input_text 作为快照保留在工作流；第一次仅处理一行。
4. HTTP Request：POST `https://api.apizt.com/v1/chat/completions`；认证使用 Generic Credential Type → Header Auth，凭据名 Authorization，值由你在凭据页面设置为 Bearer 后接自己的 Key。发送 application/json，model 用目录中的准确 ID；不要在 Code 节点执行网络请求。
5. Prompt 要求仅输出 qr_id、category、summary。category 只能是 配送/退款/其他；summary 不超过 80 字。JSON 请求用对象构建，不拼接用户原文。
6. 从真实响应取 choices[0].message.content；JSON.parse 解析。连同原快照与新读取的同 qr_id 当前行组成 `{source,current,model_output}`，运行 review-rows.mjs 内的函数。不能把已经被 HTTP 节点替换的 `$json` 当作原始行。
7. 人工核对摘要是否忠于原文。为已审核结果单独建立审批记录，记录 qr_id 与 input_revision。模型输出不允许设置审批状态。
8. 更新前再次查询 qr_id 并验证原文、版本和唯一性。已删除、重复、变化或已处理则停止写入。Google Sheets Update Row 使用 Map Each Column Manually，Column to Match On 选 qr_id，只映射 AI 列与 processed_revision；避免 Append or Update 创建找不到的行。
9. 写入后重新读取该 qr_id，核对实际字段与原文未改。只把读取后的值标记为已写入。

并发修改仍可能发生在最后一次读与写之间。普通 Sheets 行更新没有本示例自带的原子比较并交换；首版单并发运行，正式使用需应用层锁或可验的协调服务。

## 写入格式与恢复

在当前节点版本设置 Cell Format → Let n8n format（API valueInputOption 为 RAW），避免把模型文字作为公式执行。若使用 HTTP 调 Sheets API，明确填写 valueInputOption=RAW；A1 range 必须根据最新 qr_id 查出的行定位，不能使用旧位置。

模型超时：标记 unknown，先核对执行与平台用量，再决定是否重试。写入超时：先 Get Row(s) 回读目标字段，不能直接重新生成或追加行。去重持久化用 qr_id + input_revision；离线函数不保存运行历史。

验收需要真实 Google 权限、请求、返回、审批与回读。本资料没有连接用户第三方账户，没有实际扣费或 Google Sheets 写入记录。

官方依据：
- https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googlesheets/sheet-operations/
- https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/
- https://github.com/n8n-io/n8n/blob/n8n%402.42.3/packages/nodes-base/nodes/Google/Sheet/v2/actions/sheet/update.operation.ts
- https://developers.google.com/workspace/sheets/api/reference/rest/v4/spreadsheets.values/update
