基于 AgentScope 的虚拟 AI 女友 Agent 系统
Mori 是一个基于 AgentScope 框架构建的虚拟 AI 女友 Agent 系统。项目充分利用 AgentScope 已有的功能(Model、Agent、Tool、Memory 等),专注于业务逻辑和用户体验的实现。
- 情感陪伴需求:为用户提供温暖、贴心的虚拟陪伴体验
- 个性化交互:通过长期记忆功能记住用户偏好,实现个性化对话
- 灵活扩展:支持多 Agent 协作架构,可根据需求扩展功能
- 温柔体贴的人设:Mori 具有温柔、善解人意、幽默风趣的性格特点
- 持久记忆能力:能够记住用户的偏好、习惯和重要信息
- 多模型支持:支持 OpenAI、通义千问、DeepSeek、Ollama 等多种 LLM
- 易于定制:通过 Jinja2 模板系统轻松定制 Agent 人设和行为
- 🤖 多 Agent 架构:支持主 Agent 与子 Agent 协作,子 Agent 自动注册为主 Agent 的工具
- 🧠 长期记忆:基于 Mem0 实现,支持跨会话记忆用户偏好和重要信息
- 💬 流式对话:支持流式输出,提供更自然的对话体验
- 🔧 工具调用:支持自定义工具和并行工具调用
- 🌐 MCP 协议:预留 Model Context Protocol 集成接口
| 模型类型 | 提供商 | 说明 |
|---|---|---|
| OpenAI | OpenAI | GPT-4、GPT-3.5-Turbo 等 |
| DashScope | 阿里云 | 通义千问系列 |
| DeepSeek | DeepSeek | DeepSeek-Chat 等 |
| Ollama | 本地 | Llama3、Qwen 等本地模型 |
| Gemini | Gemini 系列 |
- DashScope (text-embedding-v2/v3)
- OpenAI (text-embedding-3-small/large)
- Gemini (text-embedding-004)
- Ollama (nomic-embed-text, mxbai-embed-large)
| 类别 | 技术 | 版本 | |------|------| | 核心框架 | AgentScope | 1.0.8+ | | 模板引擎 | Jinja2 | 3.1.0+ | | 配置验证 | Pydantic | 2.0+ | | GUI 框架 | Gradio | 4.0.0+ | | 长期记忆 | Mem0AI | 0.1.0+ | | HTTP 客户端 | httpx | 0.25.0+ | | 依赖管理 | uv | - | | 代码规范 | black, ruff, pre-commit | - | | Python | Python | 3.10+ |
- Python 3.10 或更高版本
- uv 包管理器
- 一个 LLM API 密钥(OpenAI、DeepSeek、通义千问等)
git clone https://github.com/acgurl/mori.git
cd mori# 创建虚拟环境
uv venv
# 激活虚拟环境
# Windows PowerShell:
.venv\Scripts\activate
# Linux/Mac:
source .venv/bin/activate
# 安装项目依赖
uv pip install -e .
# 安装开发依赖(可选)
uv pip install -e ".[dev]"# Windows PowerShell:
Copy-Item config\models.yaml.example config\models.yaml
Copy-Item config\agents.yaml.example config\agents.yaml
Copy-Item config\config.yaml.example config\config.yaml
# Linux/Mac:
cp config/models.yaml.example config/models.yaml
cp config/agents.yaml.example config/agents.yaml
cp config/config.yaml.example config/config.yaml# Windows PowerShell:
$env:OPENAI_API_KEY="your-api-key-here"
# Linux/Mac:
export OPENAI_API_KEY="your-api-key-here"python gui/app.py然后在浏览器中访问: http://localhost:7860
config/
├── models.yaml # 模型配置
├── agents.yaml # Agent 配置
├── config.yaml # 全局配置
├── mcp.json # MCP 配置(可选)
└── template/ # 自定义模板目录
└── custom.jinja2 # 自定义提示词模板
models:
# OpenAI 配置
main_gpt4:
model_name: gpt-4
model_type: openai
api_key: ${OPENAI_API_KEY} # 从环境变量读取
generate_kwargs:
temperature: 0.7
max_tokens: 2000
# DeepSeek 配置(OpenAI 兼容接口)
deepseek_chat:
model_name: deepseek-chat
model_type: openai
api_key: ${DEEPSEEK_API_KEY}
base_url: https://api.deepseek.com/v1
generate_kwargs:
temperature: 0.7
# 通义千问配置
qwen_max:
model_name: qwen-max
model_type: dashscope
api_key: ${DASHSCOPE_API_KEY}
# Ollama 本地模型
local_llama3:
model_name: llama3
model_type: ollama
base_url: http://localhost:11434
# 嵌入模型配置(用于长期记忆)
embedding_models:
dashscope_embedding:
model_name: text-embedding-v2
model_type: dashscope
api_key: ${DASHSCOPE_API_KEY}# 指定主 Agent
primary_agent: mori
agents:
# 主 Agent - 虚拟 AI 女友
mori:
model: main_gpt4 # 引用 models.yaml 中的配置
template: mori # 模板名称
parallel_tool_calls: true
memory_config:
type: memory
max_length: 100
# 长期记忆配置
long_term_memory:
enabled: true
mode: "agent_control" # agent_control / static_control / both
user_name: "user"
embedding_model: "dashscope_embedding"
storage_path: "data/memory/mori"
on_disk: trueglobal:
log_level: INFO
log_dir: logs
server:
host: 127.0.0.1
port: 7860
share: false| 变量名 | 说明 |
|---|---|
OPENAI_API_KEY |
OpenAI API 密钥 |
DASHSCOPE_API_KEY |
阿里云 DashScope API 密钥 |
DEEPSEEK_API_KEY |
DeepSeek API 密钥 |
GEMINI_API_KEY |
Google Gemini API 密钥 |
mori/
├── mori/ # 核心模块
│ ├── __init__.py
│ ├── mori.py # Mori 核心封装类
│ ├── config.py # 配置加载和验证
│ ├── exceptions.py # 自定义异常
│ │
│ ├── agent/ # Agent 相关
│ │ ├── factory.py # Agent 工厂
│ │ └── manager.py # Agent 管理器
│ │
│ ├── model/ # 模型相关
│ │ └── factory.py # 模型工厂
│ │
│ ├── memory/ # 记忆相关
│ │ └── factory.py # 记忆工厂
│ │
│ ├── template/ # 模板系统
│ │ ├── loader.py # 模板加载器
│ │ ├── service.py # 模板服务
│ │ └── internal_template/ # 内置模板
│ │ └── mori.jinja2 # Mori 提示词模板
│ │
│ ├── tool/ # 工具系统
│ │ ├── factory.py # 工具工厂
│ │ ├── agent_tools.py # Agent 工具
│ │ └── internal_tools/ # 内置工具
│ │ └── example_tools.py # 示例工具
│ │
│ ├── mcp/ # MCP 集成(预留)
│ │ └── README.md
│ │
│ └── utils/ # 工具函数
│ ├── model_wrapper.py # 模型包装器
│ └── response.py # 响应处理
│
├── gui/ # GUI 界面
│ └── app.py # Gradio 应用
│
├── logger/ # 日志系统
│ └── config.py # 日志配置
│
├── config/ # 配置文件
│ ├── models.yaml.example # 模型配置示例
│ ├── agents.yaml.example # Agent 配置示例
│ ├── config.yaml.example # 全局配置示例
│ └── template/ # 自定义模板目录
│
├── tests/ # 测试
│ ├── test_config.py
│ ├── test_template.py
│ └── ...
│
├── docs/ # 文档
│ ├── ARCHITECTURE.md # 架构设计
│ ├── QUICKSTART.md # 快速开始
│ ├── LONG_TERM_MEMORY.md # 长期记忆指南
│ └── ...
│
├── pyproject.toml # 项目配置
├── .pre-commit-config.yaml # pre-commit 配置
├── LICENSE # MIT 许可证
└── README.md # 项目说明
import asyncio
from mori.mori import Mori
async def main():
# 初始化 Mori
mori = Mori(config_dir="config")
# 发送消息
response = await mori.chat("你好,今天过得怎么样?")
print(response)
# 继续对话
response = await mori.chat("我今天工作有点累")
print(response)
# 重置对话历史
await mori.reset()
if __name__ == "__main__":
asyncio.run(main())import asyncio
from mori.mori import Mori
async def memory_example():
mori = Mori(config_dir="config")
# 分享偏好(Agent 会自动记录)
response = await mori.chat("我喜欢喝拿铁咖啡")
print(response)
# 清空短期记忆(模拟新会话)
await mori.reset()
# 询问偏好(Agent 会从长期记忆检索)
response = await mori.chat("我喜欢喝什么咖啡?")
print(response)
asyncio.run(memory_example())import asyncio
from mori.mori import Mori
async def multi_agent_example():
mori = Mori(config_dir="config")
# 主 Agent 会根据任务自动调用子 Agent
response = await mori.chat("帮我写一首关于春天的诗")
print(response)
# 查看可用的 Agent
print(f"可用 Agents: {mori.list_agents()}")
print(f"主 Agent: {mori.get_primary_agent_name()}")
asyncio.run(multi_agent_example())在 config/template/ 目录下创建自定义模板:
{# config/template/custom.jinja2 #}
你是一个专业的技术助手。
## 当前信息
{% if current_time %}
- **当前时间**: {{ current_time }}
{% endif %}
## 你的职责
- 回答技术问题
- 提供代码示例
- 解释技术概念
请用专业、清晰的语言回答用户的问题。然后在 agents.yaml 中引用:
agents:
tech_assistant:
model: main_gpt4
template: custom # 使用自定义模板uv pip install -e ".[dev]"
pre-commit install# 运行所有测试
pytest tests/
# 运行特定测试
pytest tests/test_config.py
# 带详细输出
pytest tests/ -v# 运行所有检查
pre-commit run --all-files
# 格式化代码
black .
# 检查代码风格
ruff check .在 mori/tool/internal_tools/ 中创建新工具:
from agentscope.tool import ToolResponse
from agentscope.message import TextBlock
async def my_custom_tool(param: str) -> ToolResponse:
"""我的自定义工具
Args:
param: 参数说明
Returns:
ToolResponse: 工具响应
"""
result = f"处理结果: {param}"
return ToolResponse(
content=[TextBlock(type="text", text=result)]
)
# 注册工具
def register_tools(toolkit):
toolkit.register_tool_function(my_custom_tool)我们欢迎所有形式的贡献!
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 创建 Pull Request
- 遵循现有的代码风格(使用 black 和 ruff)
- 为新功能添加测试
- 更新相关文档
- 提交信息清晰明了
如果你发现了 bug 或有功能建议,请在 GitHub Issues 中提交。
本项目采用 MIT 许可证。
MIT License
Copyright (c) 2025 ACGURL
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
- 项目仓库: https://github.com/acgurl/mori
- 问题反馈: GitHub Issues
- AgentScope: https://github.com/modelscope/agentscope
- AgentScope 文档: https://doc.agentscope.io/
Made with 💕 by ACGURL