完整项目:个人笔记与面试助手

# 完整项目:个人笔记与面试助手

本篇目标

把 Agent 开发整块知识收束为一个可实现、可评测、可在面试中完整讲述的项目,覆盖需求、架构、数据、流程、安全和演进路线。

形成完整架构拆解交付里程碑准备项目故事覆盖系统设计追问

# 项目一句话

个人笔记与面试助手以本地技术笔记为可信知识源,提供带引用问答、模拟面试、薄弱点记录和复习计划;Agent 负责开放式检索与追问,Workflow 负责权限、评测、审批和状态恢复。

# 需求与非目标

# 核心需求

  1. 按知识库搜索 Markdown 并生成可追溯回答;
  2. 根据岗位和难度进行模拟面试与动态追问;
  3. 识别薄弱点,经用户确认后写入学习记录;
  4. 根据掌握度生成复习计划;
  5. 支持流式进度、暂停、恢复、取消和失败解释。

# 第一版不做

  • 不自动改写或删除原笔记;
  • 不做无边界联网研究;
  • 不一开始拆多个 Agent;
  • 不让模型直接持有部署、数据库或第三方密钥;
  • 不以 “回答看起来不错” 代替评测。

# 总体架构

图中的 SSE 是服务端向浏览器持续推送状态的 HTTP 连接;BFF(Backend for Frontend)是专门服务这个前端的后端接口层;HITL 是需要用户审批或补充信息时暂停任务;Tracing 则把一次任务经过的步骤串成可排查的记录。

Web 前端
  ├─ 问答 / 模拟面试 / 学习计划
  ├─ SSE 任务事件
  └─ 审批与恢复
        ↓
API / BFF:鉴权、限流、taskId、事件协议
        ↓
Workflow Runtime
  ├─ 输入校验与 Router
  ├─ Agent Loop
  │   ├─ search_notes
  │   ├─ read_note
  │   └─ get_learning_progress
  ├─ RAG 与 Context Builder
  ├─ Eval / 引用检查
  └─ HITL:save_learning_gap
        ↓
PostgreSQL + Vector Store + Object Storage + Queue
        ↓
Tracing / Metrics / Eval Dataset
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 核心数据模型

Document(id, path, title, module, version, updatedAt, accessScope)
Chunk(id, documentId, heading, content, embedding, metadata)
Thread(id, userId, mode, createdAt)
Task(id, threadId, goal, status, phase, budget, version)
Checkpoint(taskId, version, state, completedActionIds, createdAt)
LearningGap(id, userId, topic, evidence, confidence, confirmedAt)
Trace(traceId, taskId, versions, metrics, outcome)
1
2
3
4
5
6
7

学习薄弱点必须带证据和用户确认,不把模型推断直接写成长期记忆。

# 一次问答流程

  1. API 鉴权、限流并创建 Task;
  2. Context Builder 组装目标、权限、相关历史和可用工具;
  3. Router 判断直接回答、RAG 问答或模拟面试;
  4. Agent 通过 Tool Calling 搜索和读取笔记;
  5. RAG 做权限过滤和混合召回,再用重排模型(Reranker)重新排列候选结果并生成引用;
  6. 生成器输出答案,Evaluator 检查证据和覆盖度;
  7. 通过后返回 completed,不足则补查或 incomplete;
  8. 每步保存状态并发送事件,Trace 记录完整链路。

# 一次模拟面试流程

选择岗位与难度
  ↓
根据知识库和掌握度选题
  ↓
用户回答
  ↓
Evaluator 按准确性、结构、项目例子评分
  ↓
Agent 根据缺口动态追问
  ↓
生成可直接复述的改进答案
  ↓
预览薄弱点 → 用户确认 → 写入 Memory
1
2
3
4
5
6
7
8
9
10
11
12
13

追问次数、覆盖主题和停止条件属于任务状态;问题与参考答案来自笔记和评测集,不让模型完全自由发挥。

# Tool 设计

Tool 风险 关键控制
search_notes 只读低风险 权限过滤、TopK、输出裁剪
read_note 只读低风险 允许路径、大小上限
get_learning_progress 私有只读 服务端绑定 userId
preview_learning_gap 无副作用 生成结构化预览
save_learning_gap 写操作 审批、参数哈希、幂等

# 评测集

至少准备这些切片:

  • 已有笔记可直接回答;
  • 需要跨两篇笔记组合;
  • 证据不足应拒答;
  • 新旧文档冲突;
  • 相似工具选择;
  • 恶意 Markdown 提示注入;
  • 普通用户试图读取其他知识库;
  • 写入审批、拒绝、过期和重复提交;
  • 达到最大轮数后保留结果并恢复。

指标包括完成率、引用准确率、工具选择、拒答、安全、P95 延迟、每成功任务成本和人工介入率。

# 分阶段实现

# 第 1 阶段:可验证问答

完成文档解析、RAG、引用和离线评测,不先做 Agent 循环。

# 第 2 阶段:安全 Tool Calling

增加搜索、读取进度工具,建立 Schema、权限、超时和 Trace。

# 第 3 阶段:Agent + Workflow

只在证据不足和模拟追问时使用 Agent Loop,外层 Workflow 控制预算和验收。

# 第 4 阶段:Memory 与人工介入

保存任务状态和 Checkpoint,经用户确认写入薄弱点,支持刷新恢复。

# 第 5 阶段:生产闭环

加入队列、SSE 和小比例灰度发布,再补齐成本预算、安全评测和运行告警,最后比较 Mastra 与 LangChain 的真实实现代价。

# 面试项目回答模板

# 2 分钟版本

我做了一个个人笔记与面试助手,它不是让模型随便聊天,而是根据我的 Markdown 笔记生成带来源、可以检查的回答,还能通过模拟面试发现并记录薄弱点。

架构上,我先把流程分成确定和不确定两部分。鉴权、检索流程、质量检查、审批和停止条件由 Workflow 控制;只有第一次检索不够时怎样补查,以及模拟面试怎样根据回答继续追问,才交给 Agent。工具虽然用 Schema 描述,但真实权限和执行始终由后端控制。RAG 负责从笔记中找证据,任务状态和 Checkpoint 单独持久化,所以页面刷新或任务超时后仍能继续。保存薄弱点属于写操作,必须先展示预览并获得用户确认,同时使用幂等键防止重复写入。

最后,我用一组真实面试题检查任务完成率、引用、工具选择、安全、延迟和费用,并用 Trace 判断失败发生在检索、模型决策还是工具执行。实现上可以用 Mastra 完成 TypeScript 版本,也可以用 LangChain、LangGraph 和 LangSmith 完成 Python 版本,但面试时我更强调这些框架背后的状态、权限和评测设计。

# 被追问 “最大的难点是什么”

最大的难点有两个。第一,模型说得像真的,不代表它使用了正确笔记,所以我把检索和回答分开评测,并让引用绑定真实文档 ID。第二,长任务可能因为刷新、超时或服务重启中断,所以我把任务状态从聊天记录中独立出来,在关键步骤保存 Checkpoint,写操作再配合审批和幂等。这样既能定位错误来自检索、生成还是执行,也能安全恢复任务。

# 被追问 “为什么使用 Agent”

因为有两类下一步很难提前写死:第一次没找到合适笔记时,要根据已有结果决定怎样改写和补查;模拟面试时,也要根据用户刚才的回答决定追问什么。其他固定流程仍由 Workflow 控制,包括权限、评测、写入和停止。也就是说,我不是把整个系统都改成 Agent,而是只把真正需要语义判断的局部交给模型。

# 系统设计追问

1. 如何保证引用不会被模型编造?参考答案

模型只引用检索结果中的 documentId,最终链接由宿主应用查表生成;返回前校验引用存在、用户有权限且确实支持对应陈述。

2. 如何支持十分钟的长任务?参考答案

API 创建 taskId 后把工作放入队列,由后端 Worker 执行,并在每一步保存 Checkpoint。前端通过 SSE 接收进度,页面刷新后用同一个 taskId 查询状态并继续订阅。取消操作写入持久化标记,产生副作用的写入使用幂等键,避免恢复或重试时重复执行。

3. 如何证明 Agent 改造值得?参考答案

先用固定 RAG/Workflow 建基线,再用同一真实任务集比较开放问题的完成率、人工介入、延迟、成本和故障。只有收益超过新增复杂度才保留 Agent。

4. Mastra 和 LangChain 最终选哪个?参考答案

我会先用同一条小而完整的业务链路做概念验证。TypeScript 全栈团队和一体化交付更偏向 Mastra;Python 生态、复杂状态图和 LangSmith 体系更偏向 LangChain/LangGraph。领域状态和 Tool 契约保持框架无关,这样即使以后切换框架,业务层也不用跟着大改。

5. 下一步怎样演进?参考答案

先扩大真实评测集和补齐失败恢复,再根据证据决定是否增加多 Agent、MCP 远程复用或 A2A。不会为了功能列表提前引入复杂架构。

# Agent 开发知识库完成后的复习方法

  1. 先用总览图复述主线;
  2. 每篇只看 “先记住一句话” 和面试回答;
  3. 不看答案完成折叠自测;
  4. 用本项目贯穿回答每个架构问题;
  5. 对答不顺的主题回到原理和代码,而不是死背术语。

# 参考资料

上次更新时间: 2026年09月05日 01:03:42