# Lantai **Repository Path**: sumht/lantai ## Basic Information - **Project Name**: Lantai - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-15 - **Last Updated**: 2026-06-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 兰台 Lantai > **面向 AI Agent 的团队知识管理平台** · Team Knowledge Management Platform for AI Agents 兰台用 Java/Spring Boot 重新实现了 ByteDance OpenViking 的核心思路,为 AI 编码助手(Claude Code / Cursor / Trae / Codex 等)提供**长期记忆存储、会话与消息追踪、项目规则管理**,以及一套开箱即用的 Web 管理界面。 它的核心定位是**记忆与规则的中枢**:Agent 在不同会话、不同项目里产生的知识与约定,统一沉淀在这里;下一次会话启动时,再由平台把相关上下文注入回 Agent。平台的存储、召回、注入**不依赖任何运行时 LLM**——记忆是结构化入库 + MySQL 全文检索,规则是版本化的 Markdown,全部确定、可审计、可复现。此外提供一个**可选的 LLM 记忆抽取**能力(配置 DeepSeek 后,可从历史会话中抽取候选记忆供人工审核入库)。 --- ## ✨ 特性 - **🧠 10 类结构化记忆** + 字段级合并引擎(REPLACE / IMMUTABLE / SUM / PATCH),知识不会无脑覆盖 - **🔍 双列全文检索**:`content` + `abstract` 加权打分,叠加使用频率权重,中英文友好(ngram 分词) - **📜 版本化规则系统**:`draft → published → archived` 生命周期,项目级与用户级两层分配,用户级覆盖项目级 - **💬 会话生命周期追踪**:基于单调递增 `seqNum` 的增量上报、断点续传、token 聚合统计 - **🔌 双接入通道**:Claude Code Hooks(push / 自动注入)+ MCP Server(pull / 按需调用),共用同一套 API Key 认证 - **🛡️ 内容脱敏**:上报消息时自动剥离注入的 XML 标签,防止注入内容被当作记忆二次提取 - **🖥️ 单 JAR Web 管理台**:Vite + Vue 3 + TypeScript SPA,构建产物并入 Spring Boot 静态资源,单 JAR 部署 - **🤖 可选记忆抽取**:配置 DeepSeek 后,可从会话历史中抽取候选记忆,前端审核确认后入库 --- ## 🏗️ 架构总览 兰台为 Agent 提供**两条互补的接入通道**,写入的数据落在同一批表中: ``` ┌─────────────────────────────────────────────┐ │ AI Agent / Coding Tool │ │ (Claude Code · Cursor · Trae · Codex …) │ └──────────┬──────────────────────┬────────────┘ │ │ ① Push / 自动注入 │ │ ② Pull / 按需调用 (Claude Code Hooks) │ │ (MCP over SSE) ▼ ▼ ┌──────────────────────────┐ ┌──────────────────────────┐ │ HookController │ │ MCP Server (9 tools) │ │ /api/v1/hooks/* │ │ /sse + /mcp/message │ │ session/start │ │ ping / search_rules … │ │ memories/search │ │ remember / start_session│ │ session/messages │ │ add_message / end_session│ │ session/end │ │ │ └────────────┬─────────────┘ └──────────────┬───────────┘ │ API Key (X-API-Key) │ ▼ ▼ ┌──────────────────────────────────────────────────────┐ │ Domain Services │ │ session · memory · rule · project · user · hook │ │ memory/engine (MergeEngine · TypeRegistry) │ └────────────────────────┬─────────────────────────────┘ ▼ MySQL 8.0 · 11 张表 · Flyway ``` - **Hooks 通道(push)**:Claude Code 在会话的 4 个生命周期阶段(SessionStart / UserPromptSubmit / Stop / SessionEnd)回调兰台,兰台把**用户画像 + 规则 + 相关记忆**以 XML 注入回对话。 - **MCP 通道(pull)**:任意 MCP 客户端用同一把 API Key 连接 SSE,按需调用 9 个工具读写记忆 / 会话 / 规则。 --- ## 🧠 核心能力 ### 记忆系统 10 种记忆类型,统一存于 `ov_memory` 单表,由 `MemoryTypeRegistry` 定义各自的字段与合并策略: | # | 类型 | 模式 | 面向 | 说明 | |---|------|------|------|------| | 1 | `profile` | upsert | 用户 | 用户画像,每用户一条 | | 2 | `preferences` | upsert | 用户 | 用户偏好,按 topic 区分 | | 3 | `entities` | upsert | 用户 | 知识实体,Wiki 风格 | | 4 | `events` | add_only | 用户 | 事件记录,只追加 | | 5 | `identity` | upsert | 用户 | Agent 身份定义 | | 6 | `soul` | upsert | 用户 | Agent 核心真相 | | 7 | `experiences` | upsert | Agent | 执行经验 | | 8 | `trajectories` | add_only | Agent | 操作轨迹,带时间戳 | | 9 | `skills` | upsert | Agent | 技能 + 执行统计 | | 10 | `tools` | upsert | Agent | 工具 + 调用统计 | 每条记忆由 `(userId, memoryType, uriPath)` 唯一标识。写入时 **MergeEngine** 按字段级策略合并:`REPLACE`(覆盖)、`IMMUTABLE`(只首次写)、`SUM`(计数累加)、`PATCH`(段落级去重追加)。 记忆之间通过 `ov_memory_link` 的有向边组成知识图谱,支持 6 种关系(related_to / belongs_to / caused_by / derived_from / contradicts / evolved_from),可双向 BFS 遍历(最大 3 层)。 ### 规则系统 规则是版本化的 Markdown,生命周期 `draft → published → archived`,**只有 `published` 状态参与召回**。两层分配: - **项目级**(`ov_project_rule`):把规则绑定到项目,多对多; - **用户级**(`ov_user_recall_rule`):用户级覆盖,合并时**用户级优先、按 ruleId 去重**。 ### 会话追踪 基于 `seqNum` 单调递增 + `SessionCapture.lastSeqNum` 水位线实现**增量上报与断点续传**;每条消息记录 `promptTokens` / `completionTokens` 并在 Session 级聚合;上报时 `sanitizeContent()` 剥离注入的 `` / `` XML,防止污染。 ### 记忆抽取(可选 · LLM) 配置 DeepSeek 后,可在 Web 界面对某个历史会话触发**记忆抽取**:调用 DeepSeek 分析会话消息 → 返回候选记忆 → 用户在前端审核(`memory-extract-review` 页面)→ 确认后写入知识库。会话用 `memory_extracted` 标记避免重复抽取。**未配置 DeepSeek 时此功能自动不可用,不影响其余任何能力。** --- ## 🛠️ 技术栈 | 层 | 技术 | |----|------| | 后端 | Spring Boot 3.3.6 · Java 17 · MyBatis Plus 3.5.7 | | 数据库 | MySQL 8.0+ · Flyway 自动迁移 | | 认证 | Spring Security + JWT(jjwt 0.12.6)+ API Key | | 接口文档 | SpringDoc OpenAPI(Swagger UI:`/swagger-ui.html`) | | MCP | Spring AI 1.0.0 MCP Server(SSE 传输:`/sse` + `/mcp/message`) | | 前端 | Vite 5 · Vue 3.5 · TypeScript · Pinia · Element Plus 2.9(按需)· Vue Router 4(hash)· Axios · md-editor-v3 | --- ## 🚀 快速开始 ### 前置条件 - **JDK 17+** - **Maven 3.8+** - **MySQL 8.0+**(默认连接 `db.basic:3306/lantai`,可在 `application.yml` 修改为 `localhost` 等) > `db.basic` 是仓库默认配置里的内网域名,本机开发请改成你可达的 MySQL 地址。库 `lantai` 需提前创建(空库即可,Flyway 会在启动时自动建表并写入种子数据)。 ### 1. 准备数据库 ```sql CREATE DATABASE lantai DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ``` ### 2. 编译 & 运行 ```bash # 编译 mvn compile # 启动(Flyway 自动建表) mvn spring-boot:run ``` 启动成功后(后端端口 `48066`): - **Web 管理台**: - **Swagger UI**: - **MCP SSE 端点**: ### 3. 前端 前端是独立的 Vite 工程(`frontend/`)。开发:`cd frontend && npm install && npm run dev`(默认 5173,proxy 到后端 48066,享 HMR)。生产构建:`cd frontend && npm run build`,产物写入 `src/main/resources/static/`,随 Spring Boot 单 JAR 部署。 ### 4. 打包 ```bash mvn package -DskipTests # 产物:target/lantai-1.0.0-SNAPSHOT.jar(单 JAR 含前端静态资源) ``` --- ## 📁 项目结构 ``` Lantai/ ├── src/main/java/com/lantai/ │ ├── LantaiApplication.java # 入口 │ ├── hook/ # Claude Code Hooks 端点 + 上下文注入 │ ├── mcp/ # MCP Server(9 工具,SSE) │ ├── session/ # 会话 / 消息 / 捕获水位线 │ ├── memory/ # 记忆 CRUD + 全文检索 + 图谱 │ │ └── engine/ # MergeEngine / MemoryTypeRegistry │ ├── rule/ # 规则(版本/生命周期)+ 用户召回规则 │ ├── project/ # 项目 + 项目规则分配(short_code 路由) │ ├── user/ # 用户 + 用户召回规则分配 │ ├── extraction/ # (可选)DeepSeek 记忆抽取 │ ├── auth/ # 登录 / JWT 刷新 / API Key CRUD │ ├── security/ # JwtAuthFilter / ApiKeyAuthFilter / SecurityConfig │ ├── team/ # 团队(单组织) │ ├── config/ # CORS / Jackson / MyBatis / 异步配置 │ └── common/ # BaseEntity / ApiResponse / PageResponse / 枚举 ├── src/main/resources/ │ ├── application.yml # DB / JWT / API Key / DeepSeek 配置 │ ├── db/migration/V1..V16.sql # Flyway 迁移 │ └── static/ # 前端构建产物(Vite build 输出,勿手改) ├── frontend/ # 前端 Vite 工程(Vue 3 + TS + Pinia + Element Plus) │ ├── src/ # api / stores / router / constants / layouts / views │ └── vite.config.ts # outDir → static,dev proxy → 48066 ├── .claude/ │ ├── hooks/lantai-hooks/*.mjs # Claude Code Hooks 客户端脚本 │ └── lantai.json # Hooks 连接配置(serverUrl / apiKey / project) └── docs/ # 设计图、参考、cheatsheet ``` ### 后端约定 - **所有响应**统一用 `ApiResponse`(`{code, message, data}`)包裹 - **所有实体**继承 `BaseEntity`(`id` 自增 + `createdAt` / `updatedAt` 自动填充) - **Mapper** 为纯 MyBatis Plus `BaseMapper` 接口(无 XML) - **DTO** 使用 Java records - **Service** 直接注入具体类(无接口层) - **REST** 路径统一在 `/api/v1/` 下;Hooks 在 `/api/v1/hooks/` --- ## ⚙️ 配置(`application.yml` 摘要) ```yaml spring: datasource: url: jdbc:mysql://db.basic:3306/lantai?... # 改成你的 MySQL 地址 username: root password: root flyway: enabled: true # 启动自动建表 jwt: access-token-expiration: 86400000 # 24h refresh-token-expiration: 604800000 # 7d apikey: prefix: "lt_" # API Key 前缀(可配) length: 32 deepseek: # 可选:记忆抽取功能 api-key: "" # 留空则抽取功能不可用 ``` --- ## 🔌 接入 AI Agent ### 方式一:Claude Code Hooks(push / 自动注入) 1. 在 Web 界面创建用户并获得 API Key(`X-API-Key`,默认 `lt_` 前缀,明文精确匹配认证)。 2. 把 `.claude/hooks/lantai-hooks/` 挂到 Claude Code 的 hooks 配置,并填写 `.claude/lantai.json`: ```json { "serverUrl": "http://localhost:8080", "apiKey": "lt_xxx", "project": "" } ``` 3. 会话生命周期回调: | Hook 事件 | 端点 | 作用 | |-----------|------|------| | SessionStart | `POST /api/v1/hooks/session/start` | 注入 ``(用户画像 + 规则) | | UserPromptSubmit | `POST /api/v1/hooks/memories/search` | 注入 ``(两阶段召回) | | Stop | `POST /api/v1/hooks/session/messages` | 增量上报消息 | | SessionEnd | `POST /api/v1/hooks/session/end` | 关闭会话 + flush 剩余消息 | ### 方式二:MCP(pull / 按需调用,SSE 传输) 任意 MCP 客户端用同一把 API Key 连接: ```bash claude mcp add --transport sse lantai http://localhost:8080/sse \ --header "X-API-Key: lt_xxx" ``` 提供 9 个工具(snake_case):`ping`;读类 `search_rules` / `get_rule` / `search_memories` / `get_memory`;写 / 会话类 `remember` / `start_session` / `add_message` / `end_session`。写入落到与 Hooks 相同的表。 > 完整工具表与传输细节见 `docs/recall-cheatsheet.md` §13。 --- ## 📝 开发工作流 本项目用 **OpenSpec** 做变更管理,并要求"涉及业务逻辑/需求变更先设计 → 落档 → 实现再动手"。完整纪律(复杂度信号、OpenSpec change 流程、验证闸门)见 [`CLAUDE.md`](./CLAUDE.md)。 - 设计/计划/任务统一记录在 `openspec/changes//`(`proposal.md` / `design.md` / `specs/*/spec.md` / `tasks.md`),完成后由 `/opsx:archive` 归档到 `openspec/changes/archive/`。 - 本项目**未配置测试框架**,验证循环为:`mvn compile` → `mvn spring-boot:run` → 接口/手动验证(Swagger / curl)→ commit。 --- ## 📄 文档索引(`docs/`) - `project-logic.md` — 项目逻辑全景(架构图、记忆/规则/会话细节、数据流转) - `recall-cheatsheet.md` — 召回速查(含 MCP 工具表、传输细节) - `recall-architecture.svg` / `recall-lifecycle.drawio` — 召回架构与生命周期图 - `design-recall-injection-optimization.md` / `recall-diagrams.md` — 注入优化设计 - `claude-code-hooks-reference.md` — Claude Code Hooks 参考资料 > 注:部分 `docs/` 文档写于多租户改造之前,其中"多租户 / team_id / `ov_audit_log` / 旧前端 `lantai-ui`"等描述已过时(见 `V14__remove_team_id.sql`)。以本 README 与代码为准。 --- ## 🙏 致谢 ClaudeCode+GLM ## License 本项目当前未声明开源许可证,默认保留所有权利。