持久记忆AI学术顾问

一个生产级的AI学术顾问,通过MCP架构实现跨对话的长期记忆和语义检索,支持学生偏好、历史对话和学术里程碑的持久化存储与上下文感知交互。

  • by Rushikesh-5706
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 Rushikesh-5706/Persistent-Memory-AI-Academic-Advisor-with-an-MCP-Server-and-Vector-Search

使用说明

带有MCP服务器和矢量搜索的持久内存AI学术顾问

一个生产级的人工智能学术顾问,保持长期、情境感知的记忆 在对话中。系统将语言模型与其存储层分离 使用内存、控制和进程(MCP)架构模式,实现 顾问回忆学生的偏好、过去的对话和学术里程碑 超越任何单一上下文窗口的约束。


建筑

该系统由三个主要层组成:

层 技术 责任
Agent Python+Ollama(llama3) 会话界面,工具编排
MCP服务器 FastAPI+Uvicorn 内存工具API,请求路由,验证
关系存储 SQLite+SQLAlchemy 结构化内存:对话、偏好、里程碑
矢量存储 ChromaDB+句子变换器 语义记忆:基于相似性的上下文检索

数据流:

  1. 用户向代理发送消息。
  2. 代理人打电话来 memory_retrieve_by_context 以获取语义相关的过去记忆。
  3. 代理人打电话来 memory_read 获取最近的谈话内容。
  4. 两者都作为上下文注入到提示符中。
  5. LLM生成响应。
  6. 代理人打电话来 memory_write 坚持SQLite和ChromaDB的新转变。

先决条件

  • 已安装Docker和Docker Compose
  • Ollama已安装并在您的主机上运行,llama3型号已拔出

要安装Ollama并拉动模型:

# Install Ollama (Linux)
curl -fsSL https://ollama.com/install.sh | sh

# Pull the llama3 model
ollama pull llama3

设置和运行

1.克隆存储库

git clone https://github.com/Rushikesh-5706/Persistent-Memory-AI-Academic-Advisor-with-an-MCP-Server-and-Vector-Search.git
cd Persistent-Memory-AI-Academic-Advisor-with-an-MCP-Server-and-Vector-Search

2.配置环境变量

环境变量在中内联设置 docker-compose.yml 和工作出 框,无需更改。这 .env.example 归档所有可用文档 变量以供参考。

如果要覆盖任何值,请打开 docker-compose.yml 并编辑 environment: 块下 mcp_server 服务。对于代理,请复制 示例文件并对其进行编辑:

cp .env.example .env

3.启动MCP服务器

docker-compose up --build

等待健康检查通过。当您看到以下内容时,服务器已准备就绪: mcp_server | INFO: Application startup complete.

4.运行代理(可选,用于交互式使用)

在单独的终端中:

cd agent
pip install -r requirements.txt
python agent.py

API 参考

所有端点均由 http://localhost:8000.

健康检查

GET /health

答复:

{"status": "ok"}

列出工具

GET /tools

返回所有可用内存工具及其说明的列表。

写存储器

POST /invoke/memory_write

请求正文:

{
  "memory_type": "conversation",
  "data": {
    "user_id": "student_001",
    "turn_id": 1,
    "role": "user",
    "content": "I want to major in bioinformatics."
  }
}

支持 memory_type 值: conversation, preference, milestone

答复(201):

{"status": "success", "memory_id": "conv_student_001_1"}

读存储器

POST /invoke/memory_read

请求正文:

{
  "user_id": "student_001",
  "query_type": "last_n_turns",
  "params": {"n": 5}
}

支持 query_type 值: last_n_turns, preferences, milestones

按上下文检索

POST /invoke/memory_retrieve_by_context

请求正文:

{
  "user_id": "student_001",
  "query_text": "What subjects does this student find interesting?",
  "top_k": 3
}

返回语义相似的存储记忆及其相关性得分。


项目结构

.
├── docker-compose.yml          orchestrates the mcp_server service
├── Dockerfile                  builds the mcp_server image
├── .env.example                documents all required environment variables
├── submission.json             test data for automated evaluation
├── docs/
│   └── memory_architecture.png system architecture diagram
├── mcp_server/
│   ├── main.py                 FastAPI application, route handlers
│   ├── database.py             SQLAlchemy models, session management, CRUD operations
│   ├── memory_schemas.py       Pydantic v2 request/response schemas
│   ├── vector_store.py         ChromaDB client, embedding generation, similarity search
│   ├── tools.py                Tool registry and execution logic
│   └── requirements.txt        Python dependencies
└── agent/
    ├── agent.py                Ollama-powered conversational agent
    └── requirements.txt        Agent dependencies

内存架构参考

架构 字段
对话 user_id、turn_id、角色、内容、时间戳
UserPreferences user_id,首选项(JSON字典)
里程碑 用户id、里程碑id、描述、状态、完成日期

设计决策

为什么选择SQLite来处理结构化数据? SQLite不需要单独的服务器进程,持久化为挂载的单个文件卷 并处理学术顾问预期的交易量 无争议的工作负载。SQLAlchemy为ORM层提供了完整的迁移 如果需要更强大的数据库,则提供支持。

为什么选择ChromaDB进行矢量搜索? ChromaDB以嵌入式模式运行,具有基于文件的持久性,与 该项目的部署模型。它原生支持余弦相似性 与句子转换器无缝集成,无需单独的服务。

为什么所有MiniLM-L6-v2都用于嵌入? 该模型在CPU上高效运行,产生384维嵌入,平衡 具有存储和计算成本的语义质量,并且在英语方面经过了很好的测试 句子级相似性任务——正是这里使用的检索模式。

当代作家 对话表和里程碑表都对以下内容实施了独特的约束 分别为(user_id、turn_id)和(user_id,milestone_id)。写入功能 执行追加销售操作,因此处理重复写入时不会出错或 重复记录。


故障排除

MCP服务器无法启动 检查一下 ./data 目录是可写的。容器写入SQLite 数据库和ChromaDB文件。跑 mkdir -p data && chmod 777 data 如果需要的话。

特工拒绝与Ollama建立联系 确保Ollama在您的主机上运行 ollama serve 而且 OLLAMA_BASE_URL 在 .env 比赛。在Linux上, http://localhost:11434 作品 直接。在带有Docker Desktop的macOS或Windows上,使用 http://host.docker.internal:11434.

语义搜索返回空结果 按以下方式筛选集合 user_id.确保 user_id 在检索请求中 与写入操作期间使用的一致。