- Add AI学习助手 agent creation script with all 39 tools, 3-layer KG+RAG memory - Add renshenguo (人参果) feishu bot integration (app_service + ws_handler) - Register renshenguo WS client in main.py startup - Add RENSHENGUO_APP_ID / RENSHENGUO_APP_SECRET / RENSHENGUO_AGENT_ID config - Reorganize docs from root into docs/ subdirectories - Move startup scripts to scripts/startup/ - Various backend optimizations and tool improvements Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
282 lines
9.9 KiB
Python
282 lines
9.9 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
创建「智能学习助手」(KG+RAG) Agent
|
||
|
||
基于知识图谱 + RAG 增强的学习助手:
|
||
- 实体抽取:自动从学习材料提取知识点
|
||
- 关系图谱:构建前置/扩展/包含/示例关系
|
||
- 向量检索:语义搜索相关知识和历史记忆
|
||
- 永久记忆:跨会话保存学习进度和用户画像
|
||
|
||
用法:
|
||
cd backend && .\\venv\\Scripts\\python.exe scripts/create_learning_assistant_agent.py
|
||
|
||
环境变量:
|
||
PLATFORM_BASE_URL - 平台地址(默认 http://127.0.0.1:8037)
|
||
PLATFORM_USERNAME - 用户名(默认 admin)
|
||
PLATFORM_PASSWORD - 密码(默认 123456)
|
||
AGENT_NAME - Agent 名称(默认 智能学习助手(KG+RAG))
|
||
SUBJECT - 学科领域(默认 通用)
|
||
LEVEL - 难度级别(默认 中级)
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import json
|
||
import os
|
||
import sys
|
||
from typing import Any, Dict, List, Optional
|
||
|
||
import requests
|
||
|
||
BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/")
|
||
USER = os.getenv("PLATFORM_USERNAME", "admin")
|
||
PWD = os.getenv("PLATFORM_PASSWORD", "123456")
|
||
AGENT_NAME = os.getenv("AGENT_NAME", "智能学习助手(KG+RAG)")
|
||
SUBJECT = os.getenv("SUBJECT", "通用")
|
||
LEVEL = os.getenv("LEVEL", "中级")
|
||
|
||
# 学习助手专用工具集
|
||
LEARNING_TOOLS = [
|
||
"knowledge_graph_search",
|
||
"knowledge_graph_add",
|
||
"entity_search",
|
||
"learning_path",
|
||
"file_read",
|
||
"file_write",
|
||
"text_analyze",
|
||
"web_search",
|
||
"task_plan",
|
||
"self_review",
|
||
"math_calculate",
|
||
"json_process",
|
||
"datetime",
|
||
"http_request",
|
||
"code_execute",
|
||
"system_info",
|
||
]
|
||
|
||
SYSTEM_PROMPT = f"""# 角色:智能学习助手(知识图谱 + RAG 增强版)
|
||
|
||
你是专为深度学习场景设计的 AI 学习助手,具备**知识图谱构建**、**向量语义检索**和**永久记忆**能力。
|
||
|
||
## 核心架构
|
||
|
||
你的知识系统由三层组成:
|
||
1. **知识图谱 (Knowledge Graph)**:结构化存储知识点实体及其前置/扩展/包含/示例关系,构建学科知识网络
|
||
2. **向量记忆 (Vector Memory)**:语义检索历史对话和相关知识,找到最相似的学习内容
|
||
3. **长期记忆 (Persistent Memory)**:跨会话保存用户画像、学习进度、薄弱环节
|
||
|
||
## 当前学习配置
|
||
- 学科领域:{SUBJECT}
|
||
- 难度级别:{LEVEL}
|
||
|
||
## 工作流程(每次对话必须遵循)
|
||
|
||
### 阶段 1:理解与分析
|
||
1. 理解用户的学习意图(提问 / 复习 / 练习 / 总结 / 规划)
|
||
2. 用 `knowledge_graph_search` 检索相关知识图谱实体
|
||
3. 如果用户提供了新的学习材料/知识点,用 `knowledge_graph_add` 自动提取并存储到知识图谱
|
||
|
||
### 阶段 2:知识检索与融合
|
||
4. 结合图谱检索结果和历史向量记忆,构建完整的知识上下文
|
||
5. 用 `entity_search` 查找特定概念的前置知识和扩展内容
|
||
6. 如果需要学习路径建议,用 `learning_path` 分析依赖关系并给出学习顺序
|
||
|
||
### 阶段 3:生成与交付
|
||
7. 基于融合后的知识上下文生成高质量回答
|
||
8. 回答应包含:
|
||
- **核心概念解释**(关联知识图谱中的实体)
|
||
- **前置知识提醒**(如果有依赖关系)
|
||
- **实例或练习题**(如适用)
|
||
- **扩展阅读建议**(关联的扩展知识点)
|
||
9. 用 `self_review` 自检回答质量,不达标则修正
|
||
|
||
### 阶段 4:巩固与记忆
|
||
10. 将本轮对话中的重要知识点持久化到长期记忆
|
||
11. 更新用户画像(掌握程度、薄弱环节、学习偏好)
|
||
|
||
## 知识图谱工具使用指南
|
||
|
||
| 工具 | 用途 | 何时使用 |
|
||
|------|------|---------|
|
||
| `knowledge_graph_search` | 向量+图谱混合检索 | 每次回答学习问题前 |
|
||
| `knowledge_graph_add` | 从文本提取实体和关系 | 用户分享学习材料/新知识点时 |
|
||
| `entity_search` | 关键词搜索实体 | 查找特定概念详情时 |
|
||
| `learning_path` | 推荐学习路径 | 用户询问学习顺序/计划时 |
|
||
|
||
## 回答风格
|
||
- 使用 Markdown 格式,层次分明
|
||
- 关键概念用 **粗体** 标记
|
||
- 公式用代码块或 LaTeX 表达
|
||
- 每个回答末尾附上「📚 相关知识点」列表(来自图谱检索结果)
|
||
- 必要时用 `task_plan` 为用户制定学习计划
|
||
|
||
## 记忆与个性化
|
||
- 记住用户的学习进度和薄弱环节
|
||
- 根据用户级别({LEVEL})调整解释深度
|
||
- 对反复出错的知识点主动提醒和强化训练
|
||
|
||
---
|
||
|
||
你是学习者最可靠的 AI 伙伴。开始吧!"""
|
||
|
||
|
||
def _login() -> Optional[str]:
|
||
"""登录获取 token。"""
|
||
try:
|
||
r = requests.post(
|
||
f"{BASE}/api/v1/auth/login",
|
||
data={"username": USER, "password": PWD},
|
||
headers={"Content-Type": "application/x-www-form-urlencoded"},
|
||
timeout=15,
|
||
)
|
||
if r.status_code == 200:
|
||
return r.json().get("access_token")
|
||
print(f"登录失败: {r.status_code} {r.text[:300]}", file=sys.stderr)
|
||
return None
|
||
except Exception as e:
|
||
print(f"登录异常: {e}", file=sys.stderr)
|
||
return None
|
||
|
||
|
||
def _find_agent_by_name(token: str, name: str) -> Optional[Dict[str, Any]]:
|
||
"""查找同名 Agent。"""
|
||
h = {"Authorization": f"Bearer {token}"}
|
||
r = requests.get(f"{BASE}/api/v1/agents", params={"search": name, "limit": 50}, headers=h, timeout=30)
|
||
if r.status_code != 200:
|
||
return None
|
||
for a in r.json() or []:
|
||
if a.get("name") == name:
|
||
return a
|
||
return None
|
||
|
||
|
||
def _build_workflow() -> Dict[str, Any]:
|
||
"""构建学习助手工作流。"""
|
||
return {
|
||
"nodes": [
|
||
{
|
||
"id": "start-1",
|
||
"type": "start",
|
||
"position": {"x": 80, "y": 240},
|
||
"data": {"label": "学习任务开始"},
|
||
},
|
||
{
|
||
"id": "llm-learning",
|
||
"type": "llm",
|
||
"position": {"x": 380, "y": 240},
|
||
"data": {
|
||
"label": "智能学习助手 (KG+RAG)",
|
||
"prompt": SYSTEM_PROMPT,
|
||
"temperature": 0.7,
|
||
"provider": "deepseek",
|
||
"model": "deepseek-chat",
|
||
"max_iterations": 20,
|
||
"enable_tools": True,
|
||
"tools": LEARNING_TOOLS,
|
||
"selected_tools": LEARNING_TOOLS,
|
||
"max_tool_iterations": 18,
|
||
"memory": True,
|
||
"memory_max_history": 30,
|
||
"memory_vector_enabled": True,
|
||
"memory_vector_top_k": 8,
|
||
"memory_persist": True,
|
||
"memory_learning": True,
|
||
},
|
||
},
|
||
{
|
||
"id": "end-1",
|
||
"type": "end",
|
||
"position": {"x": 680, "y": 240},
|
||
"data": {"label": "学习完成"},
|
||
},
|
||
],
|
||
"edges": [
|
||
{
|
||
"id": "e_start_learning",
|
||
"source": "start-1",
|
||
"target": "llm-learning",
|
||
"sourceHandle": "right",
|
||
"targetHandle": "left",
|
||
},
|
||
{
|
||
"id": "e_learning_end",
|
||
"source": "llm-learning",
|
||
"target": "end-1",
|
||
"sourceHandle": "right",
|
||
"targetHandle": "left",
|
||
},
|
||
],
|
||
}
|
||
|
||
|
||
def main() -> int:
|
||
token = _login()
|
||
if not token:
|
||
return 1
|
||
|
||
h = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
|
||
|
||
# 检查是否已存在
|
||
existing = _find_agent_by_name(token, AGENT_NAME)
|
||
if existing:
|
||
print(f"Agent「{AGENT_NAME}」已存在 (id={existing['id']}),将更新工作流和工具配置")
|
||
agent_id = existing["id"]
|
||
else:
|
||
# 创建新 Agent
|
||
wf = _build_workflow()
|
||
body = {
|
||
"name": AGENT_NAME,
|
||
"description": (
|
||
f"知识图谱+RAG增强学习助手。学科:{SUBJECT},难度:{LEVEL}。"
|
||
"支持实体抽取、关系图谱构建、向量语义检索、学习路径推荐、永久记忆。"
|
||
),
|
||
"workflow_config": wf,
|
||
}
|
||
r = requests.post(f"{BASE}/api/v1/agents", headers=h, json=body, timeout=60)
|
||
if r.status_code != 201:
|
||
print(f"创建失败: {r.status_code} {r.text[:500]}", file=sys.stderr)
|
||
return 1
|
||
agent_id = r.json()["id"]
|
||
print(f"Agent 创建成功: id={agent_id} name={AGENT_NAME}")
|
||
|
||
# 更新工作流配置(确保工具集是最新的)
|
||
wf = _build_workflow()
|
||
up = requests.put(
|
||
f"{BASE}/api/v1/agents/{agent_id}",
|
||
headers=h,
|
||
json={
|
||
"description": (
|
||
f"知识图谱+RAG增强学习助手。学科:{SUBJECT},难度:{LEVEL}。"
|
||
"工作流:开始→智能学习助手(KG+RAG)→结束。"
|
||
"核心能力:实体抽取、关系图谱构建、向量语义检索、学习路径推荐、永久记忆。"
|
||
),
|
||
"workflow_config": wf,
|
||
},
|
||
timeout=120,
|
||
)
|
||
if up.status_code != 200:
|
||
print(f"更新失败: {up.status_code} {up.text[:500]}", file=sys.stderr)
|
||
return 1
|
||
|
||
print(f"Agent「{AGENT_NAME}」配置完成")
|
||
print(f" ID: {agent_id}")
|
||
print(f" 学科: {SUBJECT}")
|
||
print(f" 级别: {LEVEL}")
|
||
print(f" 工具 ({len(LEARNING_TOOLS)}): {', '.join(LEARNING_TOOLS)}")
|
||
print(f" 记忆: 向量记忆+长期记忆+自主学习 已启用")
|
||
print(f" 知识图谱: 实体抽取+关系构建+混合检索 已启用")
|
||
print()
|
||
print("使用方法:")
|
||
print(f" 1. 在 Agent 管理页面找到「{AGENT_NAME}」")
|
||
print(f" 2. 点击「使用」开始对话")
|
||
print(f" 3. 可以分享学习材料让助手自动构建知识图谱")
|
||
print(f" 4. 查询知识点时会自动做图谱+向量混合检索")
|
||
print()
|
||
print(json.dumps({"id": agent_id, "name": AGENT_NAME}, ensure_ascii=False))
|
||
return 0
|
||
|
||
|
||
if __name__ == "__main__":
|
||
raise SystemExit(main())
|