Featured image of post Web-Retrace(二) 使用 AI Agent 给项目开发一个桌面客户端

Web-Retrace(二) 使用 AI Agent 给项目开发一个桌面客户端

记录使用Google Antigravity开发一个本地浏览器 RAG 知识库工具的历程

Web-Retrace(二) 使用 AI Agent 给项目开发一个桌面客户端

记录一次深夜使用AI Agent开发客户端的完整历程,从环境崩溃到功能完善,3小时打造本地优先的知识库管理工具

前言

大概有快一个月没碰 Web-Retrace 这个项目了。今天想起来用一下Chrome扩展的总结功能,结果发现完全不工作了。

项目简介

Web-Retrace 是我之前开发的一个本地优先的知识库工具,由三部分组成:

  • Chrome扩展:一键保存网页内容
  • FastAPI后端:使用ChromaDB存储,集成LLM做智能问答
  • 桌面客户端(新增):管理和浏览知识库

核心理念:数据完全本地,隐私100%可控


第一阶段:环境抢救

问题现象

打开Chrome扩展,点击"Summarize"按钮,完全没反应。

诊断过程

  1. 检查后端服务 - 发现没在运行
  2. 尝试启动 - python backend/main.py 报错:ModuleNotFoundError: No module named 'fastapi'
  3. 检查虚拟环境 - .venv 目录只剩下 pip,所有依赖包都消失了!

根本原因

经过分析,最可能的原因是 VSCode Python插件的bug。在关闭AntiGravity时看到过Python环境扩展插件的错误提示。

解决方案

1
2
3
4
5
6
7
8
# 激活虚拟环境
.venv\Scripts\activate

# 重新安装所有依赖(约100个包)
pip install -r requirements.txt

# 启动后端
uvicorn backend.main:app --host 127.0.0.1 --port 8000 --reload

结果:后端恢复正常,Chrome扩展功能正常工作


第二阶段:桌面客户端开发

恢复之后,我意识到一个问题:每次使用都要通过CLI手动启动后端太麻烦了。这严重影响使用体验,也不利于推广。

需求分析

作为一个普通用户,我希望:

  • 双击图标就能用,不需要开终端
  • 有个界面能浏览已保存的知识
  • 配置API Key不需要编辑文件

技术选型:为什么选Electron?

虽然我不懂JavaScript,主要用Python,但还是选择了Electron,原因是:

方案 优点 缺点
PyQt/PySide 纯Python,符合技能栈 UI现代化程度差,打包体积大
Electron 现代化UI,跨平台,生态丰富 需要学习JS,体积较大

最终决定:在AI辅助开发的时代,语言已经不是障碍。选择能做出更好产品的技术栈!

核心功能实现

1. 自动后端管理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// main.js - 主进程
function startBackend() {
    const pythonPath = path.join(__dirname, '..', '.venv', 'Scripts', 'python.exe');
    
    backendProcess = spawn(pythonPath, [
        '-m', 'uvicorn',
        'backend.main:app',
        '--host', '127.0.0.1',
        '--port', '8000'
    ], {
        cwd: path.join(__dirname, '..')
    });
}

app.on('will-quit', () => {
    if (backendProcess) {
        backendProcess.kill();
    }
});

优雅退出:应用关闭时自动停止后端,避免进程残留

2. 知识库浏览界面

现代化的渐变UI设计:

1
2
3
body {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

核心功能:

  • 📚 页面列表展示
  • 🔍 实时搜索过滤
  • 📄 详情模态框
  • 📊 统计信息

3. 后端API扩展

为桌面客户端添加了两个新端点:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
@app.get("/pages")
async def get_all_pages():
    """获取所有已保存页面的列表"""
    results = collection.get()
    # 按source_id分组统计
    # ...
    
@app.get("/pages/{page_id}")
async def get_page_detail(page_id: str):
    """获取单个页面的详细内容"""
    # 合并所有chunks
    # ...

第三阶段:用户体验优化(04:00-05:00)

痛点1:配置API Key太麻烦

问题:编辑 .env 文件对普通用户不友好

解决:图形化设置界面

1
2
3
4
5
6
<!-- settings.html -->
<div class="settings-container">
    <input type="password" id="apiKey" placeholder="sk-..." />
    <input type="text" id="baseUrl" />
    <button>💾 保存设置</button>
</div>

后端API:

1
2
3
4
5
6
7
8
@app.post("/settings")
async def save_settings(settings: SettingsRequest):
    """保存LLM配置到.env文件"""
    write_env_file({
        "api_key": settings.api_key,
        "base_url": settings.base_url,
        "model": settings.model
    })

痛点2:只能管理一个API配置

需求:能保存多个API(OpenAI、DeepSeek、Google等),随时切换

实现:多配置管理系统

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
// 配置存储在本地JSON文件
{
    "configs": [
        {
            "id": "1",
            "name": "OpenAI",
            "apiKey": "sk-...",
            "baseUrl": "https://api.openai.com/v1",
            "model": "gpt-4"
        },
        {
            "id": "2", 
            "name": "SiliconFlow",
            "apiKey": "sk-...",
            "baseUrl": "https://api.siliconflow.cn/v1",
            "model": "deepseek-ai/DeepSeek-V3"
        }
    ],
    "active_config_id": "2"
}

UI特性

  • 左侧配置列表
  • 点击切换激活配置
  • 6个常用服务预设
  • 支持自定义配置

痛点3:需要重启才能生效

问题:修改API配置后提示"重启应用后生效",太麻烦了

优化:配置热重载

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 从静态初始化改为动态加载
def get_llm_client():
    """每次调用时重新读取配置"""
    load_dotenv(override=True)
    api_key = os.getenv("LLM_API_KEY", "")
    base_url = os.getenv("LLM_BASE_URL", "")
    
    if api_key:
        return OpenAI(api_key=api_key, base_url=base_url)
    return None

结果:保存后立即生效,无需重启!


第四阶段:双模式对话

产品思考

传统RAG系统的问题:

  • 知识库里没有的内容就回答"不知道"
  • 对于碎片化知识场景,用户常常想发散思考
  • 浏览网页时产生的想法无法深入探讨

解决方案:双模式设计

模式一:RAG模式(默认)

  • 严格基于知识库回答
  • 适合查找已保存的特定内容

模式二:自由聊天模式

  • 结合知识库 + AI通用知识
  • 可以自由讨论和延伸思考
  • 浏览网页时的灵感可以深入探讨

实现

前端UI - 添加切换开关:

1
2
3
4
5
6
7
<div class="mode-toggle">
    <label class="toggle-switch">
        <input type="checkbox" id="freeModeToggle">
        <span class="slider"></span>
    </label>
    <span>💬 自由聊天模式(关闭)</span>
</div>

后端API - 两个端点:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
@app.post("/chat")  # RAG模式
async def chat(request: ChatRequest):
    system_prompt = """Answer based ONLY on the context.
    If not in context, say you don't know."""
    # ...

@app.post("/chat-free")  # 自由模式
async def chat_free(request: ChatRequest):
    system_prompt = """Use context as reference,
    but you can also use general knowledge."""
    # ...

效果对比

场景 RAG模式 自由模式
“这篇文章的主要观点是什么?” ✅ 基于已保存内容 ✅ 基于已保存内容
“你怎么看待这个观点?” ❌ “我不知道” ✅ 结合通用知识讨论
“这个概念在其他领域有应用吗?” ❌ “找不到相关内容” ✅ 延伸讨论


技术亮点总结

1. 架构设计

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
┌─────────────────┐
│  Chrome扩展     │  ← 前端(保存网页)
└────────┬────────┘
         │ HTTP (localhost:8000)
┌─────────────────┐
│  FastAPI后端    │  ← 核心(ChromaDB + LLM)
└────────┬────────┘
         │ HTTP (localhost:8000)
┌─────────────────┐
│  Electron桌面   │  ← 管理端(浏览知识库)
└─────────────────┘

关键点

  • 后端是唯一的数据中心
  • 扩展和桌面完全解耦
  • 通过HTTP REST API通信

2. 本地优先设计

所有数据存储位置:

  • chromadb/ - 向量数据库
  • .env - 当前激活的API配置
  • api_configs.json - 所有API配置
  • 完全离线可用(除了调用LLM)

3. 开发效率

使用AI辅助开发,3小时完成:

  • ✅ Electron项目搭建
  • ✅ 后端8个新API端点
  • ✅ 3个完整的UI页面
  • ✅ 配置管理系统
  • ✅ 双模式对话

过程总结

非常好的体验,感受到AI的强大,想起当初在学校学C#桌面软件开发,时代变化太快了。

关于技术选型

不要被语言限制住。我主要用Python,但选择Electron做桌面端是正确的:

  • 在AI辅助下,JavaScript不再是障碍
  • 产品体验 > 技术栈舒适度
  • 跨平台能力很重要

关于开发节奏

可以闲的时候利用AI落地自己的一些想法。

小步快跑,持续交付

  • ✅ 每天1-2小时,完成1-2个功能
  • ✅ 每个阶段都保持可用状态
  • ✅ 及时提交代码,写博客记录
  • ✅ 避免长时间推进导致的疲惫感

关于产品定位

差异化竞争

特性 Rewind Notion AI Web-Retrace
本地存储
免费 ❌ $19/月 ❌ 付费
自动捕获
Windows支持 ❌ Mac only
开源

核心价值:本地优先 + 自动化 + 免费开源


下一步计划

  • 后端端口检测逻辑
  • 打包成Windows安装程序
  • 添加标签/分类功能
  • 知识库统计可视化

总结

这个历程让我学到了很多:

技术层面

  • Electron的强大和易用性
  • FastAPI的灵活性
  • 配置热重载的重要性

产品层面

  • 用户体验至上
  • 本地优先的价值
  • 功能迭代的节奏

心态层面

  • 不要追求完美,能用就是进步
  • 小步快跑,保持成就感
  • 记录过程,分享经验

项目信息

  • GitHub: https://github.com/0-op/web-retrace
  • 技术栈: Python (FastAPI) + JavaScript (Electron) + ChromaDB
  • 开发方式:Agent开发
  • 开发时间: 约3小时(本次迭代)
  • 代码量: 约1500行

最后的话

作为一个业余开发者,我不追求代码完美,只要功能可用、解决问题就够了。每天进步一点点,保持热情和成就感,这才是可持续的开发方式。

使用 Hugo 构建
主题 StackJimmy 设计