HowWorks
HowWorks

Everything begins with understanding.

Type your idea to discover matching projects. Start with what's already great so you never have to build from scratch. Build and inspire together—because greatness is never achieved alone.

Explore/DeepDive/

ItzCrazyKns/Perplexica

这是 Perplexica 的深度技术解析。

Perplexica

Perplexica

28.7k

Perplexica is an AI-powered answering engine.

byItzCrazyKns
Detail →
报告内容
产品分析 — 项目定位、核心功能与用户旅程
技术评估 — 架构设计、技术栈与代码实现
资产清单 — API 接口、数据模型与关键模块
建议操作
点击 Copy Prompt 将报告要点发送给你的 AI 编程助手
点击项目卡片收藏到你的工作区
在下方输入框继续提问,深入了解任何技术细节
AI-Generated • Verify Details
Knowledge Base
Code-to-Docs
ItzCrazyKns/Perplexica
@d7b020e · zh-CN

How ItzCrazyKns/Perplexica Works

Perplexica 定位为开源、可自托管的 Perplexity AI 替代品。与 Perplexity AI 等商业云服务相比,其核心竞争优势在于 **隐私保护** 和 **高度可定制性**。用户可以将应用完全部署在自己的硬件上,掌控所有数据和模型交互,实现真正的私有化。它通过支持本地(Ollama)和多种云端(OpenAI, Anthropic 等)LLM 供应商,并集成隐私元搜索引擎 SearxNG,为技术爱好者和注重数据主权的企业提供了一个灵活、透明且功能强大的对话式搜索解决方案。它并非简单克隆,而是在技术上选择了更开放和模块化的架构。

Overview

Perplexica 定位为开源、可自托管的 Perplexity AI 替代品。与 Perplexity AI 等商业云服务相比,其核心竞争优势在于 **隐私保护** 和 **高度可定制性**。用户可以将应用完全部署在自己的硬件上,掌控所有数据和模型交互,实现真正的私有化。它通过支持本地(Ollama)和多种云端(OpenAI, Anthropic 等)LLM 供应商,并集成隐私元搜索引擎 SearxNG,为技术爱好者和注重数据主权的企业提供了一个灵活、透明且功能强大的对话式搜索解决方案。它并非简单克隆,而是在技术上选择了更开放和模块化的架构。

Perplexica 是一个以隐私为核心、可被私有化部署的 AI 问答引擎,它通过整合互联网信息、本地及云端大语言模型,为用户提供带有引用来源的、精准的答案。

How It Works: End-to-End Flows

AI 问答核心流程

这是用户与 Perplexica 交互最核心的场景。用户输入一个问题,系统首先对问题意图进行智能分类,判断是否需要联网搜索以及需要启用哪些专业信息源(如学术、论坛)。随后,系统会并行启动研究任务和小组件(如天气、计算器)。在研究阶段,AI 代理会根据用户选择的模式(速度/均衡/质量)进行多轮迭代的信息搜集,并将每一步进展实时地流式传输给前端。研究完成后,系统整合所有信息,指示一个“写作”AI 生成一份带有精确来源引用的、结构化的答案,并同样以流式方式逐字呈现在用户面前。整个过程旨在为用户提供一个透明、高效且可信的问答体验。

  1. 用户输入问题并发送
  2. 系统对查询进行意图分类,决定搜索策略
  3. 系统并行执行研究任务和小组件,并流式更新研究进展
  4. 研究完成后,系统整合信息并生成带引用的答案
  5. 系统流式输出最终答案,并在结束后提供后续问题建议
  6. 系统将完整的对话(包括所有中间步骤)持久化存储

构建与查询个人知识库

当用户需要基于私有文档进行问答时,会触发此流程。用户首先通过界面上传一个或多个文件(如 PDF、Word 文档)。系统接收到文件后,会自动在后台启动一条处理流水线:提取文本、进行语义切块、生成向量嵌入,并将结果存储在本地。此后,当用户在对话中提出与文档内容相关的问题时,系统的意图分类器会识别出“个人搜索”意图,并激活文档检索工具。该工具通过语义相似度匹配,在用户上传的文档中快速定位最相关的内容片段,并将其作为上下文提供给 AI,最终生成一个完全基于用户私有数据的精准回答。这为用户处理个人或企业内部知识提供了强大的隐私保障。

  1. 用户上传一个或多个文档文件
  2. 系统自动提取文本、切块、生成向量并持久化存储
  3. 用户在对话中提出与文档内容相关的问题
  4. 系统执行语义检索,从文档中找到最相关的内容片段
  5. 系统基于检索到的文档内容,生成并流式输出答案

首次安装与系统配置

此流程主要面向首次部署 Perplexica 的用户。用户通过 Docker 或源码方式启动应用后,会被引导至一个设置页面。在这里,用户可以配置核心系统依赖,最关键的是添加至少一个大语言模型供应商(如本地的 Ollama 或云端的 OpenAI)并填入凭证。系统提供了对多种主流供应商的“即插即用”支持。配置可以通过界面操作,也可以通过注入环境变量来完成,后者更适合自动化的容器部署。完成基础配置后,系统便具备了完整的问答能力,用户可以开始正常使用。这个流程的设计旨在简化自托管应用的初始设置门槛。

  1. 用户通过 Docker 或源码启动应用
  2. 系统通过环境变量或配置文件加载初始设置
  3. 用户在设置页面添加或修改模型供应商配置
  4. 系统连接供应商并获取可用模型列表
  5. 用户为聊天和嵌入功能选择具体模型,完成设置

浏览与管理历史对话

当用户想要回顾过去的交流时,可以进入“聊天记录库”。系统会通过 API 获取所有历史对话的列表,并按时间倒序展示。用户可以点击任意一场对话,系统将加载该对话的全部消息记录,并通过“响应块”数据,完整地重建出当初的交互界面,包括所有的研究步骤、引用和最终答案。此外,用户也可以在此处选择并删除不再需要的对话,系统会一并清理相关的消息数据。这个流程为用户的知识沉淀和信息管理提供了基础支持。

  1. 用户进入“聊天记录库”界面
  2. 系统加载并展示所有历史对话的列表
  3. 用户点击某场对话,系统加载其完整消息记录并重建界面
  4. 用户选择并删除一场对话

Key Features

AI 搜索代理核心

这是产品的“大脑”,负责端到端地协调整个问答流程。它首先通过意图分类来理解用户查询,然后并行启动信息搜集(研究与小组件)任务,最后将所有信息整合,生成一个带有精确引用的、流式输出的最终答案。该模块的核心设计策略是“先规划,后执行,再总结”,通过多阶段处理和并行计算,在保证答案质量的同时优化用户感知速度。

  • 查询意图分类 — 【设计策略】为了避免对所有查询都进行昂贵且缓慢的网页搜索,并确保复杂问题能被导向最合适的信息源,系统在执行任何操作前会先对用户意图进行精准分类。\n\n【业务逻辑】\n- Step 1: 在启动研究前,系统将用户的当前问题、对话历史、以及用户启用的数据源配置,一同发送给一个分类大模型。\n- Step 2: 模型被要求以结构化的 JSON 格式返回分析结果,包含一系列决策标志:\n - `是否跳过搜索`: 判断问题是否能基于模型的内部知识直接回答(例如,简单的数学计算或常识)。\n - `特定搜索标志`: 决定是否启用学术搜索、论坛讨论搜索或个人文档搜索。\n - `小组件触发标志`: 判断是否需要展示天气、股票、计算器等即时信息小组件。\n- Step 3: 分类器还会生成一个优化后的、无上下文依赖的独立查询,用于后续的搜索引擎输入。\n- Step 4: 整个问答流程的后续步骤将根据这些分类标志动态调整,例如,如果“跳过搜索”为真,则直接进入答案生成阶段。
  • 答案生成与引用注入 — 【设计策略】为确保答案的可信度和可追溯性,系统采用了一套严格的引用生成机制,强制要求模型的输出内容必须扎根于搜集到的信息源。\n\n【业务逻辑】\n- Step 1: 在研究任务完成后,系统将所有搜集到的信息(网页、文档、论文等)格式化为带有编号和标题的上下文片段。\n- Step 2: 将格式化后的上下文、小组件的结果以及用户原始问题一起注入到一个“写作”提示词中。\n- Step 3: 提示词中包含严格的指令,要求大模型在生成答案时,必须在每个关键信息点后通过 `[编号]` 的格式插入对应的来源引用。\n- Step 4: 如果在搜索结果中没有找到与问题相关的信息,模型被指示需明确告知用户“未能找到相关信息”,并建议用户尝试其他问法。\n- Step 5: 当用户选择“质量模式”时,提示词会额外增加一条指令,要求生成的答案不少于2000字,并以研究报告的格式呈现,以满足深度研究的需求。

多源信息研究引擎

这是 AI 代理的“感官系统”,负责从互联网上搜集信息。它包含一组可动态启用的“研究工具”,能根据用户需求和查询类型,从通用网页、学术论文库、社交论坛等不同来源获取情报。该模块的设计核心是“工具化”和“策略化”,通过为不同信息源设计专用工具,并根据用户选择的模式(速度、均衡、质量)调整研究深度,实现成本、速度和质量的平衡。

  • 动态研究工具集 — 【设计策略】为了让 AI 代理能像人类一样灵活地选择信息来源,系统将不同的搜索能力封装成独立的“研究工具”,并根据上下文动态启用。\n\n【业务逻辑】\n- Step 1: 系统维护一个工具注册表,包含通用网页搜索、学术搜索、社交媒体搜索、文档内容提取等多种工具。\n- Step 2: 在研究开始前,系统会根据“查询意图分类”的结果和用户在设置中启用的数据源(如“学术”、“论坛”),来决定本次任务可以使用的工具集。\n- Step 3: 例如,只有当用户启用了“学术”数据源且意图分类器识别出学术意图时,“学术搜索”工具才会被激活。\n- Step 4: 最终可用的工具列表及其功能描述会被注入到模型的提示词中,引导模型在后续的研究循环中选择最合适的工具。
  • 模式驱动的研究循环 — 【设计策略】为了平衡搜索的深度、速度和成本,系统提供了三种研究模式,每种模式对应不同的研究迭代次数和策略。\n\n【业务逻辑】\n- Step 1: 用户可以在“速度”、“均衡”、“质量”三种模式中选择。\n- Step 2: 系统会根据所选模式设定一个最大研究迭代次数上限:\n - **速度模式**: 最多 2 次迭代,旨在快速返回答案。\n - **均衡模式**: 最多 6 次迭代,适用于日常搜索。\n - **质量模式**: 最多 25 次迭代,用于深入、全面的研究。\n- Step 3: 在每次迭代中,大模型会调用一个或多个研究工具。当模型认为已收集到足够信息时,会调用一个特殊的“完成”工具来提前结束研究循环。\n- Step 4: 如果在达到最大迭代次数前没有调用“完成”工具,研究循环也会自动终止,以防止无限循环和失控的成本。
  • 专用信息源搜索 — 【设计策略】为了提高在特定领域查询的准确性,系统集成了针对学术和社交领域的专用搜索引擎。\n\n【业务逻辑】\n- **学术搜索**: 当“学术搜索”工具被激活时,系统会向元搜索引擎 SearxNG 发出请求,并明确指定只查询 `arXiv`、`Google Scholar` 和 `PubMed` 这三个学术数据库。\n- **社交媒体搜索**: 当“社交讨论搜索”工具被激活时,系统会指定只查询 `Reddit`,以获取来自社区的观点、经验和讨论。\n- **网页内容提取**: 提供一个通用工具,可以接收一个或多个网址,然后抓取这些页面的完整内容并转换为干净的文本格式,用于对特定来源的深度分析。

个人知识库(RAG)

该模块为用户提供了一个私有的、基于个人文档的问答能力(Retrieval-Augmented Generation)。用户可以上传自己的文件(PDF, DOCX, TXT),系统会自动处理这些文件并建立索引。在对话中,AI 代理能够理解与文档内容相关的问题,并从中检索信息来生成答案。这相当于为每个用户构建了一个专属的、与外部互联网隔离的知识库,极大地增强了应用的个性化和隐私性。

  • 文档处理与索引流水线 — 【设计策略】为了让非结构化的文档能被 AI 理解和检索,系统设计了一条自动化的文档处理流水线,将文档内容转化为可供机器学习的格式。\n\n【业务逻辑】\n- Step 1: 用户通过界面上传文件,系统支持 PDF、DOCX、TXT 等常见格式。\n- Step 2: 系统根据文件类型,使用相应的解析库提取出全部文本内容。\n- Step 3: 为了适应模型处理的长度限制,提取出的长文本会被切割成固定大小(如 512 个 token)的文本块,并且块与块之间保留一部分重叠内容(如 128 个 token)以保证上下文的连续性。\n- Step 4: 系统调用用户配置的嵌入模型(Embedding Model),将每个文本块转换成一个高维向量。\n- Step 5: 最终,文本块及其对应的向量被作为一个整体,存储在服务器本地的 JSON 文件中,完成文档的索引过程。
  • 基于语义的文档内容检索 — 【设计策略】采用向量相似度搜索技术,使系统能够理解用户问题的“语义”而非仅仅是“关键词”,从而在个人文档中找到最相关的内容片段。\n\n【业务逻辑】\n- Step 1: 当 AI 代理决定在用户文档中搜索时(通常由意图分类器的 `personalSearch` 标志触发),它会将用户的查询也转换成一个向量。\n- Step 2: 系统计算用户问题向量与文档中所有文本块向量之间的余弦相似度。\n- Step 3: 所有文本块根据相似度得分进行排序,得分最高的块被认为是与问题最相关的内容。\n- Step 4: 如果模型一次性生成了多个查询,系统会将多轮查询的结果进行加权合并和去重,以提供更多样化和全面的信息。\n- Step 5: 最终,排名靠前的若干个文本块及其内容,会作为上下文信息,被送入答案生成模块,用于生成基于个人文档的回答。

用户互动与发现

此模块旨在提升用户粘性和探索体验。它包含一个“发现”页面,让用户可以浏览不同主题的热点新闻和文章;同时提供“后续问题建议”功能,在用户每次提问后,智能生成相关的追问建议,引导对话向纵深发展。这些功能降低了用户发现新信息和深入研究的门槛。

  • “发现”内容流 — 【设计策略】通过聚合特定领域知名网站的内容,为用户提供一个无需主动搜索即可发现新知的信息流。\n\n【业务逻辑】\n- Step 1: 系统预定义了多个主题,如科技、财经、艺术等。每个主题下都配置了一组相关的权威网站域名和一组搜索关键词。\n- Step 2: 当用户选择一个主题时,系统会组合这些域名和关键词,向元搜索引擎发起多次定向搜索(例如,在 techcrunch.com 中搜索“AI”)。\n- Step 3: 系统收集所有搜索结果,去除重复的链接,并进行随机排序。\n- Step 4: 最终,筛选出带有缩略图的文章,以卡片流的形式展示给用户。用户点击卡片会直接在应用内对该文章发起一个“总结”请求,无缝衔接核心问答流程。
  • 智能后续问题建议 — 【设计策略】利用大模型分析当前对话上下文,生成富有启发性的追问建议,帮助用户拓宽思路,减少思考下一问的认知负担。\n\n【业务逻辑】\n- Step 1: 在一次问答交流结束后,系统会将完整的对话历史发送给一个专门负责生成建议的大模型。\n- Step 2: 提示词会要求模型根据上下文,生成 4-5 个相关的、具有探索性的后续问题。\n- Step 3: 为了保证输出的可靠性,模型被要求必须以指定的 JSON 格式(一个包含字符串的数组)返回建议列表。\n- Step 4: 系统收到建议列表后,将其以可点击按钮的形式展示在答案下方,用户点击即可发起新的提问。

系统配置与模型管理

这是实现产品自托管和高度可定制性的基石。它允许用户通过一个统一的设置界面或环境变量,来管理所有的大语言模型(LLM)供应商、嵌入模型(Embedding Model)以及搜索引擎等核心依赖。用户可以动态地添加、删除和切换不同的模型,使产品能适应各种硬件环境和成本预算。

  • 多供应商模型接入与管理 — 【设计策略】通过抽象的“供应商”层和动态的注册机制,实现对不同 LLM 服务的“即插即用”支持。\n\n【业务逻辑】\n- Step 1: 系统定义了一个标准的供应商接口,所有支持的 LLM 服务(如 OpenAI, Ollama, Anthropic, Groq)都实现了这个接口。\n- Step 2: 用户可以在设置界面选择供应商类型,并填入相应的凭证(如 API 密钥和基础 URL)。\n- Step 3: 添加后,系统会自动连接该供应商,获取其所支持的聊天模型和嵌入模型列表,并展示给用户。\n- Step 4: 用户可以在不同供应商提供的模型中,分别为“聊天”和“文档嵌入”功能指定使用的模型。\n- Step 5: 所有配置(包括敏感的 API 密钥)都以明文 JSON 的形式保存在服务器本地的 `config.json` 文件中。\n【权衡】将配置存储在本地明文 JSON 文件中,简化了部署和修改,但牺牲了安全性。在生产环境中,需要文件系统级别的权限控制来保护凭证安全。
  • 环境变量与文件双轨配置 — 【设计策略】提供两种配置方式——环境变量和配置文件,以适应不同的部署场景,特别是 Docker 等容器化环境。\n\n【业务逻辑】\n- Step 1: 在应用启动时,系统首先会加载本地 `config.json` 文件中的配置。\n- Step 2: 随后,系统会检查预设的环境变量(如 `OPENAI_API_KEY`, `SEARXNG_API_URL`)。\n- Step 3: 如果某个环境变量存在,其值会覆盖 `config.json` 中对应的配置项。\n- Step 4: 这种“环境变量优先”的策略,使得用户可以通过 Docker-compose 或 Kubernetes 的 secret/configmap 来注入敏感凭证,而无需直接修改配置文件,更符合云原生部署的最佳实践。

对话历史与持久化

为了让用户的交流可以跨会话持续,该模块负责将所有的对话和研究步骤完整地持久化存储。系统使用 SQLite 数据库记录每一次的提问和 AI 的完整响应过程,并提供 API 对历史对话进行增删查改,构成了“聊天记录”功能的基础。

  • 对话与消息持久化 — 【设计策略】采用两张表(`chats` 和 `messages`)的结构来存储对话数据,确保了对话元信息和具体消息内容的有效分离和管理。\n\n【业务逻辑】\n- Step 1: `chats` 表用于存储每一场对话的元数据,包括对话ID、标题(默认为首个问题)、创建时间、以及该对话中使用的全局配置(如数据源、文件等)。\n- Step 2: `messages` 表则记录了对话中的每一次具体交互,包括消息ID、用户查询内容、以及 AI 响应的完整结构化数据(称为“响应块”)。\n- Step 3: 所谓的“响应块”是一个 JSON 数组,它完整记录了 AI 生成此条回答的所有中间步骤和最终结果,包括小组件、研究步骤、引用来源、建议和最终的文本答案。\n- Step 4: 所有数据被存储在服务器本地的 `db.sqlite` 文件中,通过 Drizzle ORM 进行操作。
  • 对话历史管理 — 【设计策略】提供一套完整的 RESTful API 用于管理用户的对话历史,支撑前端的“聊天记录”界面功能。\n\n【业务逻辑】\n- **列表**: 提供一个 `GET /api/chats` 接口,按时间倒序返回所有对话的元数据列表,用于在聊天记录库中展示。\n- **详情**: 提供一个 `GET /api/chats/[id]` 接口,返回特定对话的元数据及其包含的所有消息(及完整的“响应块”),用于恢复和展示一场完整的历史对话。\n- **删除**: 提供一个 `DELETE /api/chats/[id]` 接口,在删除一场对话的元数据时,会一并删除该对话下的所有消息记录。\n【权衡】当前列表接口不包含分页功能,如果用户有大量历史对话,一次性加载所有对话可能会导致性能问题。
  • 重试与幂等性处理 — 【设计策略】为应对网络不稳定等异常情况,消息创建过程被设计为幂等的,即重复提交相同的请求不会产生副作用。\n\n【业务逻辑】\n- Step 1: 客户端在每次发送消息时,会生成一个唯一的消息ID。\n- Step 2: 服务器在收到请求后,会先根据(对话ID, 消息ID)检查该消息是否已存在。\n- Step 3: 如果消息已存在(例如,因客户端超时重试),服务器不会创建新记录,而是会重置该消息的状态为“正在应答”,并清理掉可能存在的旧的、不完整的响应数据,然后继续处理。\n- Step 4: 如果消息不存在,则正常创建新记录。这一机制确保了即使在网络不佳的情况下,也不会产生重复的消息记录。

实时流式前端

这是用户与 Perplexica 交互的主界面,基于 React/Next.js 构建。其核心特性是能够实时、增量地展示 AI 的“思考过程”。通过与后端建立长连接,前端可以接收并渲染一系列事件,如研究步骤的更新、小组件的出现、以及最终答案的逐字生成,为用户提供了极具动态感和透明度的交互体验。

  • 基于事件的流式通信 — 【设计策略】采用服务器发送事件(Server-Sent Events, SSE)技术,在客户端和服务器之间建立一个单向的长连接,以实现高效的实时数据推送。\n\n【业务逻辑】\n- Step 1: 当用户发送消息后,前端会向 `/api/chat` 接口发起请求,该请求的响应是一个 `text/event-stream` 类型的流。\n- Step 2: 服务器在处理请求的过程中,会不断向这个流中写入 JSON 格式的事件对象,每个事件由换行符分隔。\n- Step 3: 事件类型包括:创建新界面块(`block`)、更新现有块(`updateBlock`)、研究完成(`researchComplete`)、消息结束(`messageEnd`)和错误(`error`)。\n- Step 4: 前端持续监听这个流,每当接收到一个完整的事件 JSON,就立即解析并更新界面状态。
  • 增量界面更新(JSON Patch) — 【用户价值】在展示流式生成的长文本时,避免了每次都传输全部内容的浪费,极大地提升了效率和响应速度。\n\n【设计策略】对于更新操作,服务器不发送完整的界面块数据,而是发送一个描述“如何从旧状态变为新状态”的指令集(JSON Patch)。\n\n【业务逻辑】\n- Step 1: 当 AI 的答案逐字生成时,服务器会为第一个字词创建一个新的“文本块”并发送给前端。\n- Step 2: 对于后续生成的每个字词,服务器不再发送完整的文本内容,而是生成一个遵循 RFC6902 标准的 JSON Patch 对象。例如:`{ "op": "replace", "path": "/data", "value": "更新后的完整文本" }`。\n- Step 3: 服务器将这个极小的 Patch 对象作为 `updateBlock` 事件发送给前端。\n- Step 4: 前端接收到该事件后,使用一个专门的库将这个 Patch 应用到本地存储的“文本块”对象上,从而实现对界面文本的增量更新。这个机制同样适用于更新研究步骤等复杂结构。
  • 会话重连与事件重放 — 【设计策略】为应对网络波动导致的连接中断,系统提供了一套会话重连和事件重放机制,确保用户不会丢失正在进行的流式响应。\n\n【业务逻辑】\n- Step 1: 服务器为每个正在进行的问答会话维护一个临时的、有时效性(30分钟)的事件缓冲区,记录下所有已发送给客户端的事件。\n- Step 2: 如果客户端因网络问题断开连接,它可以向 `/api/reconnect/[session_id]` 接口发起请求,尝试重连。\n- Step 3: 服务器收到重连请求后,会找到对应的会话。首先,它会将缓冲区中记录的所有历史事件一次性地“重放”给客户端,使其恢复到断连前的状态。\n- Step 4: 重放完成后,再继续实时推送新的事件,从而实现无缝的流式体验续接。\n【权衡】会话状态完全存储在服务器内存中,无法在多个服务器实例间共享。这要求在多节点部署时必须使用“粘性会话”(Sticky Session)来确保用户的重连请求能命中同一个服务器实例。

Core Technical Capabilities

实时增量界面更新架构

Problem: 如何在不重复发送大量数据的前提下,实时、流畅地向用户展示一个复杂的多阶段 AI 响应过程(包含研究步骤、小组件、流式文本等)?如果每次状态变更都发送完整数据,将导致网络拥堵和前端卡顿。

Solution: Step 1: 后端为每个问答会话维护一个内存中的UI“块”状态,并通过服务器发送事件(SSE)与前端建立一个持久的单向连接。\nStep 2: 当一个全新的UI块(如一个天气小组件)生成时,后端通过SSE发送一个“创建块”事件,其中包含该块的完整数据。\nStep 3: 当一个已有的块需要更新时(如流式答案中新增一个字),后端会计算新旧状态的差异,并生成一个标准的JSON Patch指令。\nStep 4: 后端仅将这个体积微小的Patch指令作为“更新块”事件发送给前端。前端接收后,在本地应用此Patch,从而增量更新UI。\n这个方案的核心价值在于将全量更新变为增量更新,大幅减少了网络传输量,实现了高效、低延迟的实时交互体验。

Technologies: Server-Sent Events (SSE), JSON Patch (RFC6902), ReadableStream

Boundaries & Risks: 该方案下的会话状态完全存储在服务器的内存中,且没有跨节点同步机制。这使得它在多服务器实例部署时,必须依赖负载均衡的“粘性会话”策略,否则用户的请求可能会路由到没有其会话数据的实例上,导致连接失败。同时,内存中的会话有30分钟的过期时间,可能无法支撑超过此时长的超长研究任务。

可插拔的多供应商模型架构

Problem: 如何让一个自托管应用能够灵活地接入不同来源、不同成本的大语言模型(本地、闭源API、开源模型等),以适应不同的硬件和预算限制?硬编码特定供应商会使系统僵化且难以扩展。

Solution: Step 1: 定义一个统一的“模型供应商”抽象基类,规范了所有供应商必须实现的核心方法,如获取模型列表、加载聊天模型、加载嵌入模型等。\nStep 2: 为每个具体的服务商(如OpenAI、Ollama、Groq)创建一个实现该基类的子类,将各自独特的API调用逻辑封装在内部。\nStep 3: 创建一个“模型注册表”作为中心协调者。它在应用启动时,根据用户的配置文件,动态地实例化所需的供应商子类。\nStep 4: 当应用需要使用模型时,它不直接与任何具体供应商交互,而是向“模型注册表”请求一个模型实例。注册表会根据当前配置,返回一个符合统一接口的模型对象。\n这一设计模式(通常称为策略模式或工厂模式)实现了模型使用的“控制反转”,使得添加或切换模型供应商无需修改核心代码,只需增加一个新的子类实现,具有极高的扩展性和灵活性。

Technologies: 抽象基类, 工厂模式, 依赖注入

Boundaries & Risks: 虽然架构上支持热插拔,但所有供应商配置(包括API密钥)都以明文形式存储在本地JSON文件中,存在安全风险。此外,系统在更新供应商配置时,内存中的实例管理存在缺陷,可能导致旧的配置实例未被完全清理,存在潜在的内存泄漏和配置不一致问题。

基于工具调用的迭代式研究循环

Problem: 如何让AI像人类研究员一样,能够根据问题制定计划、选择工具、迭代搜集信息,并最终在信息充足时停止?传统的单次搜索无法应对复杂问题的研究需求。

Solution: Step 1: 将信息搜集能力(如网页搜索、学术搜索)封装成独立的、可被大模型调用的“工具”。\nStep 2: 构建一个研究循环,循环的次数上限由用户选择的模式(速度/均衡/质量)决定。\nStep 3: 在每次循环中,系统向大模型发起请求,并提供可用的工具列表。模型根据当前研究进展和目标,决定调用一个或多个工具。\nStep 4: 系统执行模型指定的工具调用,并将结果返回给模型,作为下一次循环的输入。\nStep 5: 模型被赋予一个特殊的“完成”工具。当模型判断已收集到足够信息时,它会主动调用“完成”工具来终止研究循环。如果达到最大迭代次数,循环也会强制结束。\n这种机制赋予了AI规划和自主决策的能力,使其能够动态调整研究深度和广度,以适应不同问题的复杂性。

Technologies: LLM Tool Calling, 有限状态机, 异步流程控制

Boundaries & Risks: 该循环的效率和效果高度依赖于大模型的工具调用能力和“何时完成”的判断力。如果模型决策不佳,可能导致研究不充分或执行不必要的操作,从而影响答案质量和成本。循环的终止条件较为简单,缺乏更复杂的启发式规则。

基于文件系统的本地化 RAG 解决方案

Problem: 如何在不依赖外部向量数据库或付费服务的情况下,为用户提供一个功能完整的、基于私有文档的问答(RAG)能力?

Solution: Step 1: 文档上传后,系统在服务器本地文件系统上为每个文件创建一个文件夹,并将原始文件存入。\nStep 2: 系统提取文件文本,进行分块和向量化后,将文本块和对应的向量一起存储在一个与原始文件配对的 `.content.json` 文件中。\nStep 3: 所有的文件元数据被记录在另一个顶级的 `uploaded_files.json` 文件中,作为文件索引。\nStep 4: 当需要进行语义检索时,系统直接从文件系统中读取相应的 `.content.json` 文件,将所有文本块及其向量加载到内存中。\nStep 5: 在内存中完成用户查询向量与所有文本块向量的相似度计算,并返回最相关的结果。\n该方案用本地文件系统模拟了向量数据库的核心功能,为自托管应用提供了一个零依赖、零成本的RAG实现,完美契合了项目的隐私和易部署特性。

Technologies: 文本分块算法, 向量嵌入, 本地文件存储 (JSON), 余弦相似度计算

Boundaries & Risks: 所有向量和文本块在查询时都会被加载到内存中,对于拥有大量或非常大的文档的用户,可能会导致显著的内存占用和性能瓶颈。该方案不适合需要管理海量文档的企业级场景。同时,文件存储没有用户隔离,在多租户环境下存在数据泄露风险。

Related Projects

Discover more public DeepDive reports to compare architecture decisions.

  • zyphra/zonosbc40d98e1e1a - zh-CN
  • tobi/qmd63028fd5e905 - zh-CN
  • thedotmack/claude-memb2ddf59db46c - zh-CN
  • microsoft/VibeVoicece3d40c78f3c - zh-CN
  • maxbittker/sandspieldc77827b36ad - zh-CN
  • lfnovo/open-notebookeae429b3bd2c - zh-CN
Browse all public DeepDive reports