资讯动态

local-deep-research 1.7.0 发布解读:Chat 多轮研究模式、日志凭据防泄漏加固与推理模型输出治理

发布时间:2026/9/16 20:55:28 来源:尧图企业网站定制
local-deep-research 1.7.0 发布解读Chat 多轮研究模式、日志凭据防泄漏加固与推理模型输出治理【免费下载链接】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本篇技术指南基于local-deep-research仓库的 1.7.0 版本发布说明结合仓库源码逐项解读该版本的核心变更全新引入的 Chat 多轮对话式研究模式含可配置的追问上下文策略、流式引用渲染与大量正确性/无障碍修复、围绕 Logurudiagnose与redact_secrets展开的凭据防泄漏安全加固以及针对推理模型think标签的全局输出治理。读完本文你将能理解这些功能的配置入口、底层实现原理与适用边界并可直接在自托管部署中应用对应的安全配置建议。一、版本概览1.7.0 的三条主线从发布说明的整体结构看1.7.0 的改动可以归纳为三条主线安全加固Security将redact_secrets()凭据脱敏覆盖到所有携带凭据的异常日志调用点并把 Loguru 的diagnoseTrue局部变量转储从LDR_APP_DEBUG中剥离出来改为独立的显式开关LDR_LOGURU_DIAGNOSE。新功能New Features正式引入Chat Mode交互式多轮研究会话支持上下文累积、流式进度与引用、会话归档/恢复/删除/Markdown 导出以及四种可配置的追问上下文模式。缺陷修复Bug Fixes覆盖 Chat Mode 的流式引用、数据完整性、可访问性、资源边界以及非 Chat 研究路径上的队列调度、报告组装、引用格式等一批问题。下文将按照「先安全、再功能、后修复」的顺序展开并在每个小节补充对应源码证据。二、安全加固让凭据不再泄漏进日志2.1 背景Loguru 的diagnoseTrue默认行为Loguru 在记录异常时默认开启diagnoseTrue这意味着当logger.exception(...)触发时每个 traceback 帧中所有局部变量的repr()都会被渲染进日志。在一个承载 LLM 密钥、Authorization头、SQLCipher 主密码的深度研究应用中这等于把最敏感的内容原样写进每一个日志 sink。发布说明明确指出此前开启LDR_APP_DEBUG做常规调试的同时也会把diagnose一起打开任何一次异常都可能让 API Key、SQLCipher 主密码、Authorization头落入日志。2.2 双环境变量分离LDR_APP_DEBUG只管日志级别1.7.0 将两者解耦LDR_APP_DEBUG现在仅提升日志级别到 DEBUG不再附带局部变量转储LDR_LOGURU_DIAGNOSEtrue需要显式设置才能开启 Loguru 的diagnose局部变量渲染且开启时会打印显式警告。对应源码在 secure_logging.pydef is_diagnose_mode() - bool: Return True when the operator explicitly opted into traceback output. return env_truthy(LDR_APP_DEBUG) and env_truthy(LDR_LOGURU_DIAGNOSE)注意is_diagnose_mode()要求两个变量同时为真才开启诊断模式。同时SecureLogger代理把exception()重写为logger.opt(exceptionis_diagnose_mode(), depth1).error(...)见 secure_logging.py在正常运维下异常事件仍以 ERROR 级别落日志但记录中不携带异常对象——任何 sink 都无法渲染 traceback而消息文本本身仍会进入所有 sink。因此调用点仍需自行脱敏消息文本这正是scrub_error的职责。配置文档 CONFIGURATION.md 中的app.debug/LDR_APP_DEBUG条目已同步更新说明仅提升日志级别、不单独启用 Loguru 局部变量转储。2.3redact_secrets()覆盖面扩展发布说明称redact_secrets()的覆盖范围从 Google provider 扩展到了所有携带凭据的异常日志调用点包括OpenAI-compatible provider 基类的list_models自定义 OpenAI endpoint provider、OpenAI embedding providerWeb 搜索引擎子系统BaseSearchEngine.run()以及 Tavily、Exa、Serper、Google PSE、Mojeek、PubMed、Semantic Scholar、Guardian、ScaleSerp、SerpAPI、GitHub 等引擎的主 HTTP 调用错误路径本版本还补上了遗漏的 NASA ADS 引擎其_get_previews原本使用logger.exception在 loguru diagnose 模式下会渲染持有Authorization: Bearer key的self.headers现已改用带脱敏的logger.warning。脱敏机制本身采用「双重擦除dual-scrub」模式核心实现在 log_sanitizer.pysanitize_error_message()按凭据形态做正则脱敏覆盖Bearer令牌、带/不带 scheme 的Authorization头、x-api-key头、URL 内嵌凭据user:passhost包括postgresql://、redis://等 DSN、URL 查询参数?api_key、?access_token等、以及sk-/pk-、GoogleAIza/ya29.、GitHubghp_/github_pat_、AWSAKIA/ASIA、Slackxox*/xapp、JWTeyJ…等已知令牌前缀redact_secrets()按调用方提供的已知字面量做str.replace多个密钥按长度降序处理避免短密钥吞掉长密钥的子串默认最小脱敏长度 8 字符、替换标记为***REDACTED***scrub_error()把两者组合成一个 catch 块内可直接调用的防御性函数——它在except中运行、保证永不抛异常str(error)与每个 secret 的str()转换都做了保护。BaseSearchEngine通过_secret_attrs声明每个引擎自己的敏感属性默认即(api_key,)见 search_engine_base.py_scrub_error委托给scrub_error把引擎的密钥解析进secrets参数。Guardian 与 ScaleSerp 则在此基础上叠加了各自已有的正则清洗器形成纵深防御。2.4 MCP 子进程与 Benchmark CLI 的diagnoseFalse锁定diagnose默认开的问题不只存在于 Web/CLI 日志器MCP 子进程ldr-mcpstderr sink 固定diagnoseFalse。MCP 请求处理器里有大量logger.exception(...)路径此前失败时会把api_key、Authorization头、搜索引擎密钥写进 MCP 客户端的 stderr 日志。MCP 子进程没有 debug 模式因此该开关被无条件关闭。Benchmark CLIldr-benchmark/ benchmark_commands.py两处logger.add(sys.stderr, ...)均固定diagnoseFalse。benchmark 包中的 LLM 评分调用、搜索引擎 runner、数据集加载器同样存在凭据泄漏面且该 CLI 绕过config_logger环境变量门控覆盖不到它。示例脚本examples/example_browsecomp.py与三个api_usage/programmatic/片段同样传入diagnoseFalse。这些文件是用户复制进自己脚本的模板此前默认行为会把凭据泄漏传播到任何下游代码。配套地测试夹具与开发脚本tests/conftest.py的 loguru-caplog fixture、tests/api_tests/的__main__runner、tests/test_openai_api_key_e2e.py等也已统一传入diagnoseFalse保证 pytest 崩溃时帧内凭据不会进入 CI 日志。2.5 会话 API 的限流补齐Chat 的PATCH重命名/归档与DELETE会话路由现在与其它变更状态的 Chat 端点一样带有每用户限流此前它们只受全局限流器约束导致会话 API 上存在不均衡的滥用面。2.6 运维建议生产环境保持LDR_LOGURU_DIAGNOSE未设置或设为非真值LDR_APP_DEBUG仅在需要更详细日志级别时开启只有排查疑难 traceback 时才临时同时设置LDR_APP_DEBUGtrue与LDR_LOGURU_DIAGNOSEtrue排查完立即移除若自己编写调用搜索引擎/LLM provider 的脚本复制examples/模板时应保留diagnoseFalse不要绕过secure_logging.logger直接使用 loguru 的logger.exception()除非确认消息已通过scrub_error脱敏。三、新功能Chat Mode 多轮研究会话3.1 功能总览Chat Mode 是 1.7.0 的重头戏对应 PR #2953在 features.md 的 Chat Mode 章节 中被标记为Experimental。它提供交互式多轮研究对话会话跨轮次累积上下文实体、主题、来源数量答案构建过程中实时流式输出研究步骤与引用会话持久化到每用户数据库默认加密跨登出保留会话生命周期归档、重新激活、永久删除可选 LLM 生成的会话标题chat.llm_title_generation开关会话可导出为 Markdown始终使用 quick 研究模式v1每个会话同一时间一个进行中的研究。入口为侧边栏Chat链接或/chat/路由页面模板在 chat.html路由实现在 web/routers/chat.py。3.2 追问上下文模式chat.followup_context_mode追问问题不再从零开始。默认情况下之前的对话会被浓缩成一个聚焦于你新问题的短摘要使用你配置的 LLM作为该次追问研究的previous findings传入使多轮研究保持在主题内并受控于上下文长度。四种模式定义在 default_settings.json 的chat.followup_context_mode项模式行为额外 LLM 成本summary默认针对新问题对整段对话做 LLM 摘要每次追问多一次 LLM 调用raw最近的研究发现截断后使用无full整个对话原文无none无先前上下文仅新问题 原始主题无选择逻辑实现在 chat/context.pyChatContextManager读取快照中的chat.followup_context_mode缺省用DEFAULT_FOLLOWUP_CONTEXT_MODE summarynone直接返回空、raw取最近发现截断、full取完整记录而summary模式在无问题时会回退到 raw 最近发现。该模块还会记录本次追问运行了哪种模式、构建了多少字符上下文解决此前上下文构建尤其 LLM 摘要零日志输出、看起来像莫名停顿的问题。3.3 流式体验引用即时渲染、思考气泡与停止计数流式内联引用每个发送给客户端的 chunk 都会经过与最终答案相同的引用格式化器并带一个小 carry buffer 暂存跨 chunk 边界的不完整[N标记直到闭合]到达。因此用户能看到[[arxiv.org-1]](url)或report.citation_format设置的其它格式实时出现保存时不会出现格式翻转。服务端 partial-content buffer 仍存原始 chunk中途终止时恢复保存不会被重复格式化。思考指示器追问时显示 Summarizing previous conversation…研究开始时显示 agent 在工具调用间隙的中间推理文本如 I should compare the published benchmark results next…随每一步更新。停止计数点击 Stop 后若工作线程阻塞在 LLM HTTP 调用中Qwen 3、DeepSeek-R1 等思考型模型在think块内不产出 chunk可能 30 秒以上才出现停止检查点进度任务行会显示 Stopping research… (Ns) 秒数。该计数在 3 秒后才出现研究停止/完成/出错时自动清除。这是 UX 层面的缓解彻底降低终止延迟需要 per-token 流式或基于信号的 HTTP 中断等更深的改造。友好化里程碑文案Tool: search_pubmed — covid变为 Searching PubMed: covidTool: fetch_url — https://…变为 Reading the page: https://…工具结果显示为 From {engine}: …。没有显式显示名的引擎回退为清洗后的Title Case形式新增搜索引擎无需改代码即可适配。子主题研究里程碑会拾取工具的subtopics: list[str]参数并字符串化显示 Investigating subtopic: topic1, topic2而不是空引号。3.4 引用格式在 Chat 中的落地Chat 模式答案走apply_inline_hyperlinks回退路径langgraph-agent 综合文本不产出## Sources块此前硬编码NUMBER_HYPERLINKS导致所有 Chat 答案都输出[[1]](url)。1.7.0 改为按CitationFormatter.mode分发见 citation_formatter.py 的CitationMode枚举report.citation_format设置的格式现在对 Chat 引用真正生效number_hyperlinks— 数字超链接[1]domain_hyperlinks— 域名超链接[arxiv.org]domain_id_hyperlinks— 智能编号[arxiv.org]或[arxiv.org-1]domain_id_always_hyperlinks— 一致编号[arxiv.org-1]source_tagged_hyperlinks— 源标签 全局引用编号保留如[arxiv-1]、[openai.com-2]、[arxiv-3]apply_inline_hyperlinks现在还接受url或link作为来源字典的目标键——SearXNG 来源把目标放在link下search_engine_searxng.py此前回退超链接路径会静默丢弃它导致答案下方 Sources 区已完整填充而正文引用只是不可点击的[N]。四、Bug Fixes一次全面扫尾4.1 推理模型输出治理think块不再泄漏流式引用路径base_citation_handler._invoke_with_streaming现在把拼接的 chunk 先经get_llm_response_text再返回——.stream()绕过了ProcessingLLMWrapper.invoke唯一剥离标签的位置修复后流式结果与非流式invoke()契约一致think…/think不再进入持久化的 Chat 答案。主综合路径synthesize_findings与标准 knowledge generator也剥离think不再只由引用处理器兜底同时修复精确/强制答案提取器在模型返回空或仅 think响应时多出一个. content的问题。中央 LLM 包装器将字符串返回型 provider 归一化为 message 对象并对异步ainvoke也应用think剥离消除str object has no attribute content崩溃。Message 对象的tool_calls/reasoning_content保留仅重写.content。已知局限已在代码内注明LangGraphcreate_agent/bind_toolslanggraph-agent与mcp策略通过ProcessingLLMWrapper.__getattr__解析到基础 LLM绕过think剥离这是外观性泄漏推理模型标签可能出现在 agent 输出中不影响直接invoke()调用。4.2 Chat 会话的数据完整性与资源边界消息排序尊重同毫秒行的sequence_numberLoad older 游标改用复合(created_at, id)键边界行不再被静默丢弃Markdown 导出翻页遍历完整对话此前截断为 50 条部分保存的幂等标记仅在数据库写入成功后才设置瞬时失败不再永久丢失 assistant 响应。send_message现在先解析数字型搜索设置search.iterations、search.questions_per_iteration再执行写入用户消息 IN_PROGRESS 研究行的原子写——畸形值返回干净的 400而不是行已提交后的未处理 500此前会留下孤儿行并通过 per-session 409 守卫使会话不可用。内联引用 carry buffer 上限 64 字节客户端streamedContent累加器上限 256 KB镜像服务端_MAX_PARTIAL_BUFFER_BYTES并附带一次性 (Response truncated — exceeded display limit.) 提示防止无max_tokens的模型撑爆浏览器标签页。标题校验剥离 Unicode 格式/行分隔符字符Cf/Zl/Zp包括零宽空格U200B-U200D与 BOMUFEFFregenerate_title_with_llm幂等标题已不再是回退值则跳过 LLM 调用并剥离 LLM 返回标题中的\n/\r避免伪造日志聚合器中的第二条记录。ChatService.delete_session仅在删除提交之后设置内存终止标志失败的提交不能再杀掉仍存在会话的在途研究。直接模式容量拒绝路径processor_v2._start_research_directly现在为重新排队的研究递增QueueStatus.queued_tasks此前计数保持 0队列处理器会误判队列为空。4.3 会话 API 与队列调度Chat 触发的研究会插入UserActiveResearch行计入每用户app.max_concurrent_researches上限此前 Chat 研究对该上限不可见可被多个标签页绕过该行与研究行原子提交spawn 失败时清理正常完成由现有完成清扫中间件移除。队列调度器processor_v2._start_queued_researches新增专门except SystemAtCapacityError瞬时容量拒绝保持 QUEUED 等待下一轮而不是计入SPAWN_RETRY_LIMIT并在负载下被误标 FAILED。update_task_status支持processing→queued计数还原转换容量拒绝路径使用它修复全局容量拒绝重排队时active_tasks槽位泄漏、queued_tasks漂移到 0 导致队列停摆的问题。cleanup_research_resources报告调用方传入的真实终态用户终止为 SUSPENDED、出错为 FAILED不再硬编码COMPLETED——停止研究不再发出虚假的 completed socket 信号此前产生多余的 [Stopped] 气泡与误导性的 100%/Completed 翻转。4.4 引用格式化与报告组装apply_inline_hyperlinks按CitationFormatter.mode分发前述。报告结构解析修复无句点的编号章节行如1 Introduction不再IndexError崩溃含句点的章节名如1. U.S. Policy不再被截断成U——章节号只按第一个句点拆分并对畸形行有保护。format_links_to_markdownsearch_utilities.py在sorted()前把引用索引强制转为str——不同策略产出的intrecursive_decomposition_strategy.py与str_build_sources_markdown回退混合不再触发TypeError: not supported between instances of str and int排序仍保持数字序。assemble_full_report不再用 blanketexcept包住_build_sources_markdown——错误传播到调用方既有 500 路径而不是渲染一份看似完整实则静默缺失全部 Sources 的报告。GET /api/report/id的sources字段改从结构化research_resources表读取原先读的是 chat-mode-v2 重构后从未写入的死元数据键all_links_of_system。GitHub 搜索相关性排序拒绝负数、越界、非整数结果索引并去重畸形 LLM 响应不能再选中错误结果、重复列出同一仓库或丢弃全部结果。4.5 非 Chat 路径修复新闻订阅Run now或逾期订阅检查运行新闻订阅时不再在订阅无显式模型时强制 LLM 为ollama/llama3。此前news/flask_api.py硬编码这些值真值覆盖了用户配置的llm.provider/llm.model未配置模型的订阅会被静默切到 Ollama 运行且通常失败现在未设置模型以None传递start_research回退到用户设置。资源泄漏Ollama embeddings 工厂加weakref.finalize安全网直接构造OllamaEmbeddings的程序化调用方在实例被 GC 时释放底层 httpx 客户端见 ollama.pyLibrary RAG 服务在每个HTTP 请求结束时关闭包括流式端点与 embedding-manager 关闭路径一起阻止文件描述符累积。WebSocket 订阅所有权_user_owns_research现在同时接受 Benchmark 运行数字BenchmarkRun.idbenchmark 页面的实时进度当前任务详情与 SearXNG 限流警告不再被静默丢弃且没有放宽授权边界。LangGraphAgentStrategy.analyze_topic不再在工具调用显示循环里用截断的工具参数覆盖query参数——作为默认策略此前首次web_search后原始研究问题会被 ≤80 字符的搜索参数替换进而污染引用再综合、回退综合与记录的question字段。send_message采用共享require_json_body装饰器非 JSON 请求体不再绕过统一的 400 契约GET /api/report/id已改读research_resources表。报告持久化形状变更research_history.report_content持久化时只存综合答案LLM 散文 内联引用不再内嵌## Sources/## Research Metrics。用户可见视图不变——assemble_full_report()report_assembly_service.py按需重构旧显示形状含内嵌章节的旧行会被检测且不重复追加。直接调用storage.get_report()/storage.get_report_with_metadata()的代码需改用assemble_full_report()以获得旧形状。News API 的findings字段同样为 answer-only 报告内容有意为之结构化 top-N 来源链接在独立的links数组中。五、研发流程与测试质量配套发布说明还包含若干内部质量改进对二次开发者有参考价值CI 并行稳定性test_settings_routes_coverage.py的 94 个测试每个都含 register login SQLCipher KDF 10 次 Alembic 迁移从-n auto并行池拆出为专用串行步骤用--cov-append合并覆盖率避免 xdist worker 静默死亡pytest-timeout从signal改为thread方法全局单测超时从 60s 提升到 180sSIGALRM 在 Python 3.14 的weakref.py清理中会破坏 xdist worker 并丢弃覆盖率数据。测试质量多个脆弱的测试模式被重构——7 个复制粘贴的captured_username块合并为单一 fixture16 行SocketIOService._instance None重置改为 autouse fixturesetup 与 teardown 都运行三个同义反复的 dict 断言测试换成驱动真实SettingsManager的行为测试三个针对chat/routes.py的源码 grep 测试换成驱动共享 reclaim 辅助函数与真实 SQLite 会话的 8 个行为测试。对 Chat Mode 流式路径剥离think、carry buffer 溢出契约、LLM 标题换行剥离等均新增了回归测试。六、升级与运维清单日志安全确认部署环境中LDR_LOGURU_DIAGNOSE未开启如需调试临时同时设置LDR_APP_DEBUGtrueLDR_LOGURU_DIAGNOSEtrue用毕即除。详细环境变量说明见 env_configuration.md。Chat 入口通过侧边栏Chat或/chat/使用多轮研究会话会话持久化在每用户加密数据库中。追问上下文按需调整chat.followup_context_modesummary/raw/full/none注意仅summary每次追问产生额外 LLM 调用。引用格式report.citation_format现在对 Chat 答案同样生效可按需切换为域名/源标签式引用。并发上限Chat 触发的研究现在计入app.max_concurrent_researches多标签页并行 Chat 会受到同一每用户上限约束。报告形状变更若你直接调用了storage.get_report()等 API请改用assemble_full_report()获取包含 Sources 的旧形状。新闻订阅订阅未显式配置模型时不再被强制切到 Ollama将正确回退到全局llm.provider/llm.model设置。以上所有要点均可在 1.7.0 发布说明 及其引用的源码文件中核对更完整的 Chat Mode 功能说明见 features.md 的 Chat Mode 章节搜索引擎与引用格式的配置见 CONFIGURATION.md。【免费下载链接】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),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价