该项目名为“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.tpcf.cn/web/86001.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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…