Liushenwuzhu-Alpaca

LearnTrace:让 AI 辅助学习的过程可以被说明

DATE
LENGTH
31 分钟
TAGS
博客 / AI / Agent / 学习
SERIES
人工智能
STATE
生长中

生成式人工智能已经成为编程学习和课程项目里的日常工具。面对这一变化,评价不该再执着于分辨学生有没有使用 AI,而该问一个更有价值的问题:学生在使用 AI 的过程中,有没有思考、判断、修正和验证,又从中学到了什么。

现有作业通常只能交出最终代码和报告。真正的学习过程散落在聊天记录、Git 提交、设计文档和测试日志里,学生说不清,教师也看不见。LearnTrace 补的就是从「项目痕迹」到「学习说明」之间的这一层。

LearnTrace 是一个面向 AI 辅助课程项目的本地学习档案智能体。原则只有三句:证据优先,学生确认,隐私最小化。 它不是侦测器,不评分,不推荐资源,也不评估掌握程度。它帮助学生说明:AI 如何参与项目,自己如何作出决定,这些决定怎样经过实践验证。

项目仓库:https://github.com/constantinmay/learntrace-skill
版本:LearnTrace 0.1.0(2026 年 9 月参赛提交版)

评价该问什么

AI 编码工具已经能参与需求理解、方案讨论、代码修改、调试和测试。「用没用 AI」越来越难从最终代码可靠判断,也不该成为唯一焦点。一个学生可能大量使用 AI 输出却没有理解;另一个学生可能在多轮讨论里发现问题、拒绝错误建议,并形成新的认识。两个标签装不下这些差异。

我们不希望 LearnTrace 成为另一个检测工具。更关心的是:

  • 学生能不能提出合适的问题
  • 能不能理解和检查 AI 的回答
  • 建议不适用时,能不能修改或拒绝
  • 能不能从失败里调整方案
  • 能不能用测试、文档或代码变化验证自己的判断

使用 AI 本身,既不能证明已经学习,也不该自动成为否定学习的理由。评价应当回到这些可以说明、可以核验的过程上。

因此系统不回答「这段代码到底是谁写的」,而帮助学生回答:「我如何借助 AI 推进项目,我在哪些地方作出了自己的判断,我从这些选择中学到了什么。」教师看到的不是模型给出的结论,而是一份可以继续追问、可以返回原始材料核验的学习档案。

五项设计原则贯穿始终:

  1. AI 使用透明化。 不把 AI 参与当成需要隐藏的行为。
  2. 证据优先。 先回答「发生了什么」,再讨论「为什么」和「学到了什么」。
  3. 学生拥有解释权。 系统只能提出候选学习节点,不能替学生宣布已经掌握某项知识。
  4. 最小化收集。 不为「分析更全面」默认收集完整聊天和源码。
  5. 过程可核验。 关键内容保留来源,读者可以回到提交、文档、日志或授权轨迹。

明确不做的事情同样写进设计,避免实现时目标漂移:

  • 不检测作业是否由 AI 生成,不计算所谓「AI 含量」
  • 不根据 Git 作者、聊天用户或文件修改推断贡献比例
  • 不输出学习能力分数、贡献排名或自动评分
  • 不执行待分析仓库中的代码、测试或日志命令
  • 不把时间相邻或路径相同直接解释为因果关系
  • 不把系统候选、模型总结或缺失信息写成学生的个人陈述

系统怎么工作

LearnTrace 采用「本地确定性证据工具链 + 单智能体交互层」的双层架构。

确定性程序负责可以被规则化和测试的工作:文件发现、解析、脱敏、索引、Schema 校验、候选约束和报告落盘。智能体负责理解自然语言、按 Skill 编排工具、解释结构化证据并提出追问。

没有把所有步骤都交给大模型,也没有串联多个模型分别抽取、判断和写作。学习档案涉及真实个人经历,模型链越长,事实来源越难追踪,错误也越容易在中间被放大。单智能体与本地工具的边界更清楚:模型能够改善交互,但不能修改证据等级。

主数据流是:

授权输入
  → 统一事实(带来源引用)
  → 候选学习节点(带依据和不确定性)
  → 学生确认、补充或否认
  → 可追溯档案

分析与确认分成两个阶段。首次分析固定事实和候选快照;学生回答后,确认阶段只读取该快照,不重新扫描项目,也不再次推断候选。同一个问题不会因为仓库后来变了,就悄悄换一套依据。

逻辑上分成七层:交互层、智能体编排层、应用服务层、证据处理层、学习档案层、契约层、存储层。对人来说,更直接的是六件事:先发现再读取、把异构材料变成统一事实、管住隐私和规模、提出可质疑的候选、让学生确认、同时给出人能读和机器能核的产物。

核心能力是怎样设计出来的

先发现,后读取

系统先以只列目录、不读正文的方式发现候选 Git 仓库、Markdown 或纯文本文档、测试日志和可选的 AI 轨迹,再把范围交给用户。只有确认之后才进入解析。

AI 会话导出可能含完整聊天、工具参数和源码片段,因此必须逐个文件显式授权。一份文件的授权不会自动扩展到其他会话。LearnTrace 不扫描 ~/.claude/、~/.codex/ 或 OpenCode 历史目录。

多源材料,统一成可回查的事实

Git、任务书、设计报告、已有测试日志被转换成带来源引用的可观察事件。Git 不只给最近几条提交摘要,而是生成完整但轻量的历史索引:提交树、文件角色、源码与测试是否共同出现。智能体要理解某次关键修改时,再按提交、路径、行范围或字节范围回读,避免一次加载整个仓库。暂存区和当前工作区也可以检查,尚未提交但确实存在的阶段性成果能够被如实记录。

二进制文件、Git LFS 指针、子模块、非 UTF-8 文本或超长内容不会被强行解释,只保留类型、对象标识、大小和不可读原因。测试信息只能来自用户已有的日志,LearnTrace 不会临时跑测试来制造证据。

三类编码 Agent,一种最小事件

OpenCode、Claude Code、Codex 的会话格式不同,最终都变成同一类可观察事件。默认只保留时间、工具类型、项目内相对路径、保守的命令类别、执行状态和来源宿主。完整提示词、隐藏推理、聊天正文、工具输出、补丁正文、密钥和个人绝对路径不进入公开档案。

适配器只在观察到工具返回结果时记录完成事件;非零退出码标为错误,状态无法确认标为未知,找不到对应返回的调用则跳过并产生警告。多个会话可以合并、按稳定 ID 去重,并保留原会话标识。

长会话逐行流式解析:单文件上限 256 MiB,单行 16 MiB,单会话最多 2000 个事件,合并最多 10000 个。超出限制按确定规则截断,并留下结构化警告,不会被悄悄隐藏。普通目录扫描也不能把外观像轨迹的 JSON 当成已授权输入。

工作分段:把零散工具调用收成连续过程

已授权、已脱敏的原子事件,按固定规则分成连续工作段。不调用模型,也不从自然语言摘要反推工具或路径。先按有效时间排序;相邻间隔严格大于 30 分钟时切开;当前段与下一条记录的项目对象范围完全不相交时也切开。没有安全结构化路径时,不凭摘要猜对象范围。

工作段只引用原事件,不新增事实。段 ID 由排序后的事件 ID 计算,输入换顺序结果不变。落盘前用安全元数据重新计算并逐字段比较,遗漏、重复、伪造时间/路径/工具类别都会被拒绝。

三层证据,候选必须可被质疑

档案信息严格分成三类:

层回答的问题约束
可观察事实项目中直接发生了什么必须能定位到 Git、文件、日志或授权轨迹
系统候选哪些事实可能构成学习节点必须引用依据并说明不确定性,不得作为最终结论
学生确认学生怎样理解当时的选择与收获独立保存;可确认、补充或否认;系统不代写

Git 提交是事实,但「学生因为理解了某个概念而提交」不是 Git 能直接证明的事实。一次 AI 编辑记录是事实,但「学生接受了 AI 建议」仍需要语义证据或本人确认。

默认确定性推断器可以根据明确证据提出失败后修复、约束调整、补充测试和连续追问等候选,但不会仅凭时间接近或词语相似,断言学生修改或拒绝了 AI 建议。后一类关系只有在宿主智能体获得完整会话读取授权并做语义核对,或由学生本人补充确认时,才可进入候选或学生陈述。

三份产物,职责分开

一次完整分析形成三类互补产物:

  • learning-record.md:给学生和教师读的精简档案,写项目目标、阶段进展、AI 使用场景、关键决策、验证证据、个人反思和后续计划
  • .learntrace/learning-questions.md:仍需本人确认、补充或否认的问题
  • .learntrace/archive-records.json:完整事实、来源索引、候选关系、警告和内容指纹,用于机器审计与结果复现

主档案面向阅读,机器归档面向审计,两者不能互相替代。机器归档可能含本地来源索引,应留在本机;对外分享前检查脱敏后的阅读稿,不要直接上传原始会话和完整归档。

Web 界面还会为每次会话保存不可变的阶段产物快照。后续重新分析同一项目时,旧会话里的报告和证据引用不会被新结果篡改。

没有授权轨迹时,系统仍按 Git、文档和测试日志做普通项目复盘,并明确标记 AI 协作未记录。它不会反向猜测学生是否使用过 AI。

模型放在哪一层

LearnTrace 不绑定某一家模型,也不把模型能力混进所有底层步骤,而是:单智能体、可配置模型、本地确定性工具。

三条运行路径:

  1. 纯 CLI。 证据解析、脱敏、候选生成、Schema 校验和报告渲染全部由本地 Python 以确定性规则完成,不调用远程大模型,也不要求 API Key。核心结果可测试、可重复,也能离线运行。
  2. 宿主 Skill。 作为 Codex、Claude Code、OpenCode 等宿主中的 Skill 使用时,模型登录、API 连接和对话界面由宿主负责;LearnTrace CLI 只承担本地证据工具。
  3. 内置 Web Agent。 learntrace ui <project-dir> 启动本机工作区。用户配置 API 地址、模型 ID、协议、思考强度和 API Key。支持 Anthropic Messages、OpenAI Chat Completions、OpenAI Responses,因此可以接云端服务,也可以接兼容网关或本机回环上的本地服务。

模型的作用是理解自然语言、按 Skill 编排工具、解释已结构化的证据、发起必要追问。Git 读取、文件解析、隐私过滤、结果校验和档案落盘仍由确定性代码负责。无论使用何种模型,模型输出都不能直接突破 Schema 和渲染器的证据约束。

Web 请求链路是:

浏览器(本机)
  → FastAPI 会话服务
  → 内置 Pi SDK Agent
  → 用户配置的兼容模型 API
  → 受控 LearnTrace 工具

本地服务只监听回环地址,用一次性启动令牌和 HttpOnly Cookie 建立会话;同时校验回环 Host。API Key 进操作系统凭据库,不进入目标项目、浏览器存储、SQLite 或普通 JSON 配置。

需要说清一件事:「文件保存在本地」和「内容从不发送到远程模型」不是同一件事。选择远程 API 时,对话内容、模型所需的证据片段和工具结果可能进入远程模型上下文。若不希望发送语义内容到远程服务,应使用纯 CLI,或连接符合协议的本地模型服务。

Skill 不是操作系统沙箱。内置 Agent 的 run_command 会校验命令和路径:核对过的 LearnTrace 操作可自动放行,授权、导出、范围外或其他命令必须请求用户批准。只读的 read/grep/find/ls 不经过同一命令守卫,使用范围由 Skill 流程和底层工具行为共同约束。系统把自己定位为有边界的本地工具,而不是完整操作系统沙箱。

开发时真正难的地方

设计文档把开发重点写成:不是让模型自由撰写一份「看起来合理」的成长故事,而是让每项重要叙述都能回到原始材料,并把关于个人学习的最终解释权交还给学生。下面这些难点,决定了系统现在的形状。

异构材料必须先有同一种语义

Git 记录文件树和差异,测试日志记录执行结果,文档表达项目目标,智能编码工具又使用不同的 JSON 或 JSONL。如果每个模块直接输出自己的自然语言,归档层无法可靠判断证据等级。

解决办法是先冻结 Schema v0 和公共模型:稳定标识、事件类型、摘要、时间、来源引用、缺失状态、候选生命周期。各适配器只负责格式转换,不直接生成学习结论。跨模块信息可以被契约测试,而不是靠约定俗成。

信息完整性和上下文规模互相打架

完整复制源码、聊天和工具输出,会造成上下文膨胀和隐私风险。LearnTrace 采用「轻量索引 + 按需回读」:先保存提交、对象和文件角色等可检索索引;需要核验时,再按提交和路径分页读取有限行数或字节。轨迹使用流式解析与稳定截断,任何丢弃都有警告。

相关性很容易被写成因果关系

早期候选生成容易把时间接近的 AI 操作和 Git 提交配对,也容易让文档与提交形成大量重复候选。最终实现删除了单纯时间邻近推断,增加主题、类型和顺序约束,限制候选总量,并以学生确认作为最终门槛。宁可少提出一个候选,也不把未经支持的关联写成学习经历。

自然语言要可读,事实底线不能让

纯规则报告准确但机械,模型自由写作自然却可能越界。系统将二者分开:模型生成满足 Schema 的叙事载荷,ContractValidator 检查事实引用、确认状态、缺失证据和公开边界,渲染器再生成 Markdown。渲染边界会再次脱敏,拒绝把候选当事实、把被否认内容写成收获,或在没有测试证据时声称功能已经验证通过。

ContractValidator 能检查可判定的契约错误,但不能证明每句自然语言都被引用证据完整支持。最终语义仍需学生或读者回到原始材料复核。

本地智能体必须可恢复,也必须能停住

一次学习档案分析包含授权、工具运行、等待回答和再次渲染,无法用普通单轮聊天实现。系统通过 SQLite 状态、SSE 事件流、持久 Agent 会话、结构化问题卡片、项目写锁和会话级产物快照保持一致。刷新只重新订阅快照,不创建重复分析;重启后可以恢复同一 Agent 会话,而不是把几条网页消息拼成新上下文。同一项目同一时间只允许一个分析任务写入产物。

用户停止分析时,前端立即进入停止状态,后端取消 Agent 请求和正在执行的本地命令,并尝试终止子进程树。若操作系统拒绝或无法确认进程已经结束,系统以明确的受控降级状态告知用户,而不是把任务伪装成已停止。Windows 与 Linux 的进程树、管道关闭和权限失败行为不同,超时、终止尝试和管道回收都设了上限;持续集成同时覆盖两个平台。

安全按风险逐项设防,但不夸大成绝对沙箱

主要风险包括:会话导出含密钥和个人路径;目标仓库含不可信内容;大文件耗尽资源;模型试图读取未授权范围;其他网页调用本机接口;多个分析任务并发覆盖产物;取消后遗留子进程。

对应措施是:逐文件授权、适配与渲染两次脱敏、流式解析和数量上限、解析器只读、回环监听加启动令牌、命令白名单与路径绑定、项目锁加不可变快照、超时与子进程清理、Key 进系统凭据库。

机器档案也不是数字签名。Schema 和重算可以证明内部结构一致,不能证明一个来源不可信的文件从未被整体替换。这些边界写进设计,是为了避免把工程防护说成绝对安全。

三种入口,同一套证据能力

最短路径:

uv tool install .
learntrace --version
learntrace ui <project-dir>

页面里完成模型设置、项目选择、材料范围确认、可选轨迹授权和结构化问题回答,即可查看学习档案。

只使用本地确定性管线时:

learntrace discover <project-dir>
learntrace run <project-dir>

作为宿主 Skill 使用时,把 skills/learntrace/ 装到宿主支持的目录,并保证 learntrace CLI 可执行。宿主负责模型登录与会话权限,LearnTrace 不要求为 CLI 配置远程模型。

典型流程是:

  1. 在项目目录启动 CLI、宿主 Skill 或本地 Web 工作区
  2. 系统发现候选材料,学生确认分析范围
  3. 若要纳入 AI 协作,主动提供会话导出并逐份授权
  4. 系统解析多源材料,生成可观察事件、Git 索引、轨迹工作分段和候选学习节点
  5. 智能体围绕证据不足或需要本人判断的部分提出少量问题
  6. 生成阅读档案、问题清单和机器审计档案
  7. 学生检查脱敏后的学习档案,用于复盘、课程总结或答辩;机器档案留在本机

核心 CLI 需要 Python 3.11+。仅使用宿主 Skill 时不必另装 Node.js;使用自带 Web 工作区需要 Node.js 22.22.2+。前端静态资源、Agent 服务和 Skill 已随 Python wheel 分发,普通用户无需分别启动开发服务器。

一个可以独立检查的闭环

仓库里的 examples/task4-demo 是一组合成材料,用来检查工程闭环,不冒充真实教学效果。

案例模拟名单导入:设计文档要求支持带引号的 CSV 字段;已有 pytest 日志显示姓名「Smith, Jr.」被错误拆成两列;随后补丁把单一正则表达式替换为小型状态机,并增加引号逗号和空字段测试。

系统能确定的是失败用例和后续提交,并保留到来源的引用。它可以问:这次修改是否是为了修复日志里的失败?示例确认文件明确标注为模拟回答。确认内容进入学习档案;未经授权容器绑定的 AI 建议记录被忽略并产生警告。默认推断器也不会把会话中的 AI 建议与后续提交自动配对——这项关系必须依赖完整授权语义,或学生本人开口。

工程质量与当前边界

作品后端以 Python 3.11、FastAPI、Uvicorn、JSON Schema、SQLite、Keyring 实现 CLI、HTTP/SSE、会话存储、证据解析和档案管理;前端采用 React、TypeScript 与 Vite;内置智能体服务基于 Pi SDK。工程侧覆盖单元、契约、集成、UI、发布和跨平台测试,并用 Ruff、Pyright、Pytest、TypeScript 类型检查做持续质量控制。失败状态显式处理:缺失文件、未授权输入、格式错误、截断、无法识别的调用类型和未知执行状态,都会形成可见结果或结构化警告。

参赛提交版记录的公开持续集成基线为提交 0af1135。2026 年 9 月 6 日的 GitHub Actions 显示,Python 全量测试在 Ubuntu 和 Windows 上均为 690 项通过、1 项跳过,Web 测试 6 项通过,Agent 测试 81 项通过;Ruff、Pyright、前后端构建、资源同步和 wheel 检查同时通过。这些结果证明对应提交满足既定工程检查,但不替代对教学价值的案例观察和用户评价。

当前版本主要支持 Git、Markdown/纯文本、常见测试日志和三类编码 Agent 会话;对 PDF、Word 等复杂二进制文档主要记录文件事实,不强行解释正文。「测试通过」必须来自用户已有日志。候选学习节点不是自动评分。第一版优先保证证据边界和完整闭环:不自动运行测试,牺牲了一部分便利,却避免执行不可信项目;候选推断偏保守,可能漏掉缺乏证据的真实学习经历,但不会用模型猜测填满报告。

这些限制是有意的产品边界。课程评价涉及真实个人经历,系统宁可明确缺失证据,也不为得到更完整的报告而扩大读取范围、自动执行不可信代码,或让模型补写未经确认的经历。

后续可在不改变核心理念的前提下扩展文档格式和编码工具,增加团队视图、课程模板、脱敏分享模板和本地证据查看器,也可以在阶段边界加入轻量检查点,减少事后回忆造成的信息缺失。扩展顺序仍然是:先提高证据可用性和用户控制能力,再增加自动推断。目标不是掌握更多学生数据,而是用更少、更清楚的证据帮助学生讲明白自己的学习。

真正想留下的

在 AI 已经成为学习工具的今天,简单追问「学生是否使用了 AI」越来越难以反映真实学习情况。LearnTrace 把问题向前推一步:不回避 AI 的参与,也不把使用 AI 等同于完成学习,而是认真记录学生怎样提问、怎样判断、怎样修正,以及怎样验证。

程序保存事实并执行约束,模型帮助理解和组织,学生决定哪些候选真正代表自己的学习。最终档案既能够阅读,也能够回查;既承认 AI 的参与,也保留学生作为学习主体的判断权。

真正值得被看见的,不是一份看似完全由人独立完成的结果,而是学生在新工具参与之后仍然保有的思考和成长。LearnTrace 所做的,就是让这部分过程有证据可循、有本人确认,也有机会进入课程总结与评价。

系列 · 人工智能



Search