該項目名為“EduPal“,AI推薦

## 完整代碼實現

### 后端代碼 (app.py)

```python

import os

import json

import uuid

import requests

from datetime import datetime

from flask import Flask, render_template, request, jsonify

from dotenv import load_dotenv

# 加載環境變量

load_dotenv()

app = Flask(__name__)

# 文件路徑配置

USER_DATA_FILE = 'data/users.json'

INTERACTION_DATA_FILE = 'data/interactions/{user_id}.json'

KNOWLEDGE_GRAPH_FILE = 'data/knowledge_graphs/{topic}.json'

# 確保數據目錄存在

os.makedirs('data/users', exist_ok=True)

os.makedirs('data/interactions', exist_ok=True)

os.makedirs('data/knowledge_graphs', exist_ok=True)

# DeepSeek API 配置

DEEPSEEK_API_KEY = os.getenv('DEEPSEEK_API_KEY')

DEEPSEEK_API_URL = "https://api.deepseek.com/v1/chat/completions"

# 主頁路由

@app.route('/')

def home():

????return render_template('index.html')

# 用戶認證路由

@app.route('/auth', methods=['POST'])

def auth():

????action = request.json.get('action')

????username = request.json.get('username')

????password = request.json.get('password')

????email = request.json.get('email', '')

????if action == 'login':

????????return login_user(username, password)

????elif action == 'register':

????????return register_user(username, password, email)

????else:

????????return jsonify({'success': False, 'message': '無效操作'})

def login_user(username, password):

????try:

????????with open(USER_DATA_FILE, 'r') as f:

????????????users = json.load(f)

????????

????????for user in users:

????????????if user['username'] == username and user['password'] == password:

????????????????# 創建用戶會話

????????????????session_id = str(uuid.uuid4())

????????????????user['session_id'] = session_id

????????????????user['last_login'] = datetime.now().isoformat()

????????????????

????????????????# 更新用戶數據

????????????????with open(USER_DATA_FILE, 'w') as f:

????????????????????json.dump(users, f, indent=2)

????????????????

????????????????return jsonify({

????????????????????'success': True,

????????????????????'session_id': session_id,

????????????????????'user': {

????????????????????????'id': user['id'],

????????????????????????'username': username,

????????????????????????'email': user['email'],

????????????????????????'learning_style': user.get('learning_style', 'visual'),

????????????????????????'interests': user.get('interests', ['科技'])

????????????????????}

????????????????})

????????

????????return jsonify({'success': False, 'message': '用戶名或密碼錯誤'})

????except Exception as e:

????????return jsonify({'success': False, 'message': f'登錄失敗: {str(e)}'})

def register_user(username, password, email):

????try:

????????# 創建或加載用戶數據

????????if os.path.exists(USER_DATA_FILE):

????????????with open(USER_DATA_FILE, 'r') as f:

????????????????users = json.load(f)

????????else:

????????????users = []

????????

????????# 檢查用戶名是否已存在

????????if any(user['username'] == username for user in users):

????????????return jsonify({'success': False, 'message': '用戶名已存在'})

????????

????????# 創建新用戶

????????new_user = {

????????????'id': str(uuid.uuid4()),

????????????'username': username,

????????????'password': password,

????????????'email': email,

????????????'created_at': datetime.now().isoformat(),

????????????'learning_style': 'balanced', ?# 默認學習風格

????????????'interests': ['科技', '教育'], ?# 默認興趣

????????????'knowledge_level': 'intermediate' ?# 默認知識水平

????????}

????????

????????users.append(new_user)

????????

????????with open(USER_DATA_FILE, 'w') as f:

????????????json.dump(users, f, indent=2)

????????

????????return jsonify({'success': True, 'message': '注冊成功'})

????except Exception as e:

????????return jsonify({'success': False, 'message': f'注冊失敗: {str(e)}'})

# 核心AI對話功能

@app.route('/conversation', methods=['POST'])

def conversation():

????session_id = request.headers.get('X-Session-ID')

????user_query = request.json.get('query')

????context = request.json.get('context', [])

????

????if not session_id:

????????return jsonify({'success': False, 'message': '缺少會話ID'})

????

????# 獲取用戶信息

????user = get_user_by_session(session_id)

????if not user:

????????return jsonify({'success': False, 'message': '用戶未認證'})

????

????# 構建對話歷史

????full_context = [

????????{"role": "system", "content": build_system_prompt(user)},

????????*context[-5:], ?# 保留最近5輪對話

????????{"role": "user", "content": user_query}

????]

????

????# 調用DeepSeek API

????response = call_deepseek_api(full_context)

????

????if not response:

????????return jsonify({'success': False, 'message': 'AI服務不可用'})

????

????ai_reply = response['choices'][0]['message']['content']

????

????# 保存交互記錄

????save_interaction(user['id'], user_query, ai_reply)

????

????# 生成后續問題建議

????suggestions = generate_suggestions(ai_reply)

????

????# 情感分析

????emotion = analyze_emotion(user_query)

????

????return jsonify({

????????'success': True,

????????'reply': ai_reply,

????????'suggestions': suggestions,

????????'emotion': emotion,

????????'context': full_context

????})

def build_system_prompt(user):

????return f"""

????你是一位名為EduPal的AI學習伴侶,當前用戶信息如下:

????- 用戶名: {user['username']}

????- 學習風格: {user['learning_style']}

????- 知識水平: {user['knowledge_level']}

????- 興趣領域: {', '.join(user['interests'])}

????

????請根據用戶的學習風格和知識水平調整回答方式,融入其興趣領域的知識。

????回答應簡潔(100-200字),使用{user['learning_style']}學習風格。

????在適當的時候使用比喻、實例和可視化描述。

????"""

def call_deepseek_api(messages):

????headers = {

????????"Authorization": f"Bearer {DEEPSEEK_API_KEY}",

????????"Content-Type": "application/json"

????}

????

????payload = {

????????"model": "deepseek-chat",

????????"messages": messages,

????????"temperature": 0.7,

????????"max_tokens": 500,

????????"top_p": 0.9

????}

????

????try:

????????response = requests.post(DEEPSEEK_API_URL, headers=headers, json=payload, timeout=30)

????????return response.json()

????except Exception as e:

????????print(f"API調用失敗: {str(e)}")

????????return None

def generate_suggestions(ai_reply):

????"""生成后續問題建議"""

????prompt = f"""

????基于以下回復內容,生成3個用戶可能繼續問的問題:

????{ai_reply}

????

????要求:

????1. 問題要自然且相關

????2. 每個問題不超過10個字

????3. 返回JSON格式: {{"suggestions": ["問題1", "問題2", "問題3"]}}

????"""

????

????response = call_deepseek_api([

????????{"role": "user", "content": prompt}

????])

????

????if response:

????????try:

????????????return json.loads(response['choices'][0]['message']['content'])['suggestions']

????????except:

????????????return ["還想了解什么?", "需要進一步解釋嗎?", "還有其他問題嗎?"]

????return []

def analyze_emotion(text):

????"""分析用戶情緒"""

????prompt = f"""

????分析以下文本的情感傾向:

????"{text}"

????

????返回JSON格式:{{"emotion": "positive/negative/neutral", "intensity": 0-10}}

????"""

????

????response = call_deepseek_api([

????????{"role": "user", "content": prompt}

????])

????

????if response:

????????try:

????????????return json.loads(response['choices'][0]['message']['content'])

????????except:

????????????return {"emotion": "neutral", "intensity": 5}

????return {"emotion": "neutral", "intensity": 5}

# 知識圖譜功能

@app.route('/knowledge-graph', methods=['POST'])

def generate_knowledge_graph():

????session_id = request.headers.get('X-Session-ID')

????topic = request.json.get('topic')

????

????if not session_id:

????????return jsonify({'success': False, 'message': '缺少會話ID'})

????

????user = get_user_by_session(session_id)

????if not user:

????????return jsonify({'success': False, 'message': '用戶未認證'})

????

????# 檢查是否有緩存

????graph_file = KNOWLEDGE_GRAPH_FILE.format(topic=topic)

????if os.path.exists(graph_file):

????????with open(graph_file, 'r') as f:

????????????return jsonify({'success': True, 'graph': json.load(f)})

????

????# 生成知識圖譜

????prompt = f"""

????為以下主題創建知識圖譜:

????{topic}

????

????要求:

????1. 包含5-7個核心概念

????2. 顯示概念之間的關系

????3. 使用Mermaid語法格式

????4. 返回JSON格式: {{"mermaid": "graph TD\nA-->B\n..."}}

????"""

????

????response = call_deepseek_api([

????????{"role": "user", "content": prompt}

????])

????

????if not response:

????????return jsonify({'success': False, 'message': '生成失敗'})

????

????try:

????????graph_data = json.loads(response['choices'][0]['message']['content'])

????????with open(graph_file, 'w') as f:

????????????json.dump(graph_data, f)

????????return jsonify({'success': True, 'graph': graph_data})

????except:

????????return jsonify({'success': False, 'message': '解析失敗'})

# 學習報告功能

@app.route('/learning-report', methods=['GET'])

def generate_learning_report():

????session_id = request.headers.get('X-Session-ID')

????

????if not session_id:

????????return jsonify({'success': False, 'message': '缺少會話ID'})

????

????user = get_user_by_session(session_id)

????if not user:

????????return jsonify({'success': False, 'message': '用戶未認證'})

????

????# 加載用戶交互歷史

????interactions = load_interactions(user['id'])

????

????# 生成學習報告

????prompt = f"""

????基于以下學習交互記錄生成學習報告:

????{json.dumps(interactions[-10:], ensure_ascii=False)}

????

????報告要求:

????1. 總結學習軌跡

????2. 分析知識掌握情況

????3. 識別優勢領域

????4. 提出改進建議

????5. 推薦后續學習主題

????

????返回JSON格式:

????{{

????????"summary": "總體總結",

????????"progress": {{

????????????"strengths": ["優勢1", "優勢2"],

????????????"weaknesses": ["待改進領域1", "待改進領域2"]

????????}},

????????"recommendations": {{

????????????"resources": ["推薦資源1", "推薦資源2"],

????????????"topics": ["推薦主題1", "推薦主題2"]

????????}}

????}}

????"""

????

????response = call_deepseek_api([

????????{"role": "user", "content": prompt}

????])

????

????if not response:

????????return jsonify({'success': False, 'message': '生成失敗'})

????

????try:

????????report = json.loads(response['choices'][0]['message']['content'])

????????return jsonify({'success': True, 'report': report})

????except:

????????return jsonify({'success': False, 'message': '解析失敗'})

# 情感支持功能

@app.route('/emotional-support', methods=['POST'])

def emotional_support():

????session_id = request.headers.get('X-Session-ID')

????message = request.json.get('message')

????

????if not session_id:

????????return jsonify({'success': False, 'message': '缺少會話ID'})

????

????user = get_user_by_session(session_id)

????if not user:

????????return jsonify({'success': False, 'message': '用戶未認證'})

????

????# 情感分析

????emotion = analyze_emotion(message)

????

????# 生成支持性回復

????prompt = f"""

????用戶情緒狀態: {emotion['emotion']} (強度: {emotion['intensity']}/10)

????用戶留言: "{message}"

????

????請生成:

????1. 情感認可

????2. 建設性建議

????3. 鼓勵性結語

????

????保持溫暖、支持性的語氣,不超過150字。

????"""

????

????response = call_deepseek_api([

????????{"role": "user", "content": prompt}

????])

????

????if not response:

????????return jsonify({'success': False, 'message': '生成失敗'})

????

????return jsonify({

????????'success': True,

????????'reply': response['choices'][0]['message']['content'],

????????'emotion': emotion

????})

# 輔助函數

def get_user_by_session(session_id):

????if not os.path.exists(USER_DATA_FILE):

????????return None

????

????with open(USER_DATA_FILE, 'r') as f:

????????users = json.load(f)

????

????for user in users:

????????if user.get('session_id') == session_id:

????????????return user

????return None

def save_interaction(user_id, query, reply):

????interaction_file = INTERACTION_DATA_FILE.format(user_id=user_id)

????

????# 創建或加載交互記錄

????if os.path.exists(interaction_file):

????????with open(interaction_file, 'r') as f:

????????????interactions = json.load(f)

????else:

????????interactions = []

????

????# 添加新記錄

????interactions.append({

????????"timestamp": datetime.now().isoformat(),

????????"query": query,

????????"reply": reply

????})

????

????with open(interaction_file, 'w') as f:

????????json.dump(interactions, f, indent=2)

def load_interactions(user_id):

????interaction_file = INTERACTION_DATA_FILE.format(user_id=user_id)

????

????if os.path.exists(interaction_file):

????????with open(interaction_file, 'r') as f:

????????????return json.load(f)

????return []

if __name__ == '__main__':

????app.run(host='0.0.0.0', port=5000, debug=True)

```

### 前端核心代碼 (index.html)

```html

<!DOCTYPE html>

<html lang="zh-CN">

<head>

????<meta charset="UTF-8">

????<meta name="viewport" content="width=device-width, initial-scale=1.0">

????<title>EduPal - AI學習伴侶</title>

????<script src="https://cdn.jsdelivr.net/npm/three@0.132.2/build/three.min.js"></script>

????<script src="https://cdn.jsdelivr.net/npm/mermaid@9.1.3/dist/mermaid.min.js"></script>

????<style>

????????:root {

????????????--primary: #4361ee;

????????????--secondary: #3f37c9;

????????????--accent: #4895ef;

????????????--light: #f8f9fa;

????????????--dark: #212529;

????????????--success: #4cc9f0;

????????????--danger: #f72585;

????????}

????????

????????body {

????????????font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;

????????????background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);

????????????min-height: 100vh;

????????????margin: 0;

????????????padding: 0;

????????????color: var(--dark);

????????}

????????

????????.container {

????????????max-width: 1200px;

????????????margin: 0 auto;

????????????padding: 20px;

????????}

????????

????????header {

????????????display: flex;

????????????justify-content: space-between;

????????????align-items: center;

????????????padding: 15px 0;

????????????border-bottom: 1px solid rgba(0,0,0,0.1);

????????}

????????

????????.logo {

????????????display: flex;

????????????align-items: center;

????????????gap: 10px;

????????}

????????

????????.logo h1 {

????????????margin: 0;

????????????color: var(--primary);

????????}

????????

????????.user-section {

????????????display: flex;

????????????align-items: center;

????????????gap: 15px;

????????}

????????

????????.avatar {

????????????width: 40px;

????????????height: 40px;

????????????border-radius: 50%;

????????????background-color: var(--accent);

????????????display: flex;

????????????align-items: center;

????????????justify-content: center;

????????????color: white;

????????????font-weight: bold;

????????}

????????

????????.main-content {

????????????display: grid;

????????????grid-template-columns: 1fr 350px;

????????????gap: 25px;

????????????margin-top: 25px;

????????}

????????

????????.chat-container {

????????????background: white;

????????????border-radius: 15px;

????????????box-shadow: 0 5px 15px rgba(0,0,0,0.08);

????????????overflow: hidden;

????????????display: flex;

????????????flex-direction: column;

????????????height: 75vh;

????????}

????????

????????.chat-header {

????????????padding: 15px 20px;

????????????background: var(--primary);

????????????color: white;

????????}

????????

????????.messages {

????????????flex: 1;

????????????overflow-y: auto;

????????????padding: 20px;

????????????display: flex;

????????????flex-direction: column;

????????????gap: 15px;

????????}

????????

????????.message {

????????????max-width: 80%;

????????????padding: 12px 18px;

????????????border-radius: 18px;

????????????line-height: 1.5;

????????}

????????

????????.user-message {

????????????align-self: flex-end;

????????????background: var(--primary);

????????????color: white;

????????????border-bottom-right-radius: 5px;

????????}

????????

????????.ai-message {

????????????align-self: flex-start;

????????????background: #eef2ff;

????????????color: var(--dark);

????????????border-bottom-left-radius: 5px;

????????}

????????

????????.input-area {

????????????display: flex;

????????????padding: 15px;

????????????border-top: 1px solid #eee;

????????????gap: 10px;

????????}

????????

????????.input-area input {

????????????flex: 1;

????????????padding: 12px 15px;

????????????border: 1px solid #ddd;

????????????border-radius: 25px;

????????????font-size: 16px;

????????}

????????

????????.input-area button {

????????????background: var(--primary);

????????????color: white;

????????????border: none;

????????????border-radius: 25px;

????????????padding: 12px 25px;

????????????cursor: pointer;

????????????font-weight: 600;

????????}

????????

????????.suggestions {

????????????display: flex;

????????????gap: 10px;

????????????padding: 0 15px 15px;

????????????flex-wrap: wrap;

????????}

????????

????????.suggestion {

????????????background: #edf2ff;

????????????color: var(--primary);

????????????border-radius: 20px;

????????????padding: 8px 15px;

????????????font-size: 14px;

????????????cursor: pointer;

????????????transition: all 0.2s;

????????}

????????

????????.suggestion:hover {

????????????background: #dbe4ff;

????????}

????????

????????.sidebar {

????????????display: flex;

????????????flex-direction: column;

????????????gap: 25px;

????????}

????????

????????.card {

????????????background: white;

????????????border-radius: 15px;

????????????box-shadow: 0 5px 15px rgba(0,0,0,0.08);

????????????padding: 20px;

????????}

????????

????????.card h2 {

????????????margin-top: 0;

????????????color: var(--secondary);

????????????font-size: 1.3rem;

????????}

????????

????????#knowledge-graph {

????????????height: 300px;

????????????background: #f8f9fa;

????????????border-radius: 10px;

????????????margin: 15px 0;

????????????overflow: auto;

????????}

????????

????????.emotion-indicator {

????????????display: flex;

????????????align-items: center;

????????????gap: 10px;

????????????margin: 10px 0;

????????}

????????

????????.emotion-bar {

????????????flex: 1;

????????????height: 8px;

????????????background: #e9ecef;

????????????border-radius: 4px;

????????????overflow: hidden;

????????}

????????

????????.emotion-fill {

????????????height: 100%;

????????????background: var(--accent);

????????????border-radius: 4px;

????????}

????????

????????.avatar-3d {

????????????height: 200px;

????????????background: #f8f9fa;

????????????border-radius: 10px;

????????????display: flex;

????????????align-items: center;

????????????justify-content: center;

????????????color: #6c757d;

????????}

????????

????????.report-section {

????????????margin-top: 15px;

????????}

????????

????????.strength-item, .weakness-item {

????????????display: flex;

????????????align-items: center;

????????????gap: 8px;

????????????margin: 8px 0;

????????}

????????

????????.strength-item::before {

????????????content: "?";

????????????color: var(--success);

????????}

????????

????????.weakness-item::before {

????????????content: "!";

????????????color: var(--danger);

????????}

????????

????????.modal {

????????????display: none;

????????????position: fixed;

????????????top: 0;

????????????left: 0;

????????????width: 100%;

????????????height: 100%;

????????????background: rgba(0,0,0,0.5);

????????????z-index: 1000;

????????????justify-content: center;

????????????align-items: center;

????????}

????????

????????.modal-content {

????????????background: white;

????????????border-radius: 15px;

????????????width: 90%;

????????????max-width: 500px;

????????????max-height: 90vh;

????????????overflow-y: auto;

????????????padding: 25px;

????????}

????????

????????.auth-form {

????????????display: flex;

????????????flex-direction: column;

????????????gap: 15px;

????????}

????????

????????.auth-form input {

????????????padding: 12px 15px;

????????????border: 1px solid #ddd;

????????????border-radius: 8px;

????????????font-size: 16px;

????????}

????????

????????.auth-form button {

????????????background: var(--primary);

????????????color: white;

????????????border: none;

????????????border-radius: 8px;

????????????padding: 12px;

????????????cursor: pointer;

????????????font-weight: 600;

????????????font-size: 16px;

????????}

????????

????????.tabs {

????????????display: flex;

????????????margin-bottom: 20px;

????????}

????????

????????.tab {

????????????flex: 1;

????????????text-align: center;

????????????padding: 12px;

????????????background: #e9ecef;

????????????cursor: pointer;

????????}

????????

????????.tab.active {

????????????background: var(--primary);

????????????color: white;

????????}

????????

????????.tab:first-child {

????????????border-radius: 8px 0 0 8px;

????????}

????????

????????.tab:last-child {

????????????border-radius: 0 8px 8px 0;

????????}

????</style>

</head>

<body>

????<div class="container">

????????<header>

????????????<div class="logo">

????????????????<h1>EduPal</h1>

????????????????<span>AI學習伴侶</span>

????????????</div>

????????????<div class="user-section">

????????????????<div class="avatar" id="user-avatar">U</div>

????????????????<button id="auth-btn">登錄/注冊</button>

????????????</div>

????????</header>

????????

????????<main class="main-content">

????????????<div class="chat-container">

????????????????<div class="chat-header">

????????????????????<h2>與EduPal對話</h2>

????????????????</div>

????????????????<div class="messages" id="messages">

????????????????????<div class="message ai-message">

????????????????????????你好!我是EduPal,你的AI學習伴侶。我可以幫助你學習新知識、解答問題,還能根據你的學習風格個性化教學。你想了解什么?

????????????????????</div>

????????????????</div>

????????????????<div class="suggestions" id="suggestions">

????????????????????<div class="suggestion">推薦一個學習計劃</div>

????????????????????<div class="suggestion">解釋量子計算</div>

????????????????????<div class="suggestion">如何提高學習效率?</div>

????????????????</div>

????????????????<div class="input-area">

????????????????????<input type="text" id="user-input" placeholder="輸入你的問題...">

????????????????????<button id="send-btn">發送</button>

????????????????</div>

????????????</div>

????????????

????????????<div class="sidebar">

????????????????<div class="card">

????????????????????<h2>3D學習助手</h2>

????????????????????<div class="avatar-3d" id="avatar-3d">

????????????????????????<canvas id="avatar-canvas"></canvas>

????????????????????</div>

????????????????????<div class="emotion-indicator">

????????????????????????<span>情緒狀態:</span>

????????????????????????<div class="emotion-bar">

????????????????????????????<div class="emotion-fill" id="emotion-fill" style="width: 50%"></div>

????????????????????????</div>

????????????????????????<span id="emotion-label">中立</span>

????????????????????</div>

????????????????</div>

????????????????

????????????????<div class="card">

????????????????????<h2>知識圖譜</h2>

????????????????????<div id="knowledge-graph"></div>

????????????????????<button id="generate-graph-btn" style="width:100%">生成當前主題圖譜</button>

????????????????</div>

????????????????

????????????????<div class="card">

????????????????????<h2>學習報告</h2>

????????????????????<div id="report-summary">暫無報告數據</div>

????????????????????<button id="generate-report-btn" style="width:100%; margin-top:15px">生成學習報告</button>

????????????????</div>

????????????</div>

????????</main>

????</div>

????

????<!-- 認證模態框 -->

????<div class="modal" id="auth-modal">

????????<div class="modal-content">

????????????<div class="tabs">

????????????????<div class="tab active" data-tab="login">登錄</div>

????????????????<div class="tab" data-tab="register">注冊</div>

????????????</div>

????????????

????????????<form class="auth-form" id="login-form">

????????????????<input type="text" id="login-username" placeholder="用戶名" required>

????????????????<input type="password" id="login-password" placeholder="密碼" required>

????????????????<button type="submit">登錄</button>

????????????</form>

????????????

????????????<form class="auth-form" id="register-form" style="display:none">

????????????????<input type="text" id="register-username" placeholder="用戶名" required>

????????????????<input type="email" id="register-email" placeholder="郵箱" required>

????????????????<input type="password" id="register-password" placeholder="密碼" required>

????????????????<input type="password" id="register-confirm" placeholder="確認密碼" required>

????????????????<button type="submit">注冊</button>

????????????</form>

????????</div>

????</div>

????

????<script>

????????// 全局狀態

????????let sessionId = null;

????????let currentUser = null;

????????let conversationContext = [];

????????

????????// DOM元素

????????const authModal = document.getElementById('auth-modal');

????????const authBtn = document.getElementById('auth-btn');

????????const loginForm = document.getElementById('login-form');

????????const registerForm = document.getElementById('register-form');

????????const tabs = document.querySelectorAll('.tab');

????????const messagesContainer = document.getElementById('messages');

????????const userInput = document.getElementById('user-input');

????????const sendBtn = document.getElementById('send-btn');

????????const suggestionsContainer = document.getElementById('suggestions');

????????const knowledgeGraphContainer = document.getElementById('knowledge-graph');

????????const generateGraphBtn = document.getElementById('generate-graph-btn');

????????const emotionFill = document.getElementById('emotion-fill');

????????const emotionLabel = document.getElementById('emotion-label');

????????const reportSummary = document.getElementById('report-summary');

????????const generateReportBtn = document.getElementById('generate-report-btn');

????????

????????// 初始化3D頭像

????????function init3DAvatar() {

????????????const canvas = document.getElementById('avatar-canvas');

????????????const scene = new THREE.Scene();

????????????const camera = new THREE.PerspectiveCamera(75, canvas.clientWidth / canvas.clientHeight, 0.1, 1000);

????????????const renderer = new THREE.WebGLRenderer({ canvas, alpha: true });

????????????

????????????renderer.setSize(canvas.clientWidth, canvas.clientHeight);

????????????

????????????// 創建基礎幾何體

????????????const geometry = new THREE.SphereGeometry(1, 32, 32);

????????????const material = new THREE.MeshBasicMaterial({ color: 0x4361ee });

????????????const sphere = new THREE.Mesh(geometry, material);

????????????

????????????scene.add(sphere);

????????????camera.position.z = 3;

????????????

????????????// 動畫循環

????????????function animate() {

????????????????requestAnimationFrame(animate);

????????????????sphere.rotation.x += 0.01;

????????????????sphere.rotation.y += 0.01;

????????????????renderer.render(scene, camera);

????????????}

????????????

????????????animate();

????????}

????????

????????// 初始化Mermaid

????????mermaid.initialize({

????????????startOnLoad: true,

????????????theme: 'neutral',

????????????securityLevel: 'loose'

????????});

????????

????????// 顯示認證模態框

????????authBtn.addEventListener('click', () => {

????????????authModal.style.display = 'flex';

????????});

????????

????????// 切換登錄/注冊標簽

????????tabs.forEach(tab => {

????????????tab.addEventListener('click', () => {

????????????????tabs.forEach(t => t.classList.remove('active'));

????????????????tab.classList.add('active');

????????????????

????????????????if (tab.dataset.tab === 'login') {

????????????????????loginForm.style.display = 'flex';

????????????????????registerForm.style.display = 'none';

????????????????} else {

????????????????????loginForm.style.display = 'none';

????????????????????registerForm.style.display = 'flex';

????????????????}

????????????});

????????});

????????

????????// 登錄處理

????????loginForm.addEventListener('submit', async (e) => {

????????????e.preventDefault();

????????????

????????????const username = document.getElementById('login-username').value;

????????????const password = document.getElementById('login-password').value;

????????????

????????????const response = await fetch('/auth', {

????????????????method: 'POST',

????????????????headers: { 'Content-Type': 'application/json' },

????????????????body: JSON.stringify({

????????????????????action: 'login',

????????????????????username,

????????????????????password

????????????????})

????????????});

????????????

????????????const data = await response.json();

????????????

????????????if (data.success) {

????????????????sessionId = data.session_id;

????????????????currentUser = data.user;

????????????????document.getElementById('user-avatar').textContent = currentUser.username.charAt(0).toUpperCase();

????????????????authModal.style.display = 'none';

????????????????

????????????????// 添加歡迎消息

????????????????addMessage(`歡迎回來,${currentUser.username}!今天想學習什么?`, 'ai');

????????????} else {

????????????????alert(data.message);

????????????}

????????});

????????

????????// 注冊處理

????????registerForm.addEventListener('submit', async (e) => {

????????????e.preventDefault();

????????????

????????????const username = document.getElementById('register-username').value;

????????????const email = document.getElementById('register-email').value;

????????????const password = document.getElementById('register-password').value;

????????????const confirm = document.getElementById('register-confirm').value;

????????????

????????????if (password !== confirm) {

????????????????alert('兩次輸入的密碼不一致');

????????????????return;

????????????}

????????????

????????????const response = await fetch('/auth', {

????????????????method: 'POST',

????????????????headers: { 'Content-Type': 'application/json' },

????????????????body: JSON.stringify({

????????????????????action: 'register',

????????????????????username,

????????????????????password,

????????????????????email

????????????????})

????????????});

????????????

????????????const data = await response.json();

????????????

????????????if (data.success) {

????????????????alert('注冊成功!請登錄');

????????????????tabs[0].click();

????????????} else {

????????????????alert(data.message);

????????????}

????????});

????????

????????// 發送消息

????????sendBtn.addEventListener('click', sendMessage);

????????userInput.addEventListener('keypress', (e) => {

????????????if (e.key === 'Enter') sendMessage();

????????});

????????

????????// 建議點擊

????????suggestionsContainer.addEventListener('click', (e) => {

????????????if (e.target.classList.contains('suggestion')) {

????????????????userInput.value = e.target.textContent;

????????????????sendMessage();

????????????}

????????});

????????

????????// 生成知識圖譜

????????generateGraphBtn.addEventListener('click', async () => {

????????????if (!currentUser) {

????????????????alert('請先登錄');

????????????????return;

????????????}

????????????

????????????const lastUserMessage = conversationContext

????????????????.filter(msg => msg.role === 'user')

????????????????.pop()?.content;

????????????

????????????if (!lastUserMessage) {

????????????????alert('請先進行對話');

????????????????return;

????????????}

????????????

????????????const response = await fetch('/knowledge-graph', {

????????????????method: 'POST',

????????????????headers: {

????????????????????'Content-Type': 'application/json',

????????????????????'X-Session-ID': sessionId

????????????????},

????????????????body: JSON.stringify({ topic: lastUserMessage })

????????????});

????????????

????????????const data = await response.json();

????????????

????????????if (data.success) {

????????????????knowledgeGraphContainer.innerHTML = '';

????????????????const graphDiv = document.createElement('div');

????????????????graphDiv.className = 'mermaid';

????????????????graphDiv.textContent = data.graph.mermaid;

????????????????knowledgeGraphContainer.appendChild(graphDiv);

????????????????mermaid.init(undefined, graphDiv);

????????????} else {

????????????????alert('生成失敗: ' + data.message);

????????????}

????????});

????????

????????// 生成學習報告

????????generateReportBtn.addEventListener('click', async () => {

????????????if (!currentUser) {

????????????????alert('請先登錄');

????????????????return;

????????????}

????????????

????????????const response = await fetch('/learning-report', {

????????????????method: 'GET',

????????????????headers: { 'X-Session-ID': sessionId }

????????????});

????????????

????????????const data = await response.json();

????????????

????????????if (data.success) {

????????????????const report = data.report;

????????????????let html = `

????????????????????<h3>學習總結</h3>

????????????????????<p>${report.summary}</p>

????????????????????

????????????????????<h3>學習進度</h3>

????????????????????<div class="report-section">

????????????????????????<h4>優勢領域</h4>

????????????????????????${report.progress.strengths.map(s => `<div class="strength-item">${s}</div>`).join('')}

????????????????????????

????????????????????????<h4>待改進領域</h4>

????????????????????????${report.progress.weaknesses.map(w => `<div class="weakness-item">${w}</div>`).join('')}

????????????????????</div>

????????????????????

????????????????????<h3>學習建議</h3>

????????????????????<div class="report-section">

????????????????????????<h4>推薦資源</h4>

????????????????????????<ul>${report.recommendations.resources.map(r => `<li>${r}</li>`).join('')}</ul>

????????????????????????

????????????????????????<h4>推薦主題</h4>

????????????????????????<ul>${report.recommendations.topics.map(t => `<li>${t}</li>`).join('')}</ul>

????????????????????</div>

????????????????`;

????????????????

????????????????reportSummary.innerHTML = html;

????????????} else {

????????????????alert('生成失敗: ' + data.message);

????????????}

????????});

????????

????????// 添加消息到對話框

????????function addMessage(text, sender) {

????????????const messageDiv = document.createElement('div');

????????????messageDiv.className = `message ${sender}-message`;

????????????messageDiv.textContent = text;

????????????messagesContainer.appendChild(messageDiv);

????????????messagesContainer.scrollTop = messagesContainer.scrollHeight;

????????}

????????

????????// 發送消息

????????async function sendMessage() {

????????????const message = userInput.value.trim();

????????????if (!message) return;

????????????

????????????if (!currentUser) {

????????????????alert('請先登錄');

????????????????return;

????????????}

????????????

????????????// 添加用戶消息

????????????addMessage(message, 'user');

????????????userInput.value = '';

????????????

????????????// 添加到上下文

????????????conversationContext.push({ role: 'user', content: message });

????????????

????????????// 發送到后端

????????????const response = await fetch('/conversation', {

????????????????method: 'POST',

????????????????headers: {

????????????????????'Content-Type': 'application/json',

????????????????????'X-Session-ID': sessionId

????????????????},

????????????????body: JSON.stringify({

????????????????????query: message,

????????????????????context: conversationContext

????????????????})

????????????});

????????????

????????????const data = await response.json();

????????????

????????????if (data.success) {

????????????????// 添加AI回復

????????????????addMessage(data.reply, 'ai');

????????????????

????????????????// 更新上下文

????????????????conversationContext = data.context;

????????????????

????????????????// 更新建議

????????????????updateSuggestions(data.suggestions);

????????????????

????????????????// 更新情緒狀態

????????????????updateEmotion(data.emotion);

????????????} else {

????????????????addMessage('抱歉,我暫時無法回答這個問題。請稍后再試。', 'ai');

????????????}

????????}

????????

????????// 更新建議

????????function updateSuggestions(suggestions) {

????????????suggestionsContainer.innerHTML = '';

????????????suggestions.forEach(suggestion => {

????????????????const div = document.createElement('div');

????????????????div.className = 'suggestion';

????????????????div.textContent = suggestion;

????????????????suggestionsContainer.appendChild(div);

????????????});

????????}

????????

????????// 更新情緒狀態

????????function updateEmotion(emotion) {

????????????const intensity = emotion.intensity;

????????????emotionFill.style.width = `${intensity * 10}%`;

????????????

????????????let label = '';

????????????if (emotion.emotion === 'positive') {

????????????????label = `積極 (${intensity}/10)`;

????????????????emotionFill.style.backgroundColor = '#4ade80';

????????????} else if (emotion.emotion === 'negative') {

????????????????label = `消極 (${intensity}/10)`;

????????????????emotionFill.style.backgroundColor = '#f87171';

????????????} else {

????????????????label = `中立 (${intensity}/10)`;

????????????????emotionFill.style.backgroundColor = '#60a5fa';

????????????}

????????????

????????????emotionLabel.textContent = label;

????????}

????????

????????// 初始化

????????window.addEventListener('load', () => {

????????????init3DAvatar();

????????});

????</script>

</body>

</html>

```

### 環境文件 (.env)

```

DEEPSEEK_API_KEY=your_api_key_here

```

---

## 項目策劃書:EduPal - AI學習伴侶

### 1. 項目概述

**項目名稱**:EduPal ?

**項目定位**:基于大模型的個性化AI學習伴侶系統 ?

**核心創新**:融合情感智能與知識圖譜的學習體驗 ?

**目標用戶**:中學生、大學生及終身學習者 ?

**技術棧**: ?

- 后端:Python/Flask ?

- 前端:HTML5/CSS3/JavaScript + Three.js ?

- AI模型:DeepSeek API ?

- 可視化:Mermaid.js ?

### 2. 核心功能設計

#### 2.1 智能學習伴侶

- **個性化學習路徑**:基于用戶畫像動態調整教學內容

- **情境感知對話**:記憶對話歷史,保持對話連貫性

- **智能追問建議**:AI生成后續學習問題

- **多模態解釋**:結合文本、圖表、可視化解釋復雜概念

#### 2.2 情感智能支持

- **情緒識別系統**:分析用戶文本情感傾向與強度

- **共情式回應**:生成溫暖、支持性的回復

- **學習狀態監測**:識別學習挫折并提供鼓勵

#### 2.3 知識圖譜系統

- **動態知識圖譜**:自動生成學科概念關系圖

- **交互式探索**:點擊節點獲取詳細解釋

- **知識關聯發現**:揭示跨學科知識連接

#### 2.4 學習分析報告

- **學習軌跡可視化**:展示知識掌握進度

- **優勢領域識別**:突出用戶擅長領域

- **個性化建議**:推薦學習資源和改進方向

### 3. 技術創新點

#### 3.1 動態用戶畫像系統

```mermaid

graph LR

A[用戶交互] --> B[行為分析]

B --> C[知識水平評估]

B --> D[學習風格識別]

B --> E[興趣領域挖掘]

C --> F[個性化回復]

D --> F

E --> F

```

#### 3.2 情感智能引擎

- **情感分析模型**:基于文本的情感分類與強度量化

- **CBT(認知行為療法)融合**:在回復中融入心理學原理

- **情緒可視化**:實時情緒狀態儀表盤

#### 3.3 知識圖譜生成技術

- **概念提取算法**:自動識別核心知識點

- **關系推理引擎**:建立概念間的邏輯聯系

- **跨學科連接**:發現不同領域的知識關聯

### 4. 系統架構

#### 4.1 技術架構

```mermaid

graph TD

A[前端界面] --> B[Flask API網關]

B --> C[用戶管理系統]

B --> D[對話引擎]

B --> E[知識圖譜生成]

B --> F[學習分析模塊]

C --> G[用戶數據存儲]

D --> H[DeepSeek API]

E --> H

F --> G

```

#### 4.2 數據流設計

```mermaid

sequenceDiagram

用戶->>前端: 發起請求

前端->>后端: API調用

后端->>AI模型: 請求處理

AI模型->>后端: 返回結果

后端->>前端: 響應數據

前端->>用戶: 展示結果

前端->>后端: 用戶反饋

后端->>AI模型: 模型優化

```

### 5. 實現計劃

| 階段 | 時間 | 主要任務 | 交付物 |

|------|------|----------|--------|

| 1. 基礎框架 | 第1周 | 用戶系統搭建、API接口設計 | 可運行的原型系統 |

| 2. 核心AI | 第2周 | 對話引擎、情感分析模塊 | 智能對話功能 |

| 3. 知識可視化 | 第3周 | 知識圖譜生成、3D虛擬形象 | 交互式學習界面 |

| 4. 優化部署 | 第4周 | 性能優化、云端部署 | 可上線應用 |

### 6. 創新亮點

1. **情感智能融合** ?

???業內首個將情感分析深度融入教育場景的AI系統

2. **動態知識圖譜** ?

???實時生成個性化知識結構圖,輔助構建知識體系

3. **成長陪伴模式** ?

???從單純答疑進化為學習旅程的全程伴侶

4. **多模態交互** ?

???結合3D虛擬形象、知識圖譜和自然語言對話

### 7. 預期成果

1. **功能完備的Web應用** ?

???- 個性化學習對話系統 ?

???- 情感支持模塊 ?

???- 知識圖譜可視化 ?

???- 學習分析報告 ?

2. **技術文檔** ?

???- 系統架構設計 ?

???- API文檔 ?

???- 部署指南 ?

3. **演示材料** ?

???- 產品演示視頻 ?

???- 用戶測試報告 ?

???- 創新點說明文檔 ?

### 8. 部署方案

```bash

# 部署步驟

1. 安裝依賴

pip install flask python-dotenv requests

2. 設置環境變量

echo "DEEPSEEK_API_KEY=your_api_key" > .env

3. 啟動服務

python app.py

4. 配置生產環境

gunicorn -w 4 -b 0.0.0.0:5000 app:app

```

### 9. 項目優勢

1. **教育普惠性**:降低個性化教育門檻 ?

2. **情感連接**:解決傳統AI冷漠問題 ?

3. **知識結構化**:幫助構建系統知識體系 ?

4. **可擴展性**:支持多學科知識領域 ?

5. **用戶粘性**:成長陪伴式學習體驗 ?

---

## 下一步建議

1. **申請DeepSeek API Key**:替換.env文件中的API密鑰

2. **部署測試環境**:使用Vercel或Render部署前端

3. **豐富學科知識庫**:添加特定領域的學習資料

4. **開發移動應用**:基于Flutter開發跨平臺APP

5. **接入更多AI服務**:集成多模態模型支持圖像解釋

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/86001.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/86001.shtml
英文地址,請注明出處:http://en.pswp.cn/web/86001.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++法則15:匹配失敗并不是一種錯誤(Substitution Failure Is Not An Error)。

C法則15&#xff1a;匹配失敗并不是一種錯誤(Substitution Failure Is Not An Error)。 應用例子&#xff1a; SFINAE &#xff1a;關于is_class&#xff0c;is_base_of&#xff0c;C編譯器的魔法器&#xff0c;如何實現&#xff0c;is_class&#xff0c;is_base_of。_c is cl…

Ollama客戶端 + Docker搭建本地知識庫(Mac系統)

一、環境準備 1. 安裝Ollama客戶端 官網下載&#xff1a;https://ollama.com 驗證安裝&#xff1a; ollama --version2. 安裝Docker Desktop 下載地址&#xff1a;https://www.docker.com/products/docker-desktop 安裝后確保Docker狀態為"Running" 二、基礎搭建…

FastMCP 2.9 版本詳解:MCP 原生中間件與類型轉換增強

下面我將從三個方面來講解這個&#xff0c;第一是講解2.9版本的更新&#xff0c;第二是講解什么將手動解析底層JSON-RPC 消息&#xff0c;丟失 FastMCP 高層語義&#xff0c;第三是講一講&#xff0c;什么叫做中間件。不了解的兄弟們系好安全帶&#xff0c;我們準備發車了&…

LTspice仿真6——PWL折線波產生

1.自定義波形 2.自定義波形周期 3.以文件.txt的形式定義折線波 4.通過C語言編程&#xff0c;一系列操作&#xff0c;生成自定義正弦波&#xff08;可自定義性強&#xff09;

FunASR搭建語音識別服務和VAD檢測

調整VAD參數 1. 查找VAD模型的配置文件 FunASR中的VAD模型為FSMN-VAD&#xff0c;參數配置類為VADXOptions&#xff0c;可以在以下路徑中找到&#xff1a; /workspace/FunASR/runtime/python/onnxruntime/funasr_onnx/utils/e2e_vad.py 其中&#xff0c;VADXOptions類定義了…

多模態大模型(從0到1)

文章目錄 一、多模態大模型二、常見模態組合 典型應用場景三、多模態&#xff08;模型 框架&#xff09;1. 多模態模型2. 多模態框架 —— 開源項目推薦&#xff08;可快速上手&#xff09; 四、入門與學習路線1. 理論基礎2. 主流多模態模型實戰3. 進階與應用拓展&#x1f4d…

# Vue.js 精確輪播組件實現詳解

## &#x1f4d6; 概述 本文詳細介紹了一個基于 Vue.js 開發的高精度輪播組件&#xff0c;該組件實現了精確的卡片對齊和平滑滾動效果。組件支持混合布局&#xff08;大卡片網格布局&#xff09;&#xff0c;具備智能位置計算和精確滾動控制功能。 ## ? 組件特點 ### &#x1…

將RESP.app的備份數據轉碼成AnotherRedisDesktopManager的格式

將RESP.app的備份數據轉碼成AnotherRedisDesktopManager的格式 最近發現了AnotherRedisDesktopManager&#xff0c;這個軟件可以直接展示proto數據。 將RESP.app導出的json文件&#xff0c;轉碼為AnotherRedisDesktopManager的ano文件&#xff08;是一個list轉了base64&#xf…

前端基礎知識JavaScript系列 - 09(JavaScript原型,原型鏈 )

一、原型 JavaScript 常被描述為一種基于原型的語言——每個對象擁有一個原型對象 當試圖訪問一個對象的屬性時&#xff0c;它不僅僅在該對象上搜尋&#xff0c;還會搜尋該對象的原型&#xff0c;以及該對象的原型的原型&#xff0c;依次層層向上搜索&#xff0c;直到找到一個…

vue3+ts 使用VueCropper實現剪切圖片

效果圖&#xff1a; 參考文檔&#xff1a; Vue-Cropper 文檔Vue-Cropper 文檔 安裝VueCropper //npm安裝 npm install vue-croppernext -d --save//yarn安裝 yarn add vue-croppernext 引入組件 在main.ts中全局注冊&#xff1a; import VueCropper from vue-cropper; i…

el-table特殊表頭樣式

el-table特殊表頭樣式 實現表頭是按鈕 <el-table-column align"center"><template slot"header"><el-buttonsize"mini"type"primary"icon"el-icon-plus"circleclick"addData"></el-button&g…

el-tree的屬性render-content自定義樣式不生效

需求是想要自定義展示el-tree的項&#xff0c;官網有一個:render-content屬性&#xff0c;用的時候發現不管是使用class還是style&#xff0c;樣式都沒有生效&#xff0c;還會報一個錯&#xff0c;怎么個事呢&#xff0c;后來發現控制臺還會報一個錯“vue.js:5129 [Vue warn]: …

銀杏書簽里的春天

春末的細雨沾濕了舊書扉頁&#xff0c;我在泛黃的《飛鳥集》里發現那枚銀杏書簽時&#xff0c;窗外的梧桐樹正抖落最后一片枯葉。深褐色的葉脈間夾著張字條&#xff0c;娟秀的字跡被歲月暈染&#xff1a;"給永遠在奔跑的人。" 十年前的我在舊書店打工&#xff0c;每天…

spring-ai 1.0.0 學習(十四)——向量數據庫

向量數據庫是AI系統中常用的工具&#xff0c;主要用來存儲文檔片段及進行語義相似度查找 與傳統數據庫不同&#xff0c;它執行的是相似度查找而不是精確匹配 最小化樣例 首先在application.properties中&#xff0c;根據所用Embedding模型&#xff0c;添加一個嵌入式模型型號…

Spring Boot 的Banner的介紹和設置

Spring Banner 是指在 Spring Boot 應用啟動時,控制臺上顯示的那一段 ASCII 藝術字(通常是 Spring 的 logo),以及一些應用信息。 Banner 是 Spring Boot 提供的一個小但有趣的功能,可以讓應用程序啟動時更具個性也顯得更高級。 默認 Banner Spring Boot 內置了一個默認…

魅族“換血”出牌:手機基本盤站不穩,想靠AI和汽車“改命”

撰稿|何威 來源|貝多財經 被吉利收購后&#xff0c;魅族逐漸轉向在AI領域躬身耕作。 自2024年2月以“All in AI”正式宣告轉型、喊出不再推出傳統智能手機的豪言開始&#xff0c;這家曾以設計見長的手機廠商&#xff0c;將下半場押注在AI終端、AR眼鏡與智能座艙系統上&#…

力扣熱題100之將有序數組轉換為二叉搜索樹

題目 給你一個整數數組 nums &#xff0c;其中元素已經按 升序 排列&#xff0c;請你將其轉換為一棵 平衡 二叉搜索樹。 代碼 使用遞歸的方法 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # s…

mac隱藏文件現身快捷鍵

在 macOS 系統中&#xff0c;?顯示/隱藏隱藏文件? 有兩種常用方法&#xff0c;以下是詳細說明&#xff1a; ? 方法一&#xff1a;使用快捷鍵&#xff08;最簡單&#xff09; 打開 ?訪達&#xff08;Finder&#xff09;?。 進入任意文件夾&#xff08;如桌面或文檔&#x…

IAR Workspace 中 Debug 與 Release 配置的深度解析

IAR Workspace 中 Debug 與 Release 配置的深度解析 一、配置的本質區別 1. 核心目標對比 特性Debug 配置Release 配置優化目標調試友好性性能/尺寸優化代碼優化無或低優化 (-O0/-O1)高級優化 (-O2/-O3/-Oz)調試信息包含完整符號信息無或最小化符號斷言檢查啟用通常禁用輸出…

Ubuntu下安裝python3

一、下載python3源碼 以要安裝的是python3.13.5為例&#xff0c;在 Index of /ftp/python/3.13.5/ 下載Python-3.13.5.tgz&#xff1a; 將壓縮包上傳到Ubuntu系統中&#xff0c;解壓&#xff1a; tar -zxvf Python-3.13.5.tgz 二、安裝 進入解壓后的源碼目錄&#xff1a; c…