AI
接入 Workers AI,理解聊天流、文件摘要、积分预留、队列重试与死信恢复。
能力边界与代码位置
| 模块 | 职责 |
|---|---|
packages/ai | Workers AI 模型调用与输入处理 |
packages/db/src/store.ts | 积分账本、预留、结算与补偿 |
apps/web/src/server/jobs.ts / packages/db/src/index.ts | 任务调度、outbox、租约与重试 |
apps/web/src/server/api.ts | 聊天及摘要 API 的会话、输入和资源归属校验 |
apps/web/src/server.ts | 队列消费与定时恢复入口 |
当前模型为 @cf/meta/llama-3.1-8b-instruct,通过 AI binding 调用。此模板不是自动配置所有模型供应商的通用网关;切换模型需核对输入输出、流格式、成本与测试。
本地与真实调用
默认 Vite 配置 remoteBindings: false,使首次本地启动不依赖远程账户,但这不提供本地模型模拟器。聊天界面可打开不等于模型可返回内容。
要做真实 AI 验收,需在自己的 Cloudflare 账户准备 Workers AI binding 和额度,再明确选择远程绑定或自己的部署。此操作可能产生服务消耗。不要使用公共演示来进行批量或成本测试,也不要将真实 Token 贴到问题记录中。
聊天调用
POST /api/chat 接受:
{
"prompt": "Explain the uploaded release notes",
"requestId": "e60b2e4b-32b1-42a5-bfd0-dbb20ecb37e9"
}prompt 长度为 1 至 16,000 个 JavaScript 字符;requestId 可选,提供时必须为 UUID。使用真实请求时每次新操作生成自己的 UUID,不复用本例。响应为 text/event-stream,前端需逐段读取,处理断流和错误,不调用 response.json()。
默认每次聊天消耗 1 积分。积分不足应在服务端拒绝;界面禁用按钮不能替代余额检查。修改费用的位置为 product.quotas.chatCredits,并同步用量文案。
文件摘要调用
- 在文件页上传自己的 text/plain 或 text/markdown。
- 调用
POST /api/summary,正文为{ "fileId": "your-owned-file-uuid" }。 - 查看创建的后台任务与状态,而不是等待一个同步全文摘要响应。
- 成功后查看结果,失败时查看任务信息并使用既有重试入口。
摘要费用默认 5 积分,配置为 summaryCredits。上传允许最大 1 MiB,但摘要只使用前 16,000 个字符,不会自动拆分长文、OCR 图片或处理任意 PDF。
积分与异步一致性
注册欢迎积分默认 30,由 welcomeCredits 配置。AI 操作先原子预留,再在结果确定后结算或补偿;任务与 outbox 使用数据库约束和租约协调。不要在客户端请求前先扣一次积分,也不要在队列重试时再扣一次。
异步任务由 JOBS 队列驱动。Worker 有主队列与死信队列消费者,最大重试次数当前为 3;每 5 分钟的 cron 用于恢复需要补偿的任务和 outbox。重试、重复投递和进程中断都必须通过相同幂等状态机,不直接在 UI 修改余额。
管理与恢复
工作台展示自己的任务与用量。后台可以查看任务、审计和死信,恢复操作必须针对明确任务,遵守状态、权限与租约。长时间处理中应先查队列、消费者和 outbox,而不是反复点击创建同一个任务。
验证与排障
- 输入过长、空输入、余额不足、非本人文件都应失败且不产生重复扣费。
- 正常聊天检查逐段输出和最终账本;断流检查可解释的失败与积分状态。
- 摘要验证成功、模型失败、重复队列投递、租约到期及死信恢复。
- 本地无输出:先确认 AI binding 是否可真实调用,不误认为默认本地启动具备模型。
- 一直 pending:检查队列绑定、消费者、cron 与可恢复 outbox。
pnpm test:unit 与 pnpm test:workers 验证逻辑边界;真实模型、生产额度和完整结果质量仍要单独验收。继续阅读 测试 和 部署。