Celevue 产品文档
更新时间:2026-07-14
1. 文档边界
本文按当前 iOS 工程目标产品 Celevue 编写,目标 Bundle ID 为 com.lingcheng.aifriend。文档中的产品名、包名、接口语义和数据模型都以 iOS 正式产品为准。
本文只描述产品能力、信息架构、技术架构、接口协议、数据策略和开发规范,不描述界面外观细节。正式实现范围只包含 iOS 原生应用和后端服务。
2. 产品概述
Celevue 是一款面向日常记录和 AI 对话的应用。用户可以用文字记下当天发生的事、想法和情绪,AI 根据这些内容进行回复、整理和总结,帮助用户把事情说清楚,也方便以后回头查看。
核心目标:
- 让用户随时记下一段话,不需要整理格式。
- 支持文字输入。
- 通过 AI 回复帮助用户继续表达和整理想法。
- 对有保存价值的发言生成历史记录,方便之后回看。
- 根据长期记录整理出当日、本周、本月摘要、常见话题和情绪起伏。
- 提供账号、隐私说明和删除账号能力。
不包含范围:
- 不包含任何交易相关功能。
- 不包含游戏化商城、权益分层或交易解锁。
- 不在本文描述界面外观。
- 首版不包含邮箱验证和找回密码闭环。
- 首版不包含远端记录标记删除能力。
3. 应用标识与版本信息
目标应用信息如下:
| 项目 | 目标值 |
|---|---|
| 产品名称 | Celevue |
| iOS Bundle ID | com.lingcheng.aifriend |
| iOS 版本号 | 1.0.0 |
| iOS 构建号 | 1 |
| 支持平台 | iOS |
| 最低系统版本 | 建议 iOS 16.0 起 |
| 原生技术栈 | SwiftUI 主体 + UIKit 系统能力桥接 |
| 默认语言 | 简体中文 |
权限目标:
- 网络访问:用于登录、同步记录和请求 AI 回复。
隐私目标:
- 账号邮箱只用于登录和账号识别。
- 用户记录和对话内容只用于应用功能。
- 不把用户内容用于广告追踪。
- 用户应能删除账号和相关内容。
4. 支持语言
首版只支持简体中文。
后续多语言策略:
- iOS 使用本地化资源统一管理文案。
- 服务端返回给用户看的文字需要带语言上下文。
- 日期、时间、数量和错误提示按当前语言环境处理。
5. 技术架构
5.1 总体架构
项目以 iOS 原生应用和后端服务为正式产品主体:
- iOS 原生应用是正式产品,一切产品能力、接口字段和验收标准以 iOS 为准。
- 后端 API 负责账号、认证、AI 对话、记录、总结和同步。
5.2 iOS 原生应用
iOS 采用 SwiftUI 主体 + UIKit 系统能力桥接。
建议模块:
- 应用入口:应用启动、依赖组装和根状态管理。
- 根协调器:启动检查、登录状态、主功能切换。
- 认证中心:登录、注册、刷新登录状态、退出登录。
- 安全令牌存储:保存敏感登录信息。
- 网络客户端:统一请求后端接口,处理鉴权、刷新、错误协议和重试。
- 对话状态:当前会话、消息发送、AI 重试和首发流程。
- 记录状态:记录列表、详情、编辑和刷新。
- 回顾状态:当日、本周、本月摘要、趋势和个人提示。
- 资料状态:账号身份和个人资料。
- 设置状态:隐私说明、AI 使用说明、删除账号等状态。
SwiftUI 负责主要业务页面和状态绑定。UIKit 用于 SwiftUI 不适合直接处理的系统能力,比如授权展示、系统分享、触觉反馈、剪贴板和部分生命周期桥接。
6. 导航架构
产品信息架构分为四层:
- 启动层:检查登录状态、首次使用状态、必要权限说明。
- 主功能层:开始记录、继续对话、查看历史记录。
- 回顾层:查看摘要、常见话题和个人提示。
- 管理层:账号、隐私、删除账号和服务配置。
推荐主路径:
- 用户打开应用。
- 应用检查是否已登录。
- 未登录时进入登录或注册流程。
- 已登录后进入主功能区。
- 用户可以开始记录、继续对话、查看历史、查看总结或进入设置。
- 用户可以按需删除账号。
异常路径:
- 登录过期:优先自动刷新令牌;刷新失败后清理本地登录状态并回到登录页。
- 网络不可用:保留当前输入,提示稍后重试。
- AI 服务失败:保留当前输入,允许重新请求。
- 请求超时:允许用户重试,重试请求必须携带同一个幂等键,避免重复消息或重复记录。
7. 首页与对话
首页承担“开始表达”和“继续当前上下文”的职责。
首页功能:
- 文字输入:用户可以直接写下今天的事、想法或问题。
- AI 回复:根据用户输入生成回复,帮助用户继续说下去。
- 最近记录:展示 AI 判断有保存价值后生成的摘要记录,方便接着看。
- 当前会话:保存本次对话上下文。
- 自动整理:AI 接收用户发言后判断是否值得保存;有价值才凝练成一条记录,无价值只回复,不新增记录。
- 错误处理:处理网络失败、AI 回复失败和登录过期。
首页数据流:
- 用户输入文字。
- 客户端把文本发送给后端,并携带
clientRequestId或idempotencyKey。 - 大模型生成回复,并判断这次发言是否有保存价值。
- 有保存价值时,后端返回 AI 凝练后的记录摘要;无保存价值时,只返回 AI 回复。
- 客户端更新当前会话;只有拿到新增记录时才刷新最近记录。
- 后端保存会话消息和有价值的记录摘要,用于后续总结。
首页文案原则:
- 用日常话,不写文艺句。
- 错误提示直接说明发生了什么。
- 不催促用户,不制造压力。
8. 设置页面
设置页面负责账号、数据、隐私和服务相关管理。
设置页面功能:
- 账号信息:展示当前账号、登录状态和基础身份信息。
- 登录管理:支持退出登录和重新登录。
- 隐私说明:说明应用会使用哪些数据、用于什么功能。
- AI 使用说明:说明用户内容会如何参与 AI 回复和总结。
- 删除账号:用户确认后删除账号和相关数据。
- 服务环境配置:开发或测试阶段可配置 API 地址;正式环境默认使用固定配置。
- 版本信息:展示当前版本号和构建号。
暂不进入首版的设置能力:
- 邮箱验证。
- 找回密码。
- 重新发送邮箱验证码。
设置页面数据规则:
- 登录信息存在安全存储中。
- 普通偏好存在轻量本地存储中。
- 删除账号必须经过二次确认。
- 删除成功后清理本地登录状态和缓存。
9. 后端 API 接口
以下是首版客户端接口方案。客户端接口只列 iOS 需要直接调用的接口;Memory 自动生成、标签整理、向量化和落库属于后端内部能力,不作为首版客户端接口暴露。
9.1 统一请求约定
- 所有需要登录的接口使用
Authorization: Bearer <accessToken>。 - 写入类请求必须携带
clientRequestId或idempotencyKey,用于超时、失败后重试时去重。 clientRequestId由 iOS 生成,建议使用 UUID,并在同一次用户动作的重试中保持不变。idempotencyKey可放在请求头Idempotency-Key,也可放在 JSON 请求体中;同一接口内必须保持一种固定方式。- 后端应保存幂等键、账号、接口路径和结果摘要,在有效窗口内重复请求时返回第一次处理结果。
- 如果同一个幂等键被用于不同请求体,后端返回
409 IDEMPOTENCY_CONFLICT。
建议幂等范围:
| 场景 | 要求 |
|---|---|
| 创建会话并首发 | 必须携带 |
| 发送消息 | 必须携带 |
| AI 重试 | 必须携带 |
| 编辑记录 | 建议携带 |
| 删除账号 | 必须携带 |
9.2 账号与认证
首版客户端接口:
| 接口 | 用途 |
|---|---|
POST /api/auth/login | 登录 |
POST /api/auth/register | 注册 |
POST /api/auth/logout | 退出登录 |
POST /api/auth/refresh | 刷新登录状态 |
DELETE /api/account | 删除账号 |
后续接口,不列为首版:
| 接口 | 用途 |
|---|---|
POST /api/auth/forgot-password | 找回密码 |
POST /api/auth/verify-email | 验证邮箱 |
POST /api/auth/resend-email-code | 重新发送邮箱验证码 |
刷新令牌规则:
- iOS 收到业务接口
401后,先判断本地是否有 refresh token。 - 如果有 refresh token,调用
POST /api/auth/refresh。 - 刷新成功后,更新 Keychain 中的 access token、refresh token 和过期时间。
- 刷新成功后自动重放原请求,原请求的
clientRequestId或idempotencyKey必须保持不变。 - 同一时间有多个请求同时收到
401时,iOS 只发起一次 refresh;其他请求等待同一个刷新结果。 - 刷新成功后,等待中的请求统一使用新 access token 重放。
- 刷新失败、refresh token 失效、refresh 接口返回
401或403时,iOS 清理本地登录态、Keychain 令牌和受保护缓存,并切回登录状态。 - refresh 请求本身不能因为
401再次触发 refresh,避免循环。
9.3 用户资料与身份
| 接口 | 用途 |
|---|---|
GET /api/profile | 获取账号身份和个人资料 |
PATCH /api/profile | 更新个人资料 |
GET /api/profile/summary | 获取个人资料摘要 |
身份 ID 规则:
AccountIdentity.id固定表示accountId。UserProfile.id固定表示profileId。accountId和profileId不能混用。GET /api/profile必须返回accountId,并返回独立的资料 ID。
推荐返回结构:
{
"accountIdentity": {
"id": "account_123",
"accountId": "account_123",
"email": "user@example.com"
},
"profile": {
"id": "profile_456",
"profileId": "profile_456",
"accountId": "account_123",
"displayName": "小陈"
}
}
9.4 对话
| 接口 | 用途 |
|---|---|
POST /api/conversations | 创建会话,可选首发 |
GET /api/conversations | 获取会话列表 |
GET /api/conversations/{conversationId} | 获取会话详情 |
POST /api/conversations/{conversationId}/messages | 发送消息 |
POST /api/conversations/{conversationId}/messages/{messageId}/retry | 重新生成回复 |
DELETE /api/conversations/{conversationId} | 删除会话 |
9.4.1 创建会话与首发语义
POST /api/conversations 请求体:
{
"clientRequestId": "uuid",
"initialText": "今天工作有点乱",
"source": "home"
}
initialText 为空或只包含空白字符时:
- 后端只创建空会话。
- 不生成用户消息。
- 不调用大模型。
- 不生成 assistant 消息。
- 不生成记录。
- 返回完整
conversation,其中messages为空数组,createdRecords为空数组。
initialText 非空时:
- 后端创建会话。
- 后端追加一条 user 消息。
- 后端调用大模型生成一条 assistant 消息。
- 后端根据这次发言判断是否生成记录。
- 如果有保存价值,后端内部写入记录,并在响应中返回本次新增的
createdRecords。 - 如果无保存价值,
createdRecords返回空数组。 - 响应返回完整
conversation,客户端以返回体为准更新本地状态。
推荐响应结构:
{
"conversation": {
"id": "conversation_123",
"title": "今天工作有点乱",
"messages": [
{
"id": "message_user_1",
"role": "user",
"content": "今天工作有点乱",
"status": "sent",
"createdAt": "2026-07-14T10:00:00Z"
},
{
"id": "message_assistant_1",
"role": "assistant",
"content": "先把最影响你的那件事说清楚,我们再一起拆。",
"status": "active",
"createdAt": "2026-07-14T10:00:03Z"
}
],
"createdRecords": [
{
"id": "record_123",
"summary": "工作事项较多,用户感到有些混乱。",
"tags": ["工作", "压力"],
"createdAt": "2026-07-14T10:00:03Z"
}
]
}
}
9.4.2 发送消息
POST /api/conversations/{conversationId}/messages 行为:
- 请求必须携带
clientRequestId或idempotencyKey。 - 后端追加 user 消息。
- 后端调用大模型生成 assistant 消息。
- 后端内部判断是否生成记录。
- 响应返回完整
conversation和本次可选新增的createdRecords。 - 客户端不要直接调用 Memory 新建接口。
9.4.3 AI 重试
POST /api/conversations/{conversationId}/messages/{messageId}/retry 用于重新生成指定 assistant 消息。
重试规则:
messageId必须指向一条 assistant 消息。- 后端不删除旧 assistant 消息。
- 旧 assistant 消息状态标记为
superseded;如后端已有replaced命名,可作为同义状态兼容,但首选superseded。 - 旧 assistant 消息可以额外返回
replacedByMessageId。 - 后端追加一条新的 assistant 消息,状态为
active。 - 如果旧消息已经被替换过,再次重试时只替换当前 active 的 assistant 消息。
- 重试可能产生新的记录,也可能不产生记录;是否产生由后端内部判断。
- 响应返回完整
conversation,客户端以返回体为准重绘消息列表。
推荐消息状态:
| 状态 | 含义 |
|---|---|
sending | 客户端发送中 |
sent | 用户消息已提交 |
active | 当前有效 assistant 回复 |
superseded | 已被新回复替代的旧 assistant 回复 |
replaced | superseded 的兼容命名,不作为首选 |
failed | 生成失败,可重试 |
9.5 记录与后端内部 Memory
iOS 客户端面向“记录”工作,不直接调用内部 Memory 写入能力。客户端以 Conversation 返回的 memory 信息或 Records 查询结果为准。当前 iOS 数据模型中的 MemoryEntry.tags 以字符串数组为准,不采用按 tagId 绑定的客户端方案。
客户端首版接口:
| 接口 | 用途 |
|---|---|
GET /api/records | 获取记录列表 |
GET /api/records/{recordId} | 获取记录详情 |
PATCH /api/records/{recordId} | 更新记录标题、摘要、标签等用户可编辑字段 |
客户端暂不列入首版的接口:
| 接口 | 原因 |
|---|---|
| 内部 Memory 写入接口 | 属于后端内部 Memory 生成能力,不由客户端直接调用 |
| 内部 Memory 标签接口 | 标签整理以后端内部能力和记录编辑接口为准,不由客户端直接调用 |
| 按 tagId 绑定的标签接口 | 不采用按 tagId 绑定的客户端方案 |
DELETE /api/records/{recordId} | 远端标记删除能力后续再做,首版不作为必需接口 |
后端内部 Memory 能力:
- 对话完成后,根据 user 消息和 assistant 回复判断是否需要形成记录。
- 生成记录摘要、标签字符串数组和后续总结需要的结构化字段。
- 调用向量模型生成 embedding。
- 写入记录表和检索索引。
- 在对话响应中返回本次新增记录,或在
GET /api/records中供客户端查询。 - 内部能力不暴露为首版客户端接口。
记录模型规则:
{
"id": "record_123",
"summary": "工作事项较多,用户感到有些混乱。",
"tags": ["工作", "压力"],
"sourceConversationId": "conversation_123",
"createdAt": "2026-07-14T10:00:03Z",
"updatedAt": "2026-07-14T10:00:03Z"
}
后续记录删除规划:
- 后续需要支持远端标记删除。
- 标记删除建议使用
deletedAt、deleteState或同级字段表达。 - 标记删除后的记录默认不出现在列表和总结输入中。
- 该能力不进入首版客户端接口范围。
9.6 总结与回顾
| 接口 | 用途 |
|---|---|
GET /api/reviews/daily | 获取今日总结 |
GET /api/reviews/weekly | 获取本周摘要 |
GET /api/reviews/monthly | 获取本月摘要 |
GET /api/reviews/topics | 获取常见话题 |
GET /api/reviews/mood | 获取情绪变化 |
POST /api/reviews/rebuild | 重新生成总结 |
9.7 系统配置
| 接口 | 用途 |
|---|---|
GET /api/app/config | 获取客户端配置 |
GET /api/app/health | 检查服务状态 |
10. 统一错误协议
后端错误响应统一使用 error envelope。
推荐结构:
{
"error": {
"code": "AUTH_TOKEN_EXPIRED",
"message": "登录已过期",
"requestId": "req_123",
"details": {
"field": "email"
}
}
}
字段规则:
error.code是稳定错误码,客户端按它做逻辑判断。error.message是可展示或可转译的简短说明,不能替代错误码。error.requestId用于排查日志。error.details只放必要的字段级错误、限制信息或上游失败摘要,不放敏感内容。
HTTP status 与错误码映射:
| HTTP status | 典型错误码 | iOS 处理 |
|---|---|---|
400 | VALIDATION_FAILED、INVALID_ARGUMENT | 展示字段或通用输入错误 |
401 | AUTH_TOKEN_EXPIRED、AUTH_REQUIRED | 触发 token refresh;refresh 失败后退出登录态 |
403 | FORBIDDEN、ACCOUNT_DISABLED | 停止重试,提示无权限或账号不可用 |
404 | RESOURCE_NOT_FOUND | 提示内容不存在,必要时从本地列表移除 |
409 | IDEMPOTENCY_CONFLICT、VERSION_CONFLICT | 停止自动重试,刷新数据或提示稍后重试 |
422 | BUSINESS_RULE_REJECTED | 展示业务规则提示 |
429 | RATE_LIMITED | 按 Retry-After 或默认间隔延后重试 |
500 | INTERNAL_ERROR | 展示服务异常,允许稍后重试 |
502 | AI_UPSTREAM_FAILED | 展示 AI 服务暂时不可用,允许重新生成 |
503 | SERVICE_UNAVAILABLE | 展示服务繁忙,允许稍后重试 |
iOS 统一处理规则:
- 网络层先解析 error envelope,再落到业务 Store。
- 只有
401可以触发自动刷新令牌。 - 刷新令牌成功后重放原请求;重放仍失败时按新错误处理。
- AI 生成失败时保留用户输入和已提交消息,提供重试入口。
- 请求超时或断网时不假定失败写入,重试必须复用原幂等键。
- 无法解析为 error envelope 的响应统一归为
UNEXPECTED_RESPONSE。
11. 后端与 AI 处理规划
后端职责:
- 账号、认证、资料、会话、记录、回顾和系统配置接口。
- 对话消息持久化。
- 对话后内部触发 Memory 生成、标签整理、向量化和落库。
- 基于记录生成日、周、月回顾和趋势数据。
- 统一鉴权、错误协议、幂等处理和请求日志。
AI 模型规划:
- 后续大语言模型接入字节旗下火山方舟。
- 后续向量模型也接入火山方舟。
- 后端应封装模型供应商适配层,避免 iOS 感知具体模型供应商。
- 对话生成、记录摘要、标签生成、总结生成和向量化要分别记录请求状态。
- AI 处理过程中的临时数据应限制保存时间,不把无用中间内容长期保存。
12. 数据持久化策略
12.1 iOS 本地存储
敏感数据:
- 登录令牌。
- 刷新令牌。
- 令牌过期时间。
- 账号标识。
策略:使用 Keychain 保存,不写入普通文件,不写入日志。
普通偏好:
- 是否完成首次引导。
- 用户同意状态。
- 当前语言。
- 本地草稿。
- 最近一次同步时间。
- 测试环境 API 地址。
策略:使用 UserDefaults 或同级轻量存储。用户内容如果需要本地暂存,要有清理机制。
本地缓存:
- 最近会话摘要。
- 最近记录列表。
- 未发送草稿。
策略:缓存只用于提升体验,服务端数据仍是最终来源。遇到冲突时优先保护用户输入。
12.2 服务端存储
服务端保存:
- 账号。
- 用户资料。
- 会话。
- 消息。
- 记录。
- 标签字符串数组和检索索引。
- 总结。
- 用户同意状态。
策略:
- 账号和内容按用户隔离。
- 删除账号后,应删除或匿名化相关数据。
- 记录只保存 AI 凝练后的摘要,不逐字保存为用户原文。
- 用户发言是否生成记录由 AI 在对话过程中判断,无保存价值的发言不新增记录。
- AI 处理过程中的临时数据应限制保存时间。
- 远端记录标记删除作为后续能力规划,不进入首版。
13. 国际化
首版只做简体中文,但代码要为后续多语言预留空间。
iOS:
- 文案集中在本地化资源里。
- 日期、时间和数字按系统语言环境展示。
后端:
- 错误码和用户可见文案分开。
- 接口支持语言参数。
- 服务端生成内容时使用用户当前语言。
14. 开发规范
14.1 iOS 优先规范
- iOS 是正式产品。
- 接口字段、模型语义和验收标准以 iOS 为准。
- 文档更新时先确认是否影响 iOS 模型和网络层。
14.2 iOS 规范
- 使用 SwiftUI 作为主体。
- UIKit 只用于系统能力桥接。
- 网络、认证和存储都要独立封装。
- 登录敏感信息放 Keychain。
- 普通偏好放轻量本地存储。
- 用户内容进入 AI 处理前要有明确说明。
- 涉及符号素材时采用 SF Symbols;本文不展开外观规范。
14.3 后端规范
- 接口使用统一错误结构。
- 登录接口和业务接口分层。
- 用户内容按账号隔离。
- 写接口实现幂等处理。
- AI 请求要记录必要的请求状态,但不要保存无用的临时数据。
- 接口变更要同步更新文档。
- Memory 生成、标签整理、向量化和落库先作为内部能力,不暴露为首版客户端接口。
14.4 文案规范
- 用日常生活里的说法。
- 少用抽象词。
- 不写文艺化表达。
- 错误提示直接说明问题。
- 隐私和数据说明要说清楚,不绕弯。
14.5 测试规范
- iOS 按实体机测试。
- 不主动添加虚拟机专用支持。
- 重点测试登录、AI 回复、历史记录、删除账号、权限拒绝和网络失败。
- 后端重点测试鉴权、数据隔离、幂等、token refresh、错误协议和 AI 异常返回。
14.6 版本管理规范
- 提交前先拉取远端。
- 本地和远端分叉时只使用 merge,不使用 rebase。
- 冲突在本地解决后再提交。
- 不覆盖他人正在写的文档或原生工程产物。
15. 后续项
后续需要补齐:
- 邮箱验证、找回密码和重新发送邮箱验证码接口。
- 远端记录标记删除能力。
- 后端接口字段的 OpenAPI 或同级契约文件。
- 火山方舟大语言模型和向量模型接入细节。
- 权限说明文案。
- 实体机测试记录。