DeepTutor v1.0.3 深度解析:题目笔记本、Mermaid 可视化与知识库兼容性加固
本文基于 DeepTutor 开源仓库中归档的 v1.0.3 Release Notes(发布于 2026.04.13)编写,逐条拆解该版本引入的核心能力,并结合仓库当前源码(如
deeptutor/api/routers/question_notebook.py、deeptutor/knowledge/manager.py、deeptutor/agents/visualize/capability.py等)定位其实现位置与工作原理。读完本文,你将了解该版本推出的「题目笔记本」复习体系、Visualize 图形生成的 Mermaid 渲染链路、知识库 Embedding 模型失配检测机制,以及针对 Qwen/vLLM、本地推理服务的一系列兼容性处理,便于在部署、接入或二次开发时直接对照验证。
版本说明:本仓库代码已演进至更高版本(见 deeptutor/version.py),但 v1.0.3 引入的核心功能在当前代码中仍有清晰的落点,文中将以「当前实现位置」形式给出可检索的源码路径,供读者按图索骥。
一、版本总览:v1.0.3 改了什么
v1.0.3 是 DeepTutor 生命周期中的一次功能密集迭代,八个主要特性可归类为三条主线:
| 主线 | 涉及功能 |
|---|---|
| 学习数据资产化 | Question Notebook(题目笔记本)取代单用途错题本 |
| 图形生成能力扩展 | Visualize 新增 Mermaid 渲染类型 |
| 兼容性与稳定性加固 | Embedding 失配检测、System Message 合并、LM Studio / llama.cpp 接入、报告 Agent 重试收敛 |
| 前端体验 | Glass 玻璃拟态主题、文档站迁移 |
下文逐一展开,并在每节给出可直接打开核对的仓库路径。
二、Question Notebook:从「错题本」到统一测验复习系统
2.1 解决的问题
v1.0.3 之前,系统只有单用途的 Wrong Answer Note(错题本),只保存做错的题目,无法支撑体系化的回顾复习。v1.0.3 用完整的 Question Notebook 将其取代:所有测验题目(答对与答错)都会持久化入库,并携带丰富的元数据。
2.2 一条记录存什么
题目条目携带的元数据在 Release Notes 中给出方向,当前 question_notebook API 的 NotebookEntryItem 模型则给出了完整字段级定义,可直接对照:
| 字段 | 含义 |
|---|---|
question / question_type |
题干与题型(选择/填空等) |
options |
选项字典(dict[str, str]) |
correct_answer / user_answer |
标准答案与用户作答 |
user_answer_images |
作答附带的图片引用(字节存于 AttachmentStore,避免 base64 回流) |
explanation / difficulty |
解析与难度 |
is_correct |
是否正确(这是它与旧错题本的本质差异——对错都记录) |
bookmarked |
是否被书签标记 |
ai_judgment |
AI 判定结果 |
session_id / session_title / turn_id |
溯源:回到产生题目的会话 |
categories |
所属分类(多对多) |
由此可以推断,题目的复习价值不只依赖「对错」二元标签,而是一整套可筛选、可回溯、可二次跟进的元数据结构。
2.3 三种组织与复习手段
- Bookmark(书签):对重点题目标记,建立自己的「待复习清单」。
- Category Tagging(分类标签):支持分类的创建、重命名、删除,按知识点/章节维度组织题库。
- 会话回链:每条记录携带
session_id与turn_id,从笔记本可一键回到原始会话查看上下文。
2.4 交互入口:/notebook 页面与 QuizViewer
该版本新增专用 /notebook 页面,提供:
- 筛选:全部(all)/ 已书签(bookmarked)/ 错题(wrong)三种视图;
- 分类管理:分类的增删改;
- 会话直达链接。
同时,QuizViewer 组件把书签与分类控件内联到做题界面中——用户在测验流程中即可直接组织题目,无需跳出。
后端接口方面,question_notebook.py 暴露了包含 bookmarked、category_id 过滤参数(如 bookmarked: bool | None、category_id: int | None,见 L207-L216)与「条目加入分类」的写入接口;该路由在 api/main.py 被挂载进 FastAPI 应用,测试侧可参考 tests/api/test_notebook_router.py。
此外,DeepTutor 的 CLI 同样提供笔记本类命令入口 deeptutor_cli/notebook.py,包含 list(列出笔记本)、create、show、remove-record、add-md(把 Markdown 作为 record 加入,支持 question/research/solve/chat 等类型)与 replace-md 等命令——尽管该 CLI 模块面向通用笔记本记录,但其与题目笔记本共用「notebook/record」这一核心抽象,可作为理解题笔记本存储模型的旁证。
三、Visualize 新增 Mermaid 渲染:结构化图生成链路
3.1 三种渲染类型并存的选型逻辑
v1.0.3 把 Visualize 能力从 svg、chartjs 两种类型扩展出第三种——Mermaid。分析 Agent 现在会在 svg / chartjs / mermaid 间做选择,并对结构化图(流程图 flowchart、时序图 sequence diagram、类图 class diagram、思维导图 mindmap 等)优先倾向 Mermaid。
当前 visualize 能力实现 中,render_type 作为结果信封的判别字段,前端据此路由到对应 Viewer;其描述中可确认该能力已包含 SVG、Chart.js、Mermaid、交互式 HTML 与 Manim 动画等多条渲染管线。分析 Agent 的 render_mode 也显式接受 mermaid(见 analysis_agent.py)。
3.2 代码生成与评审 Agent 的提示词升级
Mermaid 支持并非只改前端,后端代码生成(code generator)与评审(review)Agent 的提示词同步更新,以让模型按 Mermaid 语法规范产出可渲染代码。对应提示词文件位于:
- agents/visualize/prompts/en/code_generator_agent.yaml / zh 版
- agents/visualize/prompts/en/review_agent.yaml / zh 版
从源码演化看,评审环节经历了「LLM 评审」到「本地确定性校验」的演进:当前 capability 的注释(L147-L152)明确指出,旧版通用 LLM 评审已被零成本的本地检查取代,其中就包括 Mermaid lint——校验通过则直接交付草稿,失败才触发一次「针对具体报错」的定向修复调用(run_repair),从而省去一整轮串行 LLM 评审。生成结果以 ```mermaid 围栏代码块形式进入聊天流,前端再交给专用 Viewer 渲染。
3.3 前端渲染组件
前端由专门设计的 <Mermaid> 组件负责渲染(见 web/components/Mermaid.tsx),VisualizationViewer 依据 render_type 将 mermaid 分派给该组件,而非走通用代码高亮路径。
四、知识库 Embedding 模型失配检测:给索引加上指纹
4.1 机制概览
知识库(Knowledge Base)在建索引时记录所用的 Embedding 模型与维度;加载时系统把存储的指纹与当前配置的 Embedding 模型比对,不匹配的 KB 会被打上两个标志:
embedding_mismatch:Embedding 指纹不一致;needs_reindex:需要重建索引。
RAG 检索管线在查询失配 KB 时会上抛警告,Knowledge 页面显示告警徽章,提示用户执行 re-index。
4.2 源码级实现证据
该判定逻辑在 deeptutor/knowledge/manager.py 中有完整的落地实现,核心思路如下(L222-L235):
- 读取当前配置指纹
fp[0](模型)与fp[1](维度),与 KB 条目存储的embedding_model/embedding_dim比较; mismatch = (stored_model and stored_model != current_model) or (stored_dim 与当前维度不一致);- 如果磁盘上存在 ready 索引版本但没有任何版本匹配当前活跃签名,同样判定为失配(L228-L230);
- 一旦判定失配且尚未标记,则置
embedding_mismatch = True,并在尚无needs_reindex时补上needs_reindex = True; - 反之,匹配恢复时清除这两个标志(见 L134、L237-L239)。
状态文案(needs_reindex 等)在多语言上也有统一描述,位于 deeptutor/knowledge/manifest.py,例如英文 "needs reindexing, retrieval may be incomplete"、中文 "需要重建索引,检索结果可能不完整",且被系统提示词 manifest 与工具报告共用同一措辞。失配标志还出现在多个 RAG 管线与配置模块中(如 deeptutor/services/rag/service.py 与 deeptutor/services/config/knowledge_base_config.py),相关回归测试可参考 tests/knowledge/test_manager_embedding_flags.py。
这一机制对自托管/多模型用户尤其重要:当用户从某个 Embedding 模型切换到另一个(维度也可能变化)时,旧索引的向量空间与新模型不可通用,静默使用会导致检索质量劣化。显式的失配告警把「隐性错误」转成「显式操作指引」。
五、System Message 合并:修复 Qwen / vLLM 兼容性
5.1 问题背景
部分 Qwen 系列模型经 vLLM 提供服务时拒绝多 system 消息的会话。DeepTutor 的 Agentic 会话管线此前可能拼接出多条 system 消息,在切换到这类推理后端时直接报错。
5.2 修复方式
v1.0.3 在两个层面做了收敛:
- 管线层:在
AgenticChatPipeline(当前对应 deeptutor/agents/chat/agentic_pipeline.py)与ChatAgent中,把多条 system 消息合并为一条整体 system 消息。从当前代码可以看到,会话消息以单条系统提示打头(messages = [{"role": "system", "content": system_prompt}],见 L398),系统提示由 KB 说明、Workspace 说明、能力块等动态拼装,保证单轮内 system 内容稳定。 - 历史上下文层:Context Builder(见 deeptutor/services/session/context_builder.py)从存储的历史中过滤重复的 system 消息,避免重放旧会话时把冗余 system 重新注入,从而进一步降低多 system 消息出现的概率。
对部署 Qwen + vLLM 的用户,该修复属于「换了推理后端就能直接跑」的关键兼容点。
六、本地模型新贵:LM Studio 与 llama.cpp 的一等公民接入
6.1 新增内容
v1.0.3 为本地推理生态新增了两种一等公民 Provider 配置:
- LM Studio(默认
localhost:1234) - llama.cpp(默认
localhost:8080)
两者均通过 openai_compat 后端接入,支持自动 base-URL 探测,同时补充了 Embedding Provider 的别名映射。
6.2 当前代码中的对应关系
在 deeptutor/services/config/provider_runtime.py 中可以看到统一的 provider 规范建模方式:以 EmbeddingProviderSpec 为例,vllm 条目的标签即为 "vLLM / LM Studio",关键词含 ("vllm", "lmstudio")(见 L135-L141);对外服务类 provider 同样存在 adapter = "openai_compat" 的映射簇(L70、L211)。别名映射(如 "lmstudio": "vllm")与 embedding 端点别名("llama_cpp": "vllm",见 embedding_endpoint.py)也仍在提供本地 OpenAI 兼容服务的归一化接入。
由此可以推断,接入这类服务通常只需配置其 OpenAI 兼容端点地址即可被统一发现与复用,无需为每个本地进程单独写死厂商逻辑——这正对应 Release Notes 中「自动 base-URL 探测 + openai_compat 后端」的设计意图。
七、Glass 玻璃拟态主题与前端体验升级
v1.0.3 引入第三套视觉主题 Glass:毛玻璃卡片表面(frosted-glass)、渐变背景与光晕强调按钮。主题切换器现在按 light → dark → glass 三态循环。
该主题体系在前端有完整落点:
- 主题管理相关:web/lib/theme.ts、web/lib/theme-utils.ts;
- 首屏注入与避免闪白:web/components/ThemeScript.tsx;
- 外观设置页(主题预览卡片):web/app/(utility)/settings/appearance/page.tsx/settings/appearance/page.tsx)、web/components/settings/ThemePreviewCard.tsx;
- 玻璃质感样式定义可在 web/app/globals.css 中检索
glass相关规则。
由于 appearance/page.tsx 与 ThemeScript.tsx 均参与主题态的持久化与首屏注入,多主题切换(含 Glass)对既有使用习惯是无缝的。
八、Deep Research 报告 Agent:三合一重试收敛
在报告生成 Agent(research/reporting 链)中,导言(introduction)、正文小节(section body)与结论(conclusion)原本各有一段逐字重复的「LLM 调用 + 解析」内联块。v1.0.3 将它们抽取为共享的 _call_llm_json 助手,并加入可配置的重试逻辑:
- 三处重复代码收敛为一处实现,降低维护成本;
- 重试策略集中管理,单次解析失败时可在同一位置统一处理;
- 为后续在报告链上叠加更精细的容错策略留出了统一入口。
相关 Agent 代码位于 deeptutor/agents/research/,单元测试可参考 tests/agents/research/。
九、文档迁移与社区贡献
- 文档迁移:移除旧版 VitePress
docs/目录,文档整体迁移至项目官网,仓库侧不再维护与代码同步容易失配的双份文档。 - 社区贡献致谢(Release Notes 中列出的 PR):
@cskwork—— 支持跨会话测验回顾的错题记录(#292),这是 Question Notebook 的早期推动者;@OlegSob-glitch—— 合并 System Message 并加入历史引用回退(#295),对应第五节;@SuperMarioYL—— 知识库 Embedding 模型失配检测(#299),对应第四节。
十、如何在当前仓库中验证这些能力
建议按功能各自打开对应实现与测试文件核对,路径汇总如下:
| v1.0.3 特性 | 当前源码参考 | 相关测试 |
|---|---|---|
| Question Notebook | deeptutor/api/routers/question_notebook.py、deeptutor/api/main.py | tests/api/test_notebook_router.py |
| Mermaid 可视化 | deeptutor/agents/visualize/capability.py、web/components/Mermaid.tsx | tests/agents/visualize/ |
| Embedding 失配检测 | deeptutor/knowledge/manager.py、deeptutor/knowledge/manifest.py | tests/knowledge/test_manager_embedding_flags.py |
| System Message 合并 | deeptutor/agents/chat/agentic_pipeline.py、deeptutor/services/session/context_builder.py | tests/agents/chat/ |
| 本地 provider 接入 | deeptutor/services/config/provider_runtime.py、deeptutor/services/config/embedding_endpoint.py | tests/services/test_provider_registry.py |
| Glass 主题 | web/lib/theme.ts、web/app/(utility)/settings/appearance/page.tsx/settings/appearance/page.tsx) | web/tests/appearance-settings-page.test.ts |
对希望「开箱即用」的同学,v1.0.3 的能力多数已随后续版本持续演进到当前仓库;若要复现该版本原始形态,可对照归档发布说明 assets/releases/past_releases/ver1-0-3.md 及仓库其余历史版本说明(见 assets/releases/)理解版本脉络。总体而言,v1.0.3 的取向非常清晰:把测验数据沉淀成可检索、可分类、可追溯的学习资产,同时让图形生成与模型接入对不同推理后端保持高度兼容——这两条线索贯穿了其后多个版本的演进方向。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0632
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
video-shotcraftAI宣传片skill,使用 Remotion 制作电影级产品视频:提供106 张镜头配方卡和可复用的视频魔板。适用于 Claude Code 与 Codex以及所有其他智能体Markdown00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python09
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00