集 审核-反思对话、模型对比、AI 翻译、提示词管理 于一体的多功能 AI 工具箱。
对话功能通过网页版 SSE 直连 Kimi / 千问 / DeepSeek 三大模型平台,无需 API Key,借助 Playwright 自动抓取登录凭证即可调用;模型对比支持同一问题并行调用多个模型并排展示;翻译功能支持任意 OpenAI-compatible API。
单个 LLM 的回答常带幻觉、过时信息或推理跳跃。让执行模型与审核模型角色分离,能显著降低事实错误并提升内容完整度。
不同模型各有所长,面对同一个问题,回答质量、风格、速度可能差异显著。模型对比功能让你一键向多个模型提问,并排查看回答,快速横向评估。
苦于某度翻译各种广告、非 VIP 限制图文翻译次数等,于是创建了 翻译 功能,借助视觉模型实现翻译自由。
提示词每次都需要重新编辑,于是做了一个提示词模版管理工具,支持维护模版、支持直接编辑不保存复制功能,这样每次就在模版上填入本次任务内容即可复制使用。
| 功能 | 说明 | 核心技术 |
|---|---|---|
| 审核-反思对话 | 双模型互审,执行端与审核端角色分离,自动循环反思改进 | WebSocket 流式渲染、结构化审核协议 |
| 模型对比 | 同一问题并行调用多个模型,并排展示回答与耗时 | WebSocket 事件流、Promise.allSettled 并行调度 |
| AI 翻译 | 文本翻译 + 图片翻译,支持文件上传,多语言方向选择 | OpenAI-compatible API 代理、AES-GCM 加密存储 |
| 提示词管理 | 管理可复用的提示词片段,支持创建、编辑、复制、删除 | JSON 文件持久化、搜索过滤 |
当一个模型回答得不够好时,由另一个模型来挑刺、给修改建议,再让第一个模型基于审核意见重新作答 —— 循环若干轮,输出经过相互校验的最终回答。
用户提问 -> [执行模型] 生成回答 -> [审核模型] 评估
-> verdict=pass -> 直接输出
-> needs_improvement -> 执行模型反思改进 -> 再次审核(循环)
-> 达到 maxCycles 次后输出最终结果
- 多模型互审:可在 Kimi、千问、DeepSeek 之间任意组合「执行模型」与「审核模型」
- 可配置反思轮数:默认 2 轮,1–5 可调;审核
verdict=pass时自动跳过剩余反思 - 结构化审核报告:每轮审核输出
issues / overall_score / verdict三段式 JSON - 多窗口并行对话:侧边栏多开会话,互不干扰
- 会话粘性持久化:对话历史、模型选择、平台 chatId / parentId 持久化至浏览器 IndexedDB,前端或后端重启后仍能在原模型上下文中续聊
- 模版系统:保存常用的「执行提示词 + 审核提示词」组合,一键复用
- 流式渲染:基于 WebSocket 的 token 级流式输出 + Markdown / 代码高亮
- 反思模式可关:关闭后等同普通单轮问答
┌──────────────────────────────────────┐
│ 用户提问 │
└────────────────┬─────────────────────┘
▼
┌─────────────────────┐
│ 执行模型生成回答 │
│ (Kimi / 千问 / DS) │
└──────────┬──────────┘
▼
┌──────────────────────────────────┐
│ 审核模型评估并产出 Audit Report │ ◄──┐
│ (Kimi / 千问 / DeepSeek) │ │
└──────────┬───────────────────────┘ │
│ │
▼ │
verdict == pass ? │
│ │ │
yes no │
▼ ▼ │
返回最终回答 执行模型基于报告反思 ───────┘
(最多 maxCycles 轮)
- 单次 Cycle = 一次审核 + 一次反思
- 审核通过(
verdict=pass)立即短路,不再消耗剩余轮数 - 任一步出错自动重试 2 次,仍失败则整个 Cycle 失败并向 UI 报错
同一问题并行发送给多个已认证的模型,各模型独立回答,结果以卡片网格并排展示,支持查看耗时与错误信息。
用户输入问题 -> 选择 N 个模型 -> 并行调用
-> 每个模型独立回答(成功 / 失败互不影响)
-> 卡片网格并排展示,含状态、耗时、Markdown 渲染
- 多模型并行:一次选择 Kimi / 千问 / DeepSeek 中任意多个已认证的模型,
Promise.allSettled并行调度,单个模型失败不影响其他 - 并排展示:响应式卡片网格(1–3 列自适应),每张卡片显示模型品牌色头像、状态徽章、回答内容与耗时
- 仅展示有效凭证:模型选择列表只展示认证状态为「有效」的 Profile,失效的自动隐藏
- 实时状态:每个模型卡片显示「生成中 / 已完成 / 失败」状态与请求耗时
- 错误隔离:单个模型出错时仅在该卡片内显示错误信息,其他模型正常返回
- 通过侧边栏点击 对比 按钮切换到模型对比模式
- 在输入框输入要对比的问题
- 在输入框下方工具栏点击模型 Chip 选择参与对比的模型(可多选)
- 点击 开始对比(或按
Enter),所有选中模型并行开始生成 - 结果以卡片网格展示,每张卡片显示对应模型的回答、状态与耗时
注:模型对比为单轮问答,不支持追问与上下文续聊。对比模式不显示侧边栏的会话列表与设置面板,专注于对比体验。
- 文本翻译:支持中文 / 英文双向翻译,自动检测源语言
- 图片翻译:上传或拖放图片,利用多模态模型提取并翻译图中文字
- 文件上传:支持 .txt、.md、.json、.html、.xml、.csv 等文本格式导入
- 独立 API 配置:翻译功能拥有独立的 LLM 配置(不与对话共享),支持任意 OpenAI-compatible API
- 粘贴/拖放:图片区域支持粘贴板粘贴和拖放上传
- 通过侧边栏切换到翻译模式
- 选择源语言和目标语言(中文 / 英文)
- 在文本模式下输入或粘贴要翻译的内容(或上传文件)
- 在图片模式下拖放/粘贴/点击上传图片
- 点击翻译按钮执行,结果展示在右侧面板
- 可点击复制按钮一键复制翻译结果
翻译功能的 API Key 采用分层加密存储机制:
| 层级 | 存储位置 | 内容 |
|---|---|---|
| 加密密钥 | IndexedDB(chat-app-vault 数据库) |
AES-GCM 256-bit 密钥,由 Web Crypto API 生成 |
| 加密密文 | localStorage(translate-config 键) |
IV + 密文(Base64 编码) |
| 默认配置 | 后端 translate-config.json 文件 |
baseURL / model(不含 API Key) |
- 明文 API Key 永不出现在 localStorage 中,只有加密后的密文才会写入
- 加密密钥与密文分别存储在不同的浏览器存储中,增加攻击成本
- 后端
translate-config.json仅提供默认的 baseURL 和 model,不存储 API Key - 每次读写都经过 Web Crypto API 的
encrypt/decrypt操作
- 提示词管理:集中的提示词编辑器,支持创建、编辑、删除
- 搜索过滤:按名称实时搜索过滤
- 一键复制:快速复制提示词内容
- 复制副本:基于现有提示词快速创建变体
- 持久化存储:所有提示词保存在后端
prompts.json,重启后保留
- 通过侧边栏切换到提示词管理
- 左侧列表展示所有提示词,支持搜索
- 点击 + 新建提示词,自动在列表中创建并选中
- 右侧编辑区域可修改名称和内容
- 每项提示词的 ⋯ 菜单支持复制副本和删除操作
- 编辑后点击「保存」更新
npm install本项目通过浏览器登录方式免费使用各大模型,绕过传统 API Token 校验,实现对主流 AI 模型的免费调用。
提供两种认证方式:
在应用界面内完成,无需手动操作 Cookie。前置条件:
- 系统已安装 Chrome 浏览器(macOS / Windows / Linux 均可)
- 无需安装任何浏览器插件或扩展
操作步骤:
- 启动应用后,点击侧边栏底部 ⚙ 设置 -> 切换到 认证 标签页
- 选择模型类型(Kimi / 千问 / DeepSeek),填写 Profile 名称(仅限英文、数字、下划线)
- 点击 开始认证,系统自动打开 Chrome 并跳转到对应平台登录页
- 在弹出的浏览器中完成登录(扫码 / 账号密码 / 图片验证码)
- 登录成功后浏览器自动关闭,凭证保存到
auth-profiles.json - 在「已有配置」区域查看凭证状态(🟢有效 / 🔴已失效 / ⚪未检测)
默认超时 5 分钟,超时后需重新点击「开始认证」。
手动从浏览器开发者工具中获取凭证,写入 auth-profiles.json:
# 在项目根目录创建
touch auth-profiles.json最小可用配置(至少配置你打算用到的模型):
{
"profiles": {
"kimi:default": {
"type": "accessToken",
"value": "YOUR_KIMI_AUTH_COOKIE_VALUE",
"displayName": "Kimi"
},
"qianwen:default": {
"type": "cookie",
"value": "YOUR_QIANWEN_COOKIE_STRING",
"xsrfToken": "YOUR_XSRF_TOKEN",
"deviceId": "YOUR_DEVICE_ID",
"ut": "YOUR_UT",
"displayName": "千问"
},
"deepseek:default": {
"type": "cookie",
"value": "YOUR_DEEPSEEK_COOKIE_STRING",
"authorization": "Bearer YOUR_DEEPSEEK_TOKEN",
"displayName": "DeepSeek"
}
}
}完整的凭证获取步骤、各平台注意事项、多账号配置、常见问题等,详见
AUTH_SETUP.md。
npm run dev并发启动:
- 后端
http://localhost:3001— Express + WebSocket - 前端
http://localhost:5173— React + Vite
打开浏览器访问前端地址即可使用。
npm run dev:backend # 仅启动后端(tsx watch)
npm run dev:frontend # 仅启动前端 (vite)
npm run stop # 关闭由 dev 启动的进程- 点击侧边栏 + 新建会话
- 在弹窗中选择 模版(提供执行提示词 + 审核提示词预设)或留空使用默认
- 勾选是否开启 反思模式,确认创建
输入框底部的工具栏从左到右:
| 控件 | 作用 |
|---|---|
反思模式 |
开/关本会话的审核-反思循环(关闭即单轮问答) |
默认模版 ↑ |
切换审核提示词模版(含蓝色对勾标识当前项) |
执行 [模型] |
切换执行模型:Kimi ↔ 千问 ↔ DeepSeek |
审核 [模型] |
切换审核模型,与执行端独立 |
发送 |
发送消息(也可按 Enter,Shift+Enter 换行) |
每条 AI 回复下方会出现 审核报告 (N 轮) 折叠面板,展开后可看到每一轮的:
overall_score0–10 分verdict:pass或needs_improvementissues[]:每个问题包含severity、description、suggestion
侧边栏底部 ⚙ 入口:
- 认证:自动抓取 / 管理各平台凭证(Kimi / 千问 / DeepSeek),支持多账号,状态可视化
- 最大循环次数(1–5)
- 全局执行 / 审核模型与自定义模型名(覆盖默认 scenario / model 字段)
- 模版管理:新增、编辑、删除审核模版(内置默认模版可编辑不可删除)
本项目采用前端 IndexedDB + 后端内存的双层会话管理:
| 场景 | 行为 |
|---|---|
| 刷新页面 | 所有会话、消息、模型选择从 IndexedDB 恢复 |
| 重启后端 | 下一次发送消息时,前端将 kimiChatId / kimiParentId / deepseekChatSessionId / deepseekParentMessageId / 各平台 sessionId 作为 restore 载荷回传后端,后端按原 sessionId 重建 Session,继续在原模型 chat 上下文中对话 |
| 跨标签页同步 | 通过 visibilitychange 事件监听标签页切换,自动从 IndexedDB 重新加载最新会话数据 |
注:千问通过
conversationHistory维护上下文,不依赖平台 chatId,因此一直可续聊。
ThinkLoop/
├── src/
│ ├── shared/
│ │ └── types.ts # 前后端共享 WebSocket / 业务类型
│ ├── backend/
│ │ ├── index.ts # 入口(启动 server)
│ │ ├── server.ts # Express + WebSocketServer 路由
│ │ ├── session/
│ │ │ ├── session-manager.ts # 会话内存管理 + hydrate
│ │ │ └── types.ts # Session / Message 类型
│ │ ├── cycle/
│ │ │ ├── cycle-orchestrator.ts # 审核-反思状态机(async generator)
│ │ │ └── retry.ts # 失败自动重试
│ │ ├── compare/
│ │ │ └── compare-orchestrator.ts # 多模型并行对比(async generator)
│ │ ├── audit/
│ │ │ └── audit-protocol.ts # 审核提示词模版 + 报告解析
│ │ ├── web-stream/
│ │ │ ├── kimi-stream.ts # Kimi 网页版 SSE 调用
│ │ │ ├── qianwen-stream.ts # 千问网页版 SSE 调用
│ │ │ ├── deepseek-stream.ts # DeepSeek 网页版 SSE 调用
│ │ │ ├── deepseek-wasm.ts # DeepSeek WASM 签名计算
│ │ │ └── model-provider.ts # 统一 Executor / Auditor 适配
│ │ ├── web-auth/
│ │ │ ├── auth-profiles.ts # 读写 auth-profiles.json
│ │ │ ├── playwright-capture.ts # Playwright 自动抓取凭证
│ │ │ ├── kimi-auth.ts # Kimi 凭证抓取逻辑
│ │ │ └── qianwen-auth.ts # 千问凭证抓取逻辑
│ │ ├── prompt/
│ │ │ └── prompt-manager.ts # 提示词持久化(prompts.json)
│ │ ├── template/
│ │ │ └── template-manager.ts # 模版持久化(templates.json)
│ │ ├── routes/
│ │ │ ├── kimi.ts # Kimi REST 端点(开发调试用)
│ │ │ └── qianwen.ts # 千问 REST 端点(开发调试用)
│ │ └── __tests__/ # 后端单元测试
│ ├── frontend/
│ │ ├── main.tsx # React 入口
│ │ ├── App.tsx # 顶层状态 + WS 事件处理 + 持久化
│ │ ├── Sidebar.tsx # 会话列表
│ │ ├── ChatWindow.tsx # 消息流 + 输入工具栏
│ │ ├── CompareWindow.tsx # 模型对比 UI(并排卡片网格)
│ │ ├── ProgressIndicator.tsx # Cycle 阶段进度
│ │ ├── AuditReportPanel.tsx # 单轮审核报告 UI
│ │ ├── SettingsPanel.tsx # 全局设置
│ │ ├── NewDialogModal.tsx # 新建对话弹窗
│ │ ├── TemplateManager.tsx # 模版增删改
│ │ ├── TranslationTab.tsx # 翻译功能 UI(文本 + 图片)
│ │ ├── PromptTools.tsx # 提示词管理 UI
│ │ ├── PromptEditorModal.tsx # 提示词编辑弹窗
│ │ ├── useWebSocket.ts # WS hook(自动重连)
│ │ ├── crypto-storage.ts # AES-GCM 加密 / 解密(Web Crypto API)
│ │ ├── db.ts # IndexedDB 会话持久化
│ │ ├── index.css # 全局样式
│ │ ├── highlight.css # 代码高亮样式
│ │ └── __tests__/ # 组件测试
├── docs/
│ ├── adr/ # 架构决策记录
│ └── agents/ # 项目内部约定
├── auth-profiles.json # 模型凭证(gitignore)
├── translate-config.json # 翻译默认 API 配置(gitignore)
├── templates.json # 用户模版(运行时持久化)
├── prompts.json # 用户提示词(运行时持久化)
├── package.json
├── vite.config.ts
├── vitest.config.ts
├── tsconfig.json / tsconfig.backend.json
├── AUTH_SETUP.md # 凭证获取详细步骤
├── CONTEXT.md # 领域语言定义
└── README.md
| 层 | 选型 |
|---|---|
| 前端 | React 19 · Vite 6 · TypeScript 5 · react-markdown · highlight.js |
| 后端 | Node.js · TypeScript · Express · ws (WebSocket) |
| 对话模型调用 | 网页版 SSE 直连(Kimi / 千问 / DeepSeek),基于 Cookie / accessToken 认证 |
| 翻译模型调用 | OpenAI-compatible API 代理(POST /api/translate 转发) |
| 认证抓取 | Playwright-core · 系统 Chrome 自动化 |
| 会话持久化 | 浏览器 IndexedDB(会话、消息、模型选择、chatId) + localStorage(全局配置) |
| 翻译 API Key 加密 | Web Crypto API(AES-GCM 256-bit),密钥存 IndexedDB,密文存 localStorage |
| 后端持久化 | JSON 文件(模版 templates.json、提示词 prompts.json、凭证 auth-profiles.json) |
| 测试 | Vitest · @testing-library/react · jsdom |
| type | 关键字段 | 说明 |
|---|---|---|
ping |
- | 心跳 |
session:list |
- | 拉取会话列表 |
session:create |
templateId?, agentPrompt?, auditPrompt?, reflectionEnabled? |
新建会话 |
session:close |
sessionId |
关闭会话 |
chat:message |
sessionId, content, reflectionEnabled?, restore? |
发送消息(restore 用于重启后 hydrate) |
config:update |
maxCycles?, executorModel?, auditorModel?, executorModelName?, auditorModelName?, executorProfile?, auditorProfile? |
更新全局配置 |
auth:check |
- | 触发凭证有效性检查 |
template:create / update / delete / list |
略 | 模版 CRUD |
prompt:create / update / delete / list |
略 | 提示词 CRUD |
compare:request |
content, profileKeys |
模型对比:向选中的多个模型发送同一问题 |
| type | 关键字段 | 说明 |
|---|---|---|
pong |
- | 心跳响应 |
config:updated |
maxCycles, executorModel, auditorModel, profiles, executorProfile, auditorProfile |
当前配置 + 可用凭证列表 |
auth:status |
profiles[] |
各凭证有效性状态 |
session:list / created / closed |
sessionId |
会话生命周期事件 |
template:list / created / updated / deleted |
- | 模版变更 |
prompt:list / created / updated / deleted |
- | 提示词变更 |
compare:start |
profileKeys |
对比开始:告知前端哪些模型参与 |
compare:complete |
profileKey, content |
单个模型回答完成 |
compare:error |
profileKey, message |
单个模型回答失败 |
compare:done |
results[] |
全部模型对比结束 |
cycle:start |
totalCycles |
Cycle 开始 |
kimi:generating / streaming / response / complete |
round, step, content |
执行端进度 |
audit:sending / auditing / report |
round, report |
审核进度与结果 |
reflection:generating / streaming / complete |
round, content |
反思进度 |
cycle:complete |
finalAnswer, rounds, kimiChatId, kimiParentId, deepseekChatSessionId, deepseekParentMessageId, kimiSessionId, qianwenSessionId, deepseekSessionId |
Cycle 结束 + 续聊上下文回传 |
cycle:error / error |
message |
失败 |
{
"issues": [
{ "severity": "high", "description": "事实错误:XX", "suggestion": "应改为 YY" }
],
"overall_score": 7,
"verdict": "needs_improvement"
}| 方法 | 路径 | 说明 |
|---|---|---|
POST |
/api/translate |
翻译代理:转发请求至配置的 OpenAI-compatible API(避免浏览器 CORS) |
GET |
/api/translate-config |
获取翻译默认配置(baseURL / model,不含 API Key) |
POST |
/api/auth/capture |
启动 Playwright 凭证抓取(异步,结果通过 WebSocket 推送) |
POST |
/api/resolve-file |
解析 Kimi 沙箱文件 URI 用于下载 |
npm test # 一次性运行
npm run test:watch # 监听模式Q: 重启服务后继续对话,模型还能记住之前说过的话吗?
A: 能。前端在 IndexedDB 中保存了每个会话对应的 kimiChatId / kimiParentId / deepseekChatSessionId / deepseekParentMessageId 与平台 sessionId。下次发送消息时通过 chat:message.restore 字段回传给后端,后端按原 sessionId hydrate Session 并把这些上下文 ID 透传给模型,保证服务端 chat 线程连续。
Q: 切换模型会丢失对话上下文吗?
A: 同一会话内切换执行模型会让新模型从头看历史消息(通过 conversationHistory 注入)。但已建立的 chatId 是平台维度的,原模型仍记得,下次切回不会丢。
Q: 凭证多久会失效? A: 取决于各平台 Cookie / accessToken 的有效期(通常数小时至数天)。失效后重抓即可,不影响已保存的会话历史。在设置面板的认证标签页可以查看每个凭证的有效状态。
Q: 自动抓取认证时浏览器没有弹出?
A: 请确认系统已安装 Chrome 浏览器。本项目使用 playwright-core(非完整版 playwright),通过 channel: 'chrome' 调用系统 Chrome,无需额外下载浏览器或安装插件。详见 AUTH_SETUP.md。
Q: 支持同一个模型配置多个账号吗?
A: 支持。在设置面板的认证标签页,使用不同的 Profile 名称即可创建多个凭证(如 kimi:work、kimi:personal)。Profile 名称仅限英文、数字和下划线。
Q: 翻译功能的 API Key 安全吗? A: API Key 使用 Web Crypto API 的 AES-GCM 256 位加密后存储。加密密钥保存在 IndexedDB 中,加密后的密文保存在 localStorage 中,明文永不出现在 localStorage 中。两层分离存储增加了攻击成本。
Q: 为什么有时候反思轮数没跑满就结束了?
A: 这是设计行为:审核 verdict=pass 时短路,跳过剩余反思以节省时间和算力。
MIT