- SSML TTS with emotional styles (_build_ssml, mstts:express-as) and natural pauses - Agent avatar support: DB migration, API, frontend emoji/URL rendering - AgentChat UX: highlight.js code blocks, copy buttons, streaming cursor, char count, auto-title, keyboard shortcuts, message feedback (thumbs), undo delete, mobile responsive - Virtual company: M2 control, tier-3/4 capabilities, per-dept session fix, deliverable validator, insight analyzer enhancements - New services: agent_profiler, deliverable_validator, redis_task_registry - Android: auth refactor, launcher icons, network security config, update manager - Frontend: useSpeechQueue composable, Agents/AgentConfig/AgentTest enhancements - Various backend fixes and expanded test coverage Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
377 lines
14 KiB
Markdown
377 lines
14 KiB
Markdown
# 天工智能体 Android 客户端 PRD 文档
|
||
|
||
> **版本**: v1.3.0 (versionCode=4)
|
||
> **更新日期**: 2026-07-27
|
||
> **目标平台**: Android 8.0+ (API 26+),目标 API 34
|
||
|
||
---
|
||
|
||
## 1. 产品概述
|
||
|
||
天工智能体 Android 客户端是天工 AI Agent 平台的移动端入口,与 Web 前端(localhost:3001)和后端(101.43.95.130:8037)共享同一套 API。用户可通过手机完成 Agent 对话、语音输入、智能体管理、消息推送等全部核心操作。
|
||
|
||
### 核心价值
|
||
- **随身 AI 助手**: 随时随地与 Agent 对话,支持流式实时输出
|
||
- **多 Agent 切换**: 支持多个自定义 Agent,每个 Agent 独立会话
|
||
- **语音交互**: 内置录音转文字(ASR)和文本转语音(TTS)
|
||
- **离线队列**: 无网络时消息自动暂存,恢复网络后自动发送
|
||
|
||
---
|
||
|
||
## 2. 目标用户
|
||
|
||
| 用户类型 | 描述 | 核心需求 |
|
||
|---------|------|---------|
|
||
| 普通用户 | 日常 AI 对话使用者 | 流畅对话、语音输入、消息推送 |
|
||
| 高级用户 | Agent 创建/管理者 | 多 Agent 切换、知识库管理、自定义配置 |
|
||
| 开发者 | 调试/测试服务器 | 服务器地址配置、网络诊断 |
|
||
|
||
---
|
||
|
||
## 3. 技术架构
|
||
|
||
### 3.1 技术栈
|
||
|
||
| 层级 | 技术选型 |
|
||
|------|---------|
|
||
| UI | Jetpack Compose + Material 3 |
|
||
| 导航 | Navigation Compose(17 个路由) |
|
||
| DI | Hilt + Dagger |
|
||
| 网络 | Retrofit + OkHttp + Gson |
|
||
| SSE 流式 | 自定义 SseClient(callbackFlow) |
|
||
| 本地存储 | Room(消息/会话缓存)+ DataStore(偏好设置) |
|
||
| 安全存储 | AndroidX EncryptedSharedPreferences(AES256-GCM) |
|
||
| 图片加载 | Coil Compose |
|
||
| Markdown 渲染 | Markwon |
|
||
| 音频播放 | Media3 ExoPlayer |
|
||
| 音频录制 | MediaRecorder |
|
||
| 推送 | Firebase Cloud Messaging |
|
||
| 崩溃上报 | Tencent Bugly |
|
||
| 数据统计 | Umeng |
|
||
|
||
### 3.2 架构模式: MVVM + Repository
|
||
|
||
```
|
||
┌──────────────────────────────────────────────┐
|
||
│ UI Layer (Compose Screens) │
|
||
│ 观察 StateFlow<UiState>,用户操作 → VM │
|
||
└──────────────────┬───────────────────────────┘
|
||
│ Hilt 注入
|
||
┌──────────────────▼───────────────────────────┐
|
||
│ ViewModel Layer (7 个 @HiltViewModel) │
|
||
│ MutableStateFlow + viewModelScope.launch │
|
||
└──────────────────┬───────────────────────────┘
|
||
│
|
||
┌──────────────────▼───────────────────────────┐
|
||
│ Repository Layer (7 个 Repository) │
|
||
│ 桥接网络 API 与本地数据源 │
|
||
└────────┬──────────────────┬──────────────────┘
|
||
│ │
|
||
┌────────▼────────┐ ┌──────▼──────────────────┐
|
||
│ Remote (API) │ │ Local (Room + DataStore) │
|
||
│ ApiService (52 │ │ AppDatabase (3 表) │
|
||
│ 个端点) │ │ TokenDataStore (偏好) │
|
||
│ SseClient │ │ CredentialStore (加密) │
|
||
│ Interceptors x3 │ │ OfflineQueue │
|
||
└─────────────────┘ └─────────────────────────┘
|
||
```
|
||
|
||
### 3.3 OkHttp 拦截器链
|
||
|
||
| 顺序 | 拦截器 | 职责 |
|
||
|------|--------|------|
|
||
| 1 | DynamicUrlInterceptor | 动态改写请求 URL(支持运行时切换服务器) |
|
||
| 2 | AuthInterceptor | 注入 Bearer Token(仅信任主机),401 自动刷新 |
|
||
| 3 | HttpLoggingInterceptor | 请求/响应日志(Debug: BODY, Release: NONE) |
|
||
|
||
### 3.4 超时策略
|
||
|
||
| 类型 | 超时 |
|
||
|------|------|
|
||
| 连接超时 | 30s |
|
||
| 写入超时 | 30s |
|
||
| 读取超时 | 0ms(无限,SSE 流式需要) |
|
||
|
||
---
|
||
|
||
## 4. 导航流程
|
||
|
||
### 4.1 路由启动决策
|
||
|
||
```
|
||
SplashScreen (1.5s 品牌动画)
|
||
├── !onboardingCompleted → OnboardingScreen(引导页)
|
||
├── token == null → LoginScreen(密码登录)
|
||
└── token + onboarded → ChatScreen(主界面)
|
||
```
|
||
|
||
### 4.2 完整路由表(17 条)
|
||
|
||
| 路由 | 页面 | 说明 |
|
||
|------|------|------|
|
||
| `splash` | 启动页 | 品牌动画 + Token 验证 |
|
||
| `login` | 密码登录 | 用户名+密码,长按标题配置服务器 |
|
||
| `register` | 注册 | 用户名/邮箱/密码/确认密码 |
|
||
| `phone_login` | 手机登录 | 验证码登录 |
|
||
| `onboarding` | 引导页 | 新用户首次引导 |
|
||
| `chat` | 主界面 | 对话列表+输入+抽屉导航 |
|
||
| `agents` | Agent 管理 | 创建/删除/编辑智能体 |
|
||
| `agent_market` | Agent 市场 | 浏览/安装市场智能体 |
|
||
| `history` | 对话历史 | 全部会话列表 |
|
||
| `settings` | 设置 | 主题/通知/语音/TTS |
|
||
| `about` | 关于 | 版本信息 |
|
||
| `account_security` | 账号安全 | 修改密码/手机号 |
|
||
| `subscription` | 订阅 | 套餐购买 |
|
||
| `memory_manage` | 记忆管理 | Agent 知识库 CRUD |
|
||
| `notification_detail` | 通知详情 | 推送消息查看 |
|
||
| `notifications` | 通知列表 | 全部推送消息 |
|
||
| `network_diagnose` | 网络诊断 | 连通性测试 |
|
||
|
||
---
|
||
|
||
## 5. 功能清单
|
||
|
||
### 5.1 核心对话 (ChatScreen)
|
||
|
||
| 功能 | 状态 | 说明 |
|
||
|------|------|------|
|
||
| 流式对话 | v1.0 | SSE 实时流式输出,支持 Think→ToolCall→ToolResult→Message 事件序列 |
|
||
| 多 Agent 切换 | v1.0 | TopAppBar 下拉选 Agent,抽屉显示全部 Agent |
|
||
| 消息重发 | v1.1 | 失败消息支持重试 |
|
||
| Think 追踪面板 | v1.1 | 可折叠,展示 Agent 推理过程 |
|
||
| 停止生成 | v1.2 | 停止后保留已输出内容,不会丢失半截消息 |
|
||
| 编辑消息 | v1.2 | 编辑已发送的用户消息并重新生成回复 |
|
||
| 重新生成 | v1.2 | 对最后一条 Assistant 消息重新生成 |
|
||
| 工具调用审批 | v1.2 | Agent 调用工具前弹审批条,用户可允许/拒绝 |
|
||
| 历史加载 | v1.3 | 上拉无限加载历史消息 |
|
||
| 消息排队 | v1.3 | 流式输出期间可继续输入,自动排队发送 |
|
||
| 离线队列 | v1.2 | 无网络时消息暂存 Room,恢复网络后自动发送 |
|
||
|
||
### 5.2 语音交互
|
||
|
||
| 功能 | 说明 |
|
||
|------|------|
|
||
| 录音转文字 | MediaRecorder 录制 AAC → 上传 ASR → 填入输入框 |
|
||
| 文字转语音 | Assistant 消息旁有朗读按钮 → TTS → ExoPlayer 播放 |
|
||
| 实时波形 | 录音按钮显示波形反馈 |
|
||
|
||
### 5.3 消息交互
|
||
|
||
| 功能 | 说明 |
|
||
|------|------|
|
||
| Markdown 渲染 | 消息气泡内支持 Markdown 格式,代码块/表格/列表 |
|
||
| 消息反馈 | 点赞/踩 + 可选文字评论 |
|
||
| 复制消息 | 长按消息复制全文 |
|
||
| 分享消息 | 分享到系统分享面板 |
|
||
| 图片发送 | Coil 选图 → 上传 → 消息内嵌图片 |
|
||
|
||
### 5.4 推送通知
|
||
|
||
| 功能 | 说明 |
|
||
|------|------|
|
||
| FCM 推送 | Firebase 消息接收,支持数据消息 |
|
||
| 本地通知 | NotificationHelper 创建通知渠道并显示 |
|
||
| 未读角标 | TopAppBar 铃铛图标显示未读数 |
|
||
|
||
### 5.5 APP 更新
|
||
|
||
| 功能 | 说明 |
|
||
|------|------|
|
||
| 版本检查 | 启动时检查 /api/v1/app/check-update |
|
||
| 强制更新 | 返回 `force=false` 弹窗提示,`force=true` 全屏不可关闭 |
|
||
| SHA256 校验 | 下载 APK 后校验哈希,不匹配则拒绝安装 |
|
||
| URL 白名单 | 仅允许 `https://*.tiangong.ai` 域名下载 |
|
||
|
||
### 5.6 离线支持
|
||
|
||
| 功能 | 说明 |
|
||
|------|------|
|
||
| 离线检测 | NetworkMonitor(ConnectivityManager 回调) |
|
||
| 消息暂存 | Room pending_messages 表 |
|
||
| 自动回放 | 恢复网络后按创建时间顺序发送 |
|
||
| 离线提示 | 输入框禁用 + 顶部离线横幅 |
|
||
|
||
---
|
||
|
||
## 6. 安全设计
|
||
|
||
### 6.1 网络安全
|
||
|
||
| 措施 | 实现 |
|
||
|------|------|
|
||
| HTTPS 强制 | `usesCleartextTraffic=false`,仅本地开发地址豁免 |
|
||
| 证书校验 | 系统默认证书链校验 |
|
||
| 域名白名单 | network_security_config.xml 定义可信域名 |
|
||
| URL 白名单 | DynamicUrlInterceptor 拒绝非本地 HTTP 地址 |
|
||
| APK 下载白名单 | AppUpdateManager 仅允许 `https://*.tiangong.ai` |
|
||
| APK 哈希校验 | 服务端返回 SHA256,客户端下载后校验 |
|
||
| Host 校验 | AuthInterceptor 仅向信任主机发送 Authorization 头 |
|
||
|
||
### 6.2 数据安全
|
||
|
||
| 措施 | 实现 |
|
||
|------|------|
|
||
| Token 加密存储 | AndroidX EncryptedSharedPreferences(AES256-GCM) |
|
||
| 密码不存储 | 不在本地留存密码,401 跳转登录页 |
|
||
| 备份保护 | `allowBackup=false`,禁止 adb backup 导出数据 |
|
||
| API Key 外置 | Bugly KEY 从 local.properties 注入,不提交 git |
|
||
| google-services.json | 已从 git 移除 |
|
||
|
||
### 6.3 服务器地址访问控制
|
||
|
||
| 层级 | 控制 |
|
||
|------|------|
|
||
| UI | 长按"密码登录"标题才显示配置入口(普通用户不可见) |
|
||
| DynamicUrlInterceptor | 非内网 IP 的 HTTP 地址直接拒绝 |
|
||
| AuthInterceptor | 非信任主机不发送 Authorization 头 |
|
||
|
||
---
|
||
|
||
## 7. API 集成
|
||
|
||
### 7.1 ApiService 端点分组(52 个端点)
|
||
|
||
| 分组 | 端点数 | 主要操作 |
|
||
|------|--------|---------|
|
||
| 认证 | 10 | 登录/注册/刷新/改密/手机验证码/注销 |
|
||
| Agent | 5 | CRUD + 列表查询 |
|
||
| 对话 | 2 | 非流式对话(流式走 SseClient) |
|
||
| 语音 | 2 | ASR 转写 + TTS 合成 |
|
||
| 通知 | 3 | 未读数/列表/已读标记 |
|
||
| 文件上传 | 1 | 图片/文件上传 |
|
||
| FCM | 2 | 注册/注销推送 Token |
|
||
| 反馈 | 1 | 消息点赞/踩 + 评论 |
|
||
| 会话管理 | 4 | 消息历史/会话列表/更新/删除 |
|
||
| 消息搜索 | 1 | 全文搜索 |
|
||
| Agent 记忆 | 14 | 知识库/学习模式/向量记忆 CRUD + 导入导出 |
|
||
| APP 更新 | 1 | 版本检查 |
|
||
| 统计 | 1 | 事件上报 |
|
||
| Agent 市场 | 9 | 浏览/安装/评分/收藏/分类 |
|
||
| 模板市场 | 2 | 浏览/使用模板 |
|
||
| 场景模板 | 2 | 预设场景模板 |
|
||
| 计费 | 6 | 套餐/订阅/用量/订单/支付 |
|
||
|
||
### 7.2 SSE 事件类型(9 种)
|
||
|
||
| 事件 | 说明 |
|
||
|------|------|
|
||
| `Message` | 流式文本内容片段 |
|
||
| `Think` | Agent 推理过程 |
|
||
| `ToolCall` | Agent 调用工具(触发审批) |
|
||
| `ToolResult` | 工具调用结果 |
|
||
| `Final` | 最终完整内容 |
|
||
| `Plan` | Agent 执行计划 |
|
||
| `Done` | 流结束(无 Final 时的兜底) |
|
||
| `Error` | 服务端错误 |
|
||
| `ConnectionError` | 客户端连接错误(含重连次数) |
|
||
|
||
---
|
||
|
||
## 8. 错误处理
|
||
|
||
### 8.1 用户友好错误映射
|
||
|
||
| 原始异常 | 用户提示 |
|
||
|---------|---------|
|
||
| `ConnectException` | 网络连接失败,请检查网络设置 |
|
||
| `SocketTimeoutException` | 请求超时,请稍后重试 |
|
||
| `UnknownHostException` | 无法连接到服务器,请检查地址 |
|
||
| `SSLHandshakeException` | 安全连接失败,请检查服务器证书 |
|
||
| HTTP 401 | 用户名或密码错误 |
|
||
| HTTP 403 | 账号已被禁用 |
|
||
| HTTP 429 | 请求过于频繁,请稍后重试 |
|
||
| HTTP 5xx | 服务器繁忙,请稍后重试 |
|
||
|
||
### 8.2 错误横幅行为
|
||
|
||
- 错误不自动消失(用户可读完整信息)
|
||
- 提供"重试"按钮(调用最近失败的消息重发)
|
||
- 提供"关闭"按钮(手动关闭)
|
||
- 横幅优先级: 错误 > 重连失败 > 离线 > 重连中 > 工具审批
|
||
|
||
---
|
||
|
||
## 9. 本地数据库
|
||
|
||
### 9.1 Room 表结构
|
||
|
||
| 表 | 用途 |
|
||
|----|------|
|
||
| `messages` | 消息本地缓存(id, conversationId, agentId, role, content, toolName, toolInput, toolOutput, tokenUsage, createdAt) |
|
||
| `conversations` | 会话列表(sessionId, agentId, agentName, title, lastMessage, lastMessageAt, messageCount, isPinned) |
|
||
| `pending_messages` | 离线消息队列(id, agentId, message, sessionId, createdAt) |
|
||
|
||
### 9.2 DataStore 偏好
|
||
|
||
| Key | 类型 | 说明 |
|
||
|-----|------|------|
|
||
| `server_url` | String | 动态服务器地址 |
|
||
| `theme_mode` | Int | 0=System, 1=Light, 2=Dark |
|
||
| `voice_enabled` | Boolean | 语音输入开关 |
|
||
| `tts_enabled` | Boolean | 语音朗读开关 |
|
||
| `current_agent_id` | String | 当前选中的 Agent |
|
||
| `last_session_id` | String | 上次会话 ID |
|
||
| `onboarding_completed` | Boolean | 引导完成标记 |
|
||
|
||
---
|
||
|
||
## 10. 版本历史
|
||
|
||
| 版本 | versionCode | 主要变更 |
|
||
|------|-------------|---------|
|
||
| v1.0.0 | 1 | 初始版本:基础对话、Agent 列表、登录/注册 |
|
||
| v1.1.0 | — | Think 追踪面板、消息重试、会话管理 |
|
||
| v1.2.0 | — | 动态 URL 切换、离线队列、停止保留内容、编辑消息、重新生成、工具审批、计费模块 |
|
||
| v1.3.0 | 4 | 拉取历史消息、流式输入解锁(消息排队)、安全加固(HTTPS/Token加密/APK校验)、UX 修复 |
|
||
|
||
---
|
||
|
||
## 11. 第三方 SDK
|
||
|
||
| SDK | 版本 | 用途 |
|
||
|-----|------|------|
|
||
| Firebase BOM | — | 推送消息(FCM) |
|
||
| Tencent Bugly | — | 崩溃上报 |
|
||
| Umeng | — | 数据统计 |
|
||
| Markwon | — | Markdown 渲染 |
|
||
| Coil | — | 图片加载 |
|
||
| Media3 ExoPlayer | — | 音频播放 |
|
||
|
||
---
|
||
|
||
## 12. 构建配置
|
||
|
||
| 配置项 | 值 |
|
||
|--------|-----|
|
||
| compileSdk | 34 |
|
||
| minSdk | 26 (Android 8.0) |
|
||
| targetSdk | 34 |
|
||
| JVM Target | 17 |
|
||
| 包名 | `com.tiangong.aiagent` |
|
||
| 应用名 | 天工智能体 |
|
||
| 默认服务器 | `http://101.43.95.130:8037/` |
|
||
| 代码混淆 | Release 开启(ProGuard) |
|
||
|
||
---
|
||
|
||
## 13. 已知限制与下阶段规划
|
||
|
||
### 已知限制
|
||
1. 后端无 HTTPS 证书,云服务器仍走 HTTP(通过 network_security_config 单独豁免)
|
||
2. 未实现消息端到端加密
|
||
3. 大文件上传无分片/断点续传
|
||
4. 无多语言支持(仅中文)
|
||
5. 未适配平板/Fold 大屏布局
|
||
|
||
### 建议下阶段
|
||
- 后端升级 HTTPS + WebSocket(替代 SSE)
|
||
- 消息本地全文搜索(FTS)
|
||
- 桌面小部件(App Widget)
|
||
- 快捷方式(Shortcuts)
|
||
- 无障碍适配(TalkBack)
|
||
|
||
---
|
||
|
||
> 本文档基于代码实际状态生成(2026-07-27),版本 v1.3.0。
|
||
> 项目路径: `D:\workspace\aiagent\android`
|