智能体
mp.weixin.qq.com ·
@山行AI
本地校园 Agent 落地实践:CourseRaptor 架构拆解
文章拆解了校园 Agent 项目 CourseRaptor 的架构:将课表、成绩、考试、通知、待办、知识库、文档生成和日历等能力拆成 31 个可调用工具,按教务查询、通知附件、本地文件、时间日历、记忆知识库等分层;终端 TUI、本地 Web UI、QQ 机器人和无头 CLI 共用同一套本地内核。项目截至 2026 年 10 月 1 日约 20 Star,版本 0.3.0,ISC License,仅适配南京工业大学;作者基于源码和文档做静态整理并启动离线演示,未使用真实教务账号、未调用 DeepSeek、未访问真实教务系统。
AI推荐理由 对 CourseRaptor 校园 Agent 的架构拆解,具体给出 31 个工具的分层、三端入口共用本地内核、凭证与写操作边界等设计细节,并明确说明项目约 20 Star、版本 0.3.0、仅适配南京工业大学、未使用真实教务账号和 DeepSeek,证据边界清晰。局限在于项目规模小、单校适配,文中演示数据为虚构,实际落地效果未经验证。
72
正文
原创 山行AI 2026-10-03 10:42 河南

一个本地校园 Agent 是怎样落地的
LOCAL CAMPUS AGENT / ARCHITECTURE
31 个工具、三端入口与本地凭证保护
本文看点
01
31 个工具如何分层
02
三端共用一个 Agent
03
凭证与写操作边界
很多“校园 AI”项目停留在问答层:把学校 FAQ 接进模型,再给一个聊天框。
CourseRaptor 走的是另一条路线。它把课表、成绩、考试、通知、待办、知识库、文档生成和手机日历,拆成可以被 Agent 调用的工具;再把终端、网页、QQ 和无头 CLI 接到同一套本地内核上。
所以它真正值得拆的,不是“能不能一句话查课表”,而是:一个校园 Agent 如何把 **自然语言、学校协议、本地状态、凭证保护和多端交互** 组织成一套可以运行的系统。
截至 2026 年 10 月 1 日,Health-525/courseraptor GitHub 快照为约 20 Star,项目版本为 0.3.0,采用 ISC License,当前只适配南京工业大学。本文依据项目源码、公开文档、演示素材和相关 issue 进行静态整理,并实际启动了离线演示链路;没有使用真实教务账号、没有调用 DeepSeek,也没有访问真实教务系统。

— CourseRaptor 终端 TUI 首屏,内容为虚构演示数据
先给结论:CourseRaptor 的核心不是“让模型替你点菜单”,而是把学校系统能力收敛成可解释、可复用、可审计的工具接口。
01
THE REAL PROBLEM
### 一、它解决的不是一个页面,而是一组校园日常任务
传统教务系统的问题通常不是没有数据,而是数据分散在不同入口:课表在一个菜单,成绩在另一个页面,通知附件还要单独下载,考试安排又是另一种查询方式。
CourseRaptor 把这些任务统一成一句话可以触发的能力:
01问“我这周五下午有空吗”,由 Agent 查询课表并做时间判断。
02问“我的成绩和 GPA”,由工具抓取成绩、按学校规则计算并给出统计口径。
03问“最近有什么教务通知”,由通知工具拉取列表,再按需读取正文和附件。
04说“把课表导入手机日历”,由工具生成 .ics 文件,或者发布为可订阅链接。
05说“记住这个知识点”,由长期记忆或课程知识库工具落盘。
重点在于,对话只是入口,**真正的业务能力由工具负责**。模型负责理解意图、选择工具、组合结果和解释边界;不应该让模型自行猜节次、拼接成绩口径或直接构造教务写请求。
02
31 TOOLS
### 二、31 个工具是怎样分成能力层的
项目公开能力文档把工具组织成十大能力线,当前 Agent 默认可调用 31 个工具。
1. 教务查询
课表、成绩、考试、学籍、已选课程、重修课程、实验成绩、选课状态、课程搜索、教学班搜索和课程冲突对比,都由南京工业大学适配器提供。
其中 compare\_courses 是一个很有代表性的只读工具:它可以比较多门课的教师、时间、余量,并和当前已选课程做冲突检测,覆盖单双周和部分周重叠。它没有把“选哪门课”的判断交给一个不可追溯的模型结论,而是先产出结构化对比结果。
2. 通知与附件
通知能力不是只有一个“抓列表”:get\_news 获取公告,read\_notice 读取正文,fetch\_attachment 下载并解析附件。
附件处理也被拆成了本地能力:表格可以筛选和分页读取,文档可以按页续读或按关键词定位,下载过的附件进入缓存,减少重复请求。
3. 本地文件与文档
本地文件读取、Excel 查询、沙箱 JavaScript 计算、附件缓存管理,以及 Word、Excel、PPT、PDF 的生成和跨格式转换,构成了“查询之后还能交付文件”的一层。
4. 时间、日历与生活信息
项目把当前时间、教学周、放假调休、天气、番茄钟和待办都纳入工具体系。课表和考试可以生成整学期 .ics 日历;如果配置 GitHub 或 Gitee Token,还可以发布为手机可订阅的日历链接。
5. 记忆与知识库
短期会话记录跨重启延续,长期记忆保存用户明确要求记住的事实;课程知识点则独立进入知识库,按真实课程或自定义分类组织。
这一区分很重要:会话历史是“我们刚才聊了什么”,长期记忆是“以后仍然有用的事实”,知识库是“可检索的学习材料”。三者混在一起,Agent 很快会变成一堆无法治理的文本。
03
THREE CHANNELS
### 三、三端入口为什么要共用一个 Agent

— CourseRaptor 网页对话入口,内容为虚构演示数据
CourseRaptor 当前有三种主要交互入口,外加一个适合自动化的无头入口:
01**终端 TUI**:执行 raptor 直接对话,适合开发者和习惯命令行的用户。
02**本地 Web UI**:默认监听 127.0.0.1:3210,浏览器可以看到思考过程、工具调用和会话归档。
03**QQ 官方机器人**:使用白名单和激活暗号接入 QQ,私聊和群聊共用 Agent 能力,并把对话归档到网页历史。
04**无头 CLI**:skills/njtech-jwgl/ 提供不经过 LLM 对话的教务查询脚本,适合二次封装、定时任务和自动化流水线。
这几个入口没有各自实现一套“课表查询逻辑”,而是都调用 createRaptorAgent() 装配出的同一个 ToolLoopAgent。入口层只负责输入输出,Agent 层负责工具循环,学校适配层负责 NJTECH 协议。

— CourseRaptor QQ 会话归档界面,内容为虚构演示数据
04
QUERY FLOW
### 四、自然语言查询链路:一句“今天有什么安排”发生了什么

— CourseRaptor 自然语言查询链路
以“今天有什么安排”为例,一次典型请求可以拆成六个阶段:
01**入口接收消息**:终端、网页或 QQ 收到同一句自然语言。
02**Agent 读取上下文**:加载短期会话、长期事实和当前学校适配器的系统提示。
03**工具选择**:模型判断需要调用时间工具、课表工具、待办工具,必要时再读调休缓存。
04**学校能力执行**:get\_schedule 访问适配层,适配层负责登录、学期探测、节次解析和数据映射。
05**结构化结果回到模型**:工具返回课程、时间、状态和数据完整性信息,模型只负责组织成用户能读懂的答案。
06**多端呈现与归档**:网页展示工具卡片,终端打印结果,QQ 转成适合聊天的文本;会话按入口归档到本地。
这里的关键是“查询逻辑不藏在提示词里”。学期、单双周、调休、课程冲突等容易出错的规则尽量前置到 TypeScript 工具层,模型不需要重新发明一遍。
05
SCHOOL ADAPTER
### 五、学校适配层:把通用 Agent 和私有协议隔开

— CourseRaptor 项目架构图
项目用 SchoolAdapter 作为学校能力端口。核心层不直接依赖南京工业大学的网页字段,而是消费统一的课程、成绩、考试、通知和学期模型。
南京工业大学适配器再负责具体细节:
01正方新版教务系统的 RSA + CSRF 登录流程。
02课表、考试、成绩、通知、选课和 WebVPN 请求。
03南工大节次时间、学期编码、绩点规则和通识选修类别。
04校历日期、当前教学周、放假与调休覆盖。
这种边界让“新增一所学校”不必改写整个 Agent 内核。理想情况下,只需新增一份适配器,实现学校协议和规则,再把工具贡献给 Agent。
但这并不意味着已经是多校平台:当前仓库实际只适配南京工业大学,其他学校需要自己实现适配层,不能直接套用 NJTECH 逻辑。
06
LOCAL-FIRST
### 六、本地优先不等于完全断网
CourseRaptor 的隐私叙事很清楚:会话、记忆、知识库、凭证和缓存都落在本机;但实时查询教务系统、调用 DeepSeek 和获取天气仍然需要外部网络。
项目的“本地优先”更准确地说是:**数据和控制面在本机,外部服务只在业务需要时被调用**。
01本地 Web 只监听 127.0.0.1,不默认暴露到局域网。
02网页请求有 Host、Origin 和 CSRF 三道检查,防 DNS rebinding 和跨站写请求。
03教务查询直连学校系统,附件解析在本地完成。
04天气使用 Open-Meteo,无需额外密钥。
05DeepSeek Key 由用户自己提供,正式对话消耗用户自己的额度。
因此,用户得到的是“本地 Agent + 按需外部调用”,而不是一个把所有数据上传到 SaaS 后台的校园聊天产品。
07
CREDENTIALS
### 七、凭证保护:AES-256-GCM 解决了什么,没解决什么
项目把教务账号、密码、DeepSeek Key、QQ 机器人凭证和模型选择等信息写入 credentials.enc,使用 AES-256-GCM 加密,并通过“主机名 + 系统用户名 + 项目标识”派生本机密钥。
它解决了几类常见问题:
01凭证不会以明文 JSON 直接落盘。
02误把 credentials.enc 复制到另一台机器时,通常无法解密。
03加密文件写入采用同目录临时文件再原子替换,减少中断造成半截 JSON 的风险。
04发生损坏或无法解密时,旧文件会先隔离留档,而不是静默覆盖。
它也有清晰边界:本机恶意程序、同一用户下的恶意进程和已经获得运行权限的程序,不能靠“本机派生密钥”解决。凭证保护是降低误分享和误同步风险,不是完整的操作系统级密钥管理器。
08
OFFLINE DEMO
### 八、离线演示为什么是产品能力,不只是 Demo
离线演示通过 npm run demo 启动,固定使用虚构课表、成绩、待办、知识库和通知数据:不读取 credentials.enc,不连接教务系统,不调用 DeepSeek,也不把对话落盘。
我在本轮验证中实际启动了演示服务,服务监听 127.0.0.1:3211;/api/today 能返回虚构课程和教学周数据,知识库页面也能正常提供页面响应。它的价值是让用户先验证交互与产品形态,再决定是否配置真实账号和 API Key。

— CourseRaptor 离线演示界面,内容为虚构演示数据
真实模型演示另有 npm run demo:live,会使用虚构工具数据但调用 DeepSeek,因此会消耗 API 用量。这个“离线剧本—真实模型—真实教务”三层模式,降低了首次体验的门槛,也避免为了看界面而交出真实凭证。
09
HEADLESS CLI
### 九、无头 CLI:把 Agent 能力拆成可自动化接口
并不是所有查询都需要大模型。skills/njtech-jwgl/ 将课表、成绩、考试、通知、学籍、课程搜索等操作封装成命令行脚本:
CODE
npx tsx skills/njtech-jwgl/scripts/query.ts schedule
npx tsx skills/njtech-jwgl/scripts/query.ts grades
npx tsx skills/njtech-jwgl/scripts/query.ts news 公告通知 5
无头路径有三个实际好处:
01不经过 LLM,不消耗 DeepSeek Token。
02结果更适合脚本、定时任务和其他 Agent 继续处理。
03将“自然语言理解”和“确定性数据查询”拆开,方便测试与审计。
这也是 CourseRaptor 从个人工具走向工具链的信号:聊天 Agent 负责开放式交互,CLI 负责稳定协议,两者共享学校适配器。
10
WRITE SAFETY
### 十、写操作为什么要单独设门槛
查询和写入不是一个风险等级。
课表、成绩和通知通常是读取;选课、抢课、退课则会改变真实教务状态。项目默认不会把这些写工具全部暴露出来,抢课相关工具根据配置动态装配;即使启用,也要求交互式操作和本人二次确认。
这是一条正确的 Agent 边界:
01只读工具可以更自动化。
02课程冲突对比可以先给建议,但不直接提交选课。
03真实写操作必须把目标、课程、账号和最终动作交给用户确认。
04请求还有全局限速,避免高频访问冲击教务系统。
Agent 的“自主性”不应该通过绕过确认获得,而应该通过更好的信息整理和更少的重复操作获得。
11
LIMITATIONS
### 十一、当前项目的真实边界
CourseRaptor 很适合展示本地校园 Agent 的完整落地路径,但仍有几条边界需要放在标题之外讲清楚:
01当前只适配南京工业大学,不是开箱即用的多校产品。
02正式对话需要用户自己的 DeepSeek API Key,工具调用与离线功能不等于模型免费。
03教务官网、WebVPN、验证码和页面结构变化,都可能影响实时查询。
04“全本地”指数据和运行控制面本地化,不代表完全离线访问真实教务系统。
05便携版安装包未做代码签名,Windows SmartScreen 可能弹出提示。
06选课等写操作具有真实风险,不能交给无确认的自动化脚本。
项目当前的价值,更像是一份可运行的本地 Agent 工程样本,而不是已经解决所有学校适配和生产运维问题的商业产品。
12
LESSONS
### 十二、它对校园 Agent 设计有什么启发
第一,**工具数量不是重点,工具边界才是重点**。31 个工具如果没有明确的数据模型、失败语义和权限门槛,只会把复杂度从菜单转移到模型上下文。
第二,**学校差异必须隔离在适配层**。教务协议、学期规则、绩点算法和节次时间不是 Prompt,应该由代码和测试承载。
第三,**本地状态要分层**。会话、长期记忆、知识库、待办和凭证各自有不同的生命周期与敏感级别,不能全部塞进一个 memory.json。
第四,**离线演示是信任入口**。用户可以先看到系统怎么工作,再决定是否提交自己的教务账号,这比一上来要求配置凭证更容易建立信任。
∞
EPILOGUE
### 十三、结语:本地校园 Agent 的难点是责任边界
CourseRaptor 已经把一个校园 Agent 的关键骨架搭出来了:统一 Agent 内核、31 个工具、三端入口、无头 CLI、本地记忆、本地凭证、学校适配器和离线演示。
它最值得关注的地方,不是把“查课表”说得多聪明,而是把一件真实、敏感、带写操作风险的校园事务,拆成了可以审计、可以测试、可以逐步扩展的工程边界。
未来如果继续推进,最有价值的方向可能不是再堆几个工具,而是把学校适配器标准化、把自然语言查询链路做成可复现实测、把凭证存储升级为平台原生密钥环,并为每个真实写操作建立更强的确认和回滚语义。
声明:本文由山行整理自:Health-525/CourseRaptor( issue(
我是山行 AI,持续分享 AI 工具、Agent 工作流与开源项目观察。
如果你觉得今天这篇有收获,欢迎点赞、在看、转发三连,我们下篇见。
[跳转微信打开](https://wechat2rss.bestblogs.dev/link-proxy/?k=d1c22c48&r=1&u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU2NzkxNDY0Ng%3D%3D%26mid%3D2247491133%26idx%3D1%26sn%3D7e4337fbf2b203547509825ebb5eb8ae)