
Local Deep Research v1.0 迁移指南用户认证、SQLCipher 加密数据库与 FastAPI 部署契约变更【免费下载链接】local-deep-research~95% on SimpleQA (e.g. Qwen3.6-27B on a 3090). Supports all local and cloud LLMs (llama.cpp, Ollama, Google, ...). 10 search engines - arXiv, PubMed, your private documents. Everything Local Encrypted.项目地址: https://gitcode.com/GitHub_Trending/lo/local-deep-researchLocal Deep ResearchLDRv1.0 是一次以安全为驱动的架构级升级引入强制用户认证、每用户独立的 SQLCipher 加密数据库、线程安全的设置快照Settings Snapshot以及重组后的 API 路由结构。本文完整覆盖从 v0.x 到 v1.0 的全部破坏性变更与迁移步骤并基于当前仓库源码逐条印证新认证会话、CSRF 防护、默认绑定地址与 WebSocket 路径等关键契约的实现位置帮助你在升级服务器、改写程序化调用和 HTTP 客户端时不遗漏任何细节。v1.0 的核心改进概览官方迁移指南docs/MIGRATION_GUIDE_v1.md将 v1.0 的改进归纳为四点迁移工作全部围绕它们展开用户认证User Authentication所有访问现在都要求认证v0.x 的匿名开放访问不复存在每用户加密数据库Per-User Encrypted Databases每个用户拥有独立的 SQLCipher 加密数据库设置快照Settings Snapshots面向并发场景的线程安全设置管理新 API 结构New API Structure端点按路由前缀重新组织。破坏性变更一认证成为强制要求v0.x直接调用无认证# Direct API access from local_deep_research.api import quick_summary result quick_summary(query)v1.0必须先建立认证数据库会话from local_deep_research.api import quick_summary from local_deep_research.settings import SettingsManager from local_deep_research.database.session_context import get_user_db_session # Must authenticate first with get_user_db_session(usernameuser, passwordpass) as session: settings_manager SettingsManager(session) settings_snapshot settings_manager.get_all_settings() result quick_summary( query, settings_snapshotsettings_snapshot # Required parameter )从源码看get_user_db_session定义在 src/local_deep_research/database/session_context.py其密码解析有一条明确的回退链优先使用调用方显式传入的password程序化调用场景若未提供password但提供了session_id则从会话密码存储session_password_store.get_session_password(username, session_id)中按精确会话查找避免同一用户的两个并发会话互相串用密码再退化为扫描该用户的任意活跃会话适合后台线程但请求处理器应显式传session_id再退化为线程上下文中的user_password若数据库启用加密db_manager.has_encryption而仍拿不到密码抛出DatabaseSessionError(Encrypted database for {username} requires password)见 session_context.py#L157-L160——这正是下文常见问题中 Encrypted database requires password 报错的出处。另外两点值得注意会话是线程本地复用的上下文管理器退出时并不关闭连接实际关闭发生在cleanup_current_thread()由中间件/工作循环的 finally 块调用异常安全回滚with块内抛出的异常尤其是commit()/flush()失败会触发safe_rollback()避免把处于PendingRollbackError状态的脏会话遗留给同一线程的下一个调用者。破坏性变更二HTTP API 结构与认证流程端点结构变化v0.x/api/v1/quick_summaryv1.0/api/start_research旧的/api/v1/*路径不再可用调用旧端点会返回 404需要按新端点结构改写。基于会话的认证与 CSRF 流程import requests # v1.0 requires session-based authentication session requests.Session() # 1. Login session.post( http://localhost:5000/auth/login, json{username: user, password: pass} ) # 2. Get CSRF token for state-changing operations csrf session.get(http://localhost:5000/auth/csrf-token).json()[csrf_token] # 3. Make API requests with CSRF token response session.post( http://localhost:5000/api/start_research, json{query: test}, headers{X-CSRF-Token: csrf} )要点会话 Cookie 完成身份认证后所有变更状态state-changing的请求还必须携带X-CSRF-Token头Token 需通过GET /auth/csrf-token获取。FastAPI 版的破坏性变更说明 changelog.d/3299.breaking.md 进一步确认会话认证的POST /api/v1/*客户端若缺失或携带无效 CSRF Token将收到 403。CSRF 依赖逻辑位于 src/local_deep_research/web/dependencies/csrf.py。破坏性变更三数据库从共享明文到每用户加密维度v0.xv1.0数据库文件单一共享库ldr.db每用户独立库encrypted_databases/{username}.db加密无使用用户密码做 SQLCipher 加密访问模型任意线程直接访问线程本地thread-local会话管理队列跟踪依赖service_db内存队列跟踪不再需要service_db这意味着升级后不存在“直接把旧ldr.db挂上去用”的路径数据按用户隔离存储且必须凭认证会话才能打开。加密数据库的实现位于 src/local_deep_research/database/encrypted_db.py 与 src/local_deep_research/database/thread_local_session.py若环境中确实设置了LDR_ALLOW_UNENCRYPTEDtrue会话层会改用占位密码unencrypted-mode并打印警告见 session_context.py#L18-L20 与 session_context.py#L161-L166。破坏性变更四设置管理需要上下文v0.x全局直接读取# Direct settings access from local_deep_research.config import get_db_setting value get_db_setting(llm.provider)v1.0SettingsManager 快照# Settings require context from local_deep_research.settings import SettingsManager # Within authenticated session settings_manager SettingsManager(session) value settings_manager.get_setting(llm.provider) # Or use settings snapshot for thread safety settings_snapshot settings_manager.get_all_settings()源码层面src/local_deep_research/settings/manager.py有几个与迁移强相关的行为线程绑定检查SettingsManager记录创建时的线程 ID若在另一线程上被使用会直接抛RuntimeError见 manager.py#L575-L583。这就是为什么跨线程传递“设置快照”比传递 manager 实例更安全键值模型get_setting(llm.provider)支持精确键与命名空间前缀两种形态前缀读取会返回该命名空间下的映射字典环境变量覆盖优先级最高设置键llm.provider会被映射为环境变量LDR_LLM_PROVIDER检查check_env_setting的LDR_{_.join(key.split(.)).upper()}规则见 manager.py#L419-L458环境值优先于数据库值空字符串按“未设置”处理快照可在派发时重新应用环境覆盖apply_environment_overrides_to_snapshot()会在任务实际派发时重新注入当前LDR_*覆盖值保证排队的研究任务使用操作者最新策略见 manager.py#L461-L503。迁移步骤第 1 步升级依赖pip install --upgrade local-deep-research第 2 步创建用户账户用户必须通过 Web 界面创建账户启动服务器python -m local_deep_research.web.app打开 http://localhost:5000点击 Register 创建账户在 Settings 中配置 LLM 提供商与 API Keys第 3 步改写程序化调用代码迁移前v0.xfrom local_deep_research.api import ( quick_summary, detailed_research, generate_report ) # Direct usage result quick_summary(What is AI?)迁移后v1.0from local_deep_research.api import quick_summary from local_deep_research.settings import SettingsManager from local_deep_research.database.session_context import get_user_db_session def run_research(username, password, query): with get_user_db_session(username, password) as session: settings_manager SettingsManager(session) settings_snapshot settings_manager.get_all_settings() return quick_summary( queryquery, settings_snapshotsettings_snapshot, # Other parameters remain the same iterations2, questions_per_iteration3 )除新增的认证会话与settings_snapshot参数外其余参数如iterations、questions_per_iteration保持不变。API 层的函数实现位于 src/local_deep_research/api/research_functions.py可直接对照签名核对参数。第 4 步改写 HTTP API 调用建议为认证请求封装一个客户端类class LDRClient: def __init__(self, base_urlhttp://localhost:5000): self.base_url base_url self.session requests.Session() self.csrf_token None def login(self, username, password): response self.session.post( f{self.base_url}/auth/login, json{username: username, password: password} ) if response.status_code 200: self.csrf_token self.session.get( f{self.base_url}/auth/csrf-token ).json()[csrf_token] return response def start_research(self, query, **kwargs): return self.session.post( f{self.base_url}/api/start_research, json{query: query, **kwargs}, headers{X-CSRF-Token: self.csrf_token} ) # Usage client LDRClient() client.login(user, pass) result client.start_research(What is quantum computing?)第 5 步更新配置API KeysAPI 密钥现在加密存储于每用户数据库中。用户需要登录 Web 界面进入 Settings为各 LLM 提供商重新录入 API Key。自定义 LLM自定义 LLM 的注册现在需要设置上下文可从快照中读取配置# v1.0 custom LLM with settings support def create_custom_llm(model_nameNone, temperatureNone, settings_snapshotNone): # Access settings from snapshot if needed api_key settings_snapshot.get(llm.custom.api_key, {}).get(value) return CustomLLM(api_keyapi_key, modelmodel_name, temperaturetemperature)常见问题与解决方案问题解决方案No settings context available in thread为所有 API 调用显式传递settings_snapshot参数Encrypted database requires password确保使用get_user_db_session()并传入凭据报错源头见 session_context.py#L157-L160CSRF Token 错误在发起状态变更请求前获取新的 CSRF Token旧端点返回 404按上文端点映射更新到新 API 结构速率限制不生效限流现在是按用户计的先确认认证正常向后兼容模式不推荐用于生产如果短期内无法完成改造可以启用临时兼容开关设置环境变量LDR_USE_SHARED_DB1官方明确标注 not recommended为既有代码创建兼容包装器# compatibility.py import os os.environ[LDR_USE_SHARED_DB] 1 # Use at your own risk def quick_summary_compat(query, **kwargs): # Minimal compatibility wrapper # Note: This bypasses security features! from local_deep_research.api import quick_summary return quick_summary(query, settings_snapshot{}, **kwargs)警告兼容模式会绕过 v1.0 的安全特性认证、加密、按用户隔离仅适合过渡期不建议用于生产环境。v1.0 带来的收益安全性加密数据库保护敏感 API Key 与研究数据多用户多个用户可同时工作而互不冲突性能设置缓存与线程本地会话降低开销可靠性线程安全操作避免竞态条件隐私用户数据完全隔离。升级到基于 FastAPI 的发布Phase 1在上述 v1.0 认证/数据库改造之外服务器框架已从 Flask Werkzeug 迁移到FastAPI uvicorn。对交互式用户影响最大的变更如下完整清单见 changelog.d/3299.breaking.md其中同时包含回滚流程。请注意其中多项是永久性契约变更而非一次性升级影响。升级后需要重新登录Flask 与 StarletteFastAPI 的会话中间件使用不同的 itsdangerous 方案签名会话 Cookie浏览器中由 Flask 版本持有的会话 Cookie 新服务器无法读取。首次访问会被重定向到登录页并需要重新输入密码——只影响浏览器会话不影响数据。此外与任何 LDR 重启一样内存中的会话存储会被清空且若 LDR 无法读取或创建持久化会话密钥文件启动会直接失败需先修复数据目录权限或密钥文件内容。默认绑定地址改为 127.0.0.1Flask 时代的发布默认绑定0.0.0.0所有网卡会把服务器悄悄暴露到局域网甚至公网新默认值是127.0.0.1仅本机。如确需对其它机器开放例如自建家庭服务器必须显式设置环境变量LDR_WEB_HOST0.0.0.0。该变量在 src/local_deep_research/web/server_config.py#L24 中注册为web.host的对应环境变量。Docker 用户不受影响Dockerfile 已自动设置该变量容器端口映射照常工作。反向代理必须显式开启转发头信任当 TLS 在可信反向代理处终结时需设置TRUST_PROXY_HEADERStrue。否则 uvicorn 会把请求 scheme 视为 HTTP导致 secure-cookie、HSTS 与 WebSocket 同源行为全部出错。注意速率限制用的客户端 IP 提取遵循另一套信任规则直连 peer 是私网/回环地址即视为可信见 src/local_deep_research/web/dependencies/rate_limit.py因此代理必须覆盖而非追加X-Forwarded-For与X-Real-IP。该变量的解析位于 src/local_deep_research/web/app.py#L118-L122。完整代理配置示例见 docs/deployment/reverse-proxy.md。Socket.IO 端点迁移到 /ws/socket.ioSocket.IO 服务现在是一个挂载在/ws下的 ASGI 子应用src/local_deep_research/web/fastapi_app.py#L2358 中的app.mount(/ws, socket_app)实际服务路径为/ws/socket.iosrc/local_deep_research/web/services/socketio_asgi.py#L128-L129 中的socketio_path/ws/socket.io。内置 UI 已按path: /ws/socket.io连接如果你自写了 Socket.IO 客户端或反向代理里存在针对旧默认路径/socket.io的显式location规则必须同步更新参见 docs/deployment/reverse-proxy.md。WebSocket 跨源默认策略未变LDR_SECURITY_WEBSOCKET_ALLOWED_ORIGINS行为与之前完全一致未设置即仅允许同源same-origin only。仅当确需跨源 WS 访问少见时才显式配置。官方还特别澄清了一个历史误记早期文档曾声称该默认值从*“收紧”为同源这是错误的——旧版web/services/socket_service.py在变量未设置时本就回退到同源白名单。本次迁移只换了传输层transport源策略没有任何变化。Cookie SameSite 从 Lax 变为 Strict无配置项可恢复若你把 LDR 通过 iframe 嵌入其它工具、或依赖 OAuth 跨站重定向会话 Cookie 可能无法存活于跨站跳转LDR 自身不使用这两种模式。目前没有任何设置项或环境变量可恢复Lax——same_sitestrict硬编码在SessionMiddleware安装处src/local_deep_research/web/fastapi_app.py#L2195。如确有需要应向项目提交 issue不要期待配置项出现。优雅关闭超时上限为 10 秒硬编码uvicorn.run(timeout_graceful_shutdown10)见 src/local_deep_research/web/app.py#L146意味着服务器收到 SIGTERM/SIGINT 后进行中的 SSE 流最多再保留 10 秒即被关闭而不是无限阻塞等待。该值目前硬编码没有环境变量可延长排空窗口如有超长单请求场景需要调整请提交 issue。其他值得迁移方注意的契约变更以下内容同样记录在 changelog.d/3299.breaking.md 中若你的集成涉及相应端点需要一并处理速率限制存储优先使用RATE_LIMIT_STORAGE_URI旧名RATELIMIT_STORAGE_URL仍作为回退支持存量部署无需立即改配置重复的旧/api/news/*API 已移除迁移到/news/api/*契约并非机械前缀替换端点、请求字段与状态码均有变化详见 changelog 的逐条映射;上下文溢出端点迁移/metrics/api/context-overflow→/api/context-overflow/metrics/api/research/{id}/context-overflow→/api/research/{id}/context-overflowGET /news/health现在要求认证监控应改用公共的GET /api/v1/health存活端点含/的自定义设置键不再适用于单键设置 API内置设置不受影响。参考资料完整破坏性变更清单与回滚流程changelog.d/3299.breaking.mdAPI 快速上手docs/api-quickstart.md更新后的调用示例examples/api_usage/反向代理加固示例docs/deployment/reverse-proxy.md会话与密码解析源码src/local_deep_research/database/session_context.py设置管理源码src/local_deep_research/settings/manager.py。【免费下载链接】local-deep-research~95% on SimpleQA (e.g. Qwen3.6-27B on a 3090). Supports all local and cloud LLMs (llama.cpp, Ollama, Google, ...). 10 search engines - arXiv, PubMed, your private documents. Everything Local Encrypted.项目地址: https://gitcode.com/GitHub_Trending/lo/local-deep-research创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考