diff --git a/README.md b/README.md index 00bafb0..fa77707 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,11 @@ 本课程通过 AI 代码编辑器(如 Cursor、Windsurf)进行 **Vibe Coding**,让学生体验"用自然语言编程"的全新开发方式。但更重要的是,在这个过程中**思考人与 AI 的协作边界**,培养 AI 时代真正不可替代的能力。 **技术栈**: -- 🐍 **Python 3.10+** -- 🤖 **DeepSeek API**(大语言模型) -- 🎨 **Streamlit**(Web 界面框架) -- 🛠️ **Cursor / Windsurf**(AI 代码编辑器) +- 🐍 **Python 3.14+** (2026 Stable) +- ⚡ **uv** (极速 Python 项目管理) +- 🤖 **DeepSeek API** + **PydanticAI** (Agent 框架) +- 🎨 **Streamlit** (Data Apps) / **Chainlit** (Chatbots) +- 🛠️ **Cursor / Windsurf** (AI 代码编辑器) --- @@ -32,6 +33,27 @@ --- +## 🛠️ 第0天:环境预备 (Day 0) + +> [!IMPORTANT] +> **请在正式上课前完成以下准备**。这能让你在第一天直接进入"Vibe Coding"状态,而不是卡在安装软件上。 + +### 1. 软件安装清单 +- **Code Editor**: 推荐 [Cursor](https://cursor.com) (自带 AI) 或 VS Code + Windsurf 插件, [TRAE CN](https://www.trae.cn)。 +- **Python 3.14+**: 访问 [python.org](https://www.python.org/downloads/) 下载。 +- **uv**: 极速 Python 包管理器 (比 pip 快 10-100 倍)。 + - Mac/Linux: `curl -LsSf https://astral.sh/uv/install.sh | sh` + - Windows: `powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"` + +### 2. 验证环境 +在终端 (Terminal) 输入以下命令,看到版本号即成功: +```bash +python --version # 应显示 Python 3.14.x +uv --version # 应显示 uv 0.x.x +``` + +--- + ## 📚 第1天:课程讲解与演示(3学时) ### 1.1 课程导入(30分钟) @@ -41,6 +63,21 @@ - **核心逻辑**:"描述你想要什么,而不是告诉计算机怎么做"。 - **演示**:用自然语言在 3 分钟内创建一个完整应用。 +#### 为什么要学 Python 基础?(The "Why" in AI Era) + +很多同学会问:*"既然 AI 能写代码,我为什么还要学基础语法?"* + +> **即使是法拉利,也需要懂驾驶原理的赛车手。** + +在 Vibe Coding 中,你需要具备**两种核心能力**才能驾驭 AI: +1. **准确描述 (Prompting)**: 你需要懂一点术语 (如 "List", "Loop", "Function") 才能精准指挥 AI。 +2. **验证结果 (Auditing)**: AI 会犯错 (幻觉)。你需要能读懂代码,判断它是不是在"一本正经地胡说八道"。 + +**重点掌握:** +* **0-Based Indexing**: 为什么计算机从 0 开始数数?(因为偏移量的概念)。 +* **逻辑控制**: `if`, `for`, `while` 是所有程序的骨架。 +* **函数思维**: 把大问题拆解成小模块 (Input -> Process -> Output)。 + #### AI 时代,什么能力真正属于你? > **AI 能做的事越来越多:** 语法查询、代码生成、Bug 修复、文档撰写、测试创建、架构建议、代码重构... @@ -57,14 +94,53 @@ #### AI 代码编辑器介绍 - **Cursor**:[https://cursor.com](https://cursor.com) - **Windsurf**:[https://codeium.com/windsurf](https://codeium.com/windsurf) +- **TRAE CN**:[https://www.trae.cn](https://www.trae.cn) - **核心模式**: - **Approve/Reject**:人是最终的决策者。 - **Context Awareness**:如何让 AI "看见"你的整个项目。 -### 1.2 技术栈讲解(60分钟) +### 1.2 Vibe Coding 快速上手:新手四步法 (The 4-Step Loop) -#### DeepSeek API 快速入门 +对于 0 基础的新手,不要试图一次性写出完美代码。请遵循 **"D-P-R-I"** 循环: + +1. **Define (定义)**:用一句话说清楚你要做什么。 + * ❌ *"写个程序"* + * ✅ *"写一个倒计时器,要有开始/暂停按钮,时间到了会弹窗提示"* +2. **Prompt (提示)**:扮演产品经理,给 AI 下指令。 + * **公式**:`角色 + 任务 + 限制条件` + * *例:"你是一个 Python 专家。请用 Streamlit 写一个 番茄钟应用。要求:界面简洁,背景是黑色,使用 Session State 记录时间。"* +3. **Review (审查)**:AI 写完后,不要盲目运行。 + * **一眼定真**:代码里有没有显然的红色波浪线 (报错)? + * **结构检查**:有没有 `import`?有没有主函数? +4. **Iterate (迭代)**:运行 -> 报错 -> 把报错扔给 AI。 + * *"Vibe Coding 的精髓不在于一次写对,而在于快速试错。"* + * **黄金法则**:如果 AI 连续改 3 次还没修好,**停下来**!这通常意味着你的 Prompt 逻辑有问题,或者方向错了。 + +### 1.3 技术栈讲解(60分钟) + +#### ⚡ 2026 现代 Python 工作流 (uv) + +我们将告别繁琐的 `pip` 和虚拟环境配置,使用 Rust 编写的 **uv** 作为唯一工具。 + +**核心三步走 (The 3-Step Vibe)**: + +1. **初始化 (Init)**: 创建一个干净的"代码工作台"。 + ```bash + uv init my-ai-app + cd my-ai-app + ``` +2. **添加工具 (Add)**: 就像给手机装 App 一样简单。 + ```bash + uv add streamlit chainlit openai python-dotenv + ``` +3. **运行 (Run)**: 一键启动,无需担心环境冲突。 + ```bash + uv run main.py + ``` + +#### DeepSeek API 快速入门 (使用 OpenAI SDK) ```python +# 推荐使用 uv 管理依赖: uv add openai from openai import OpenAI # 初始化客户端 @@ -73,75 +149,188 @@ client = OpenAI( base_url="https://api.deepseek.com" ) -# 发送请求 +# ... (代码保持不变) +``` + +> [!TIP] +> **进阶选择**:对于复杂的 Agent 开发,推荐使用 **PydanticAI**,它能提供更好的类型安全和结构化输出支持。 + +#### Streamlit vs Chainlit + +- **Streamlit**: 适合构建 **数据仪表板**、**工具类应用** (如 Excel 处理、图表分析)。 +- **Chainlit**: 适合构建 **聊天机器人**、**多轮对话 Agent** (自带优美的聊天界面)。 + +**Streamlit 示例 (数据应用)**: +```python +import streamlit as st + +st.title("数据分析看板") +st.line_chart([1, 5, 2, 6]) +``` + +**Chainlit 示例 (对话应用)**: +```python +import chainlit as cl + +@cl.on_message +async def main(message: cl.Message): + # 这里调用 DeepSeek API + await cl.Message(content=f"你说了: {message.content}").send() +``` + +### 1.4 动手实践:三个"最小可运行"示例 (MVP Hands-on) + +接下来的 45 分钟,请跟随老师在你的电脑上运行这三个示例。这是你迈向 Vibe Coding 的第一步。 + +> [!NOTE] +> **准备工作**: +> 确保你已经初始化了项目并填入了 Key: +> ```bash +> mkdir day1-demo +> cd day1-demo +> uv init +> uv add openai python-dotenv streamlit chainlit +> # 创建 .env 文件并填入: DEEPSEEK_API_KEY=sk-xxxxxx +> ``` + +#### 示例 A: Hello AI (CLI 脚本) +**目标**:理解 OpenAI SDK 的最基本调用方式。 +**文件**:`main.py` + +```python +import os +from openai import OpenAI +from dotenv import load_dotenv + +# 1. 加载环境变量 (.env) +load_dotenv() +api_key = os.getenv("DEEPSEEK_API_KEY") + +if not api_key: + print("❌ 错误:未找到 DEEPSEEK_API_KEY,请检查 .env 文件") + exit() + +# 2. 初始化客户端 +client = OpenAI(api_key=api_key, base_url="https://api.deepseek.com") + +# 3. 发送请求 +print("🤖 AI 正在思考...") response = client.chat.completions.create( - model="deepseek-chat", # 使用 V3 模型 + model="deepseek-chat", messages=[ - {"role": "system", "content": "你是一个有帮助的助手"}, - {"role": "user", "content": "你好!"} + {"role": "system", "content": "你是一个赛博朋克风格的诗人。"}, + {"role": "user", "content": "用两句话描述代码的魅力。"}, ], stream=False ) +# 4. 输出结果 +print("\n" + "="*30) print(response.choices[0].message.content) +print("="*30 + "\n") +``` +**运行**: +```bash +uv run main.py ``` -> [!WARNING] -> **API Key 安全**: -> 绝对不要按将 API Key 直接提交到 GitHub 等公共仓库!请使用 `.env` 文件配合 `.gitignore` 管理。 +#### 示例 B: 魔法文案生成器 (Streamlit) +**目标**:不写 HTML/CSS,用 Python 5分钟构建可视化的 AI 应用。 +**文件**:`app_gui.py` -**关键概念**: -- **API Key**:你的"通行证",注意保密。 -- **Messages**:对话历史的列表,包含 system(人设)、user(用户)、assistant(AI)。 -- **Stream**:流式输出,提升用户体验(像打字机一样显示)。 - -#### Streamlit 快速入门 ```python import streamlit as st +import os +from openai import OpenAI +from dotenv import load_dotenv -st.title("我的第一个 Streamlit 应用") +load_dotenv() +client = OpenAI(api_key=os.getenv("DEEPSEEK_API_KEY"), base_url="https://api.deepseek.com") -# 侧边栏 +# 1. 页面配置 +st.set_page_config(page_title="魔法文案生成器", page_icon="✨") +st.title("✨ 魔法文案生成器") + +# 2. 左侧侧边栏 with st.sidebar: - st.write("这是侧边栏") + st.header("配置") + style = st.selectbox("选择风格", ["文艺风", "幽默风", "硬核科技风", "发疯文学"]) + length = st.slider("字数限制", 50, 200, 100) -# 输入框 -user_input = st.text_input("请输入你的问题:") +# 3. 主界面输入 +theme = st.text_input("你想写关于什么主题的文案?", placeholder="例如:周五下班、喝咖啡、新发型") -# 按钮与交互 -if st.button("提交"): - if user_input: - st.write(f"你输入了:{user_input}") +# 4. 按钮与 AI 调用 +if st.button("🪄 生成文案"): + if not theme: + st.warning("请先输入主题!") else: - st.warning("请输入内容!") + with st.spinner("AI 正在榨干脑汁..."): + try: + prompt = f"请用{style}写一段关于'{theme}'的朋友圈文案,带Emoji,{length}字以内。" + + response = client.chat.completions.create( + model="deepseek-chat", + messages=[{"role": "user", "content": prompt}] + ) + result = response.choices[0].message.content + + st.success("生成成功!") + st.markdown(f"### 📝 结果:\n{result}") + except Exception as e: + st.error(f"发生错误:{e}") +``` +**运行**: +```bash +uv run streamlit run app_gui.py ``` -**常用组件**: -- 🛠️ **输入**:`st.text_input`, `st.text_area`, `st.slider` -- 📄 **输出**:`st.write`, `st.markdown`, `st.chat_message` -- 🎒 **状态**:`st.session_state` (用于记住对话历史) +#### 示例 C: 会聊天的猫 (Chainlit) +**目标**:构建像 ChatGPT 一样的对话界面,支持流式输出 (Streaming)。 +**文件**:`app_chat.py` -### 1.3 完整示例演示(45分钟) +```python +import chainlit as cl +import os +from openai import OpenAI +from dotenv import load_dotenv -#### 现场演示:用 Vibe Coding 构建一个 AI 聊天应用 +load_dotenv() +client = OpenAI(api_key=os.getenv("DEEPSEEK_API_KEY"), base_url="https://api.deepseek.com") -**演示步骤**: -1. **Init**:新建文件夹,用自然语言让 AI 初始化环境。 -2. **Draft**:描述核心需求,生成 1.0 版本代码。 -3. **Refine**: - - 添加对话历史记忆(Session State)。 - - 开启流式输出(Streaming)。 - - 优化 UI(添加侧边栏设置)。 -4. **Deploy**:运行并测试。 +@cl.on_message +async def main(message: cl.Message): + # 1. 准备消息历史 + # (注意:实际项目中需要维护 st.session_state 或 cl.user_session 来保留上下文,这里仅演示单轮回复) + msg_history = [ + {"role": "system", "content": "你是一只高冷的猫,说话句尾要带'喵'。"}, + {"role": "user", "content": message.content} + ] + + # 2. 创建回复消息容器 + msg = cl.Message(content="") + await msg.send() + + # 3. 调用 AI 并流式(stream)接收 + stream = client.chat.completions.create( + model="deepseek-chat", + messages=msg_history, + stream=True + ) + + for chunk in stream: + if token := chunk.choices[0].delta.content: + await msg.stream_token(token) + + # 4. 完成更新 + await msg.update() +``` +**运行**: +```bash +uv run chainlit run app_chat.py -w +``` -**示例 Prompt**: -> "帮我创建一个基于 DeepSeek API 的聊天应用,使用 Streamlit 构建界面。要求: -> 1. 支持多轮对话,保留对话历史 -> 2. 使用流式输出,打字机效果显示回复 -> 3. 左侧边栏可以设置系统提示词 -> 4. 界面美观,有清空对话的按钮" - -### 1.4 项目要求说明(15分钟) +### 1.5 项目要求说明(15分钟) #### 项目选题(任选其一或自拟) @@ -161,6 +350,27 @@ if st.button("提交"): > 💡 **选题思考**:不只是"我能做什么",更要思考"这个项目**对谁有价值**?解决什么**真实问题**?" +#### 🚀 从 0 到 1:如何开始?(Starter Kit) + +面对空白的代码编辑器感到迷茫?请按以下步骤操作: + +**Step 1: 只要写出 README.md,你就完成了一半** +不要急着写代码。先用自然语言在 `Project_Design.md` (或草稿纸) 上写下: +1. **一句话描述**:我的应用叫什么?它是给谁用的? +2. **核心功能**:它*必须*有的 3 个功能是什么?(MVP) +3. **交互流程**:用户打开 App -> 点击什么 -> 看到什么? + +**Step 2: 让 AI 写第一行代码** +把Step 1的内容喂给 Cursor/Windsurf: +> *"我正在开发一个[项目名]。请阅读我的设计思路:[粘贴你的描述]。请帮我生成项目结构,并创建最基础的 app.py 框架。"* + +**Step 3: 最小可行性验证** +* 生成的代码能跑吗?(Run it) +* 界面上能看到按钮吗?(See it) +* 如果报错,直接把报错信息截图或复制给 AI。 + +> **记住**:你是在搭建积木,不是在烧制砖块。先搭出轮廓,再修饰细节。 + --- ## 🔧 第2天:自主开发 @@ -281,7 +491,7 @@ AI 不是神,它需要知道你的代码、你的报错、你的意图。 ### 1. 提交材料 1. **源代码**:完整项目文件夹。 2. **README.md**:项目说明文档。 -3. **requirements.txt**:`pip freeze > requirements.txt` 生成。 +3. **依赖文件**:包含 `pyproject.toml` 和 `uv.lock` (确保别人可以用 `uv sync` 还原你的环境)。 4. **开发心得**:Markdown 格式,**不少于 500 字**。 ### 2. README.md 模板 @@ -292,9 +502,9 @@ AI 不是神,它需要知道你的代码、你的报错、你的意图。 这句话介绍你的项目是做什么的,解决了什么问题。 ## 如何运行 -1. 安装依赖:`pip install -r requirements.txt` +1. 安装依赖:`uv sync` 2. 配置 Key:复制 `.env.example` 为 `.env` 并填入 Key。 -3. 运行:`streamlit run app.py` +3. 运行:`uv run streamlit run app.py` ## 功能列表 - [x] 功能 A @@ -321,21 +531,28 @@ AI 不是神,它需要知道你的代码、你的报错、你的意图。 ## 🔗 附录:环境配置指南 ### 1. 基础环境 -- **Python**:推荐 3.10+ ([官网下载](https://www.python.org/downloads/)) -- **编辑器**:推荐 Cursor 或 VS Code + Windsurf 插件。 +- **Python**: 推荐 3.14+ (2026 Stable) +- **依赖管理**: **uv** (强烈推荐,替代 pip/venv) +- **编辑器**: 推荐 Cursor 或 VS Code + Windsurf 插件。 -### 2. 项目初始化命令 +### 2. 项目初始化 (使用 uv) ```bash -# 1. 创建虚拟环境 (Windows) -python -m venv venv -.\venv\Scripts\activate +# 1. 安装 uv (MacOS/Linux) +curl -LsSf https://astral.sh/uv/install.sh | sh +# Windows: powershell -c "irm https://astral.sh/uv/install.ps1 | iex" -# 1. 创建虚拟环境 (Mac/Linux) -python3 -m venv venv -source venv/bin/activate +# 2. 初始化项目 +mkdir my-ai-app +cd my-ai-app +uv init -# 2. 安装核心库 -pip install streamlit openai python-dotenv +# 3. 添加依赖 +uv add streamlit chainlit openai python-dotenv + +# 4. 运行应用 +uv run streamlit run app.py +# 或 +uv run chainlit run app.py -w ``` ### 3. API Key 管理示例 (`.env`) @@ -347,6 +564,7 @@ DEEPSEEK_API_KEY=sk-xxxxxxx ```python # app.py import os +# uv add python-dotenv from dotenv import load_dotenv load_dotenv() # 加载 .env diff --git a/示例项目-AI数据分析师/.env-example b/示例项目-AI数据分析师/.env-example deleted file mode 100644 index 9b9185e..0000000 --- a/示例项目-AI数据分析师/.env-example +++ /dev/null @@ -1,9 +0,0 @@ -# DeepSeek API Key 配置示例 -# ================================ -# 使用方法: -# 1. 将此文件复制并重命名为 .env -# 2. 将下面的 sk-xxx... 替换为你的真实 API Key -# ================================ - -DEEPSEEK_API_KEY=sk-xxxxx - diff --git a/示例项目-AI数据分析师/.gitignore b/示例项目-AI数据分析师/.gitignore deleted file mode 100644 index b7fca19..0000000 --- a/示例项目-AI数据分析师/.gitignore +++ /dev/null @@ -1,25 +0,0 @@ -# 环境变量(包含敏感信息) -.env - -# Python -__pycache__/ -*.py[cod] -*$py.class -*.so -.Python -venv/ -ENV/ - -# IDE -.vscode/ -.idea/ -*.swp -*.swo - -# macOS -.DS_Store - -# 临时文件 -*.tmp -*.log - diff --git a/示例项目-AI数据分析师/README.md b/示例项目-AI数据分析师/README.md deleted file mode 100644 index ee38b9a..0000000 --- a/示例项目-AI数据分析师/README.md +++ /dev/null @@ -1,314 +0,0 @@ -# 📊 AI 数据分析师 - -一个基于 DeepSeek API + Streamlit 的智能数据分析平台,上传 CSV 数据即可获得 AI 驱动的深度洞察和可视化报告。 - -![Python](https://img.shields.io/badge/Python-3.10+-blue.svg) -![Streamlit](https://img.shields.io/badge/Streamlit-1.28+-red.svg) -![DeepSeek](https://img.shields.io/badge/DeepSeek-API-green.svg) -![Difficulty](https://img.shields.io/badge/难度-⭐⭐⭐⭐-orange.svg) - -## ✨ 功能特性 - -| 功能 | 描述 | -|:---|:---| -| 📈 **数据预览** | 数据表格展示、统计摘要、列信息分析 | -| 📊 **智能可视化** | 根据数据类型自动生成直方图、散点图、箱线图、热力图 | -| 🤖 **AI 深度分析** | 综合分析、相关性分析、异常检测三种模式 | -| 💬 **自然语言问答** | 用中文直接询问关于数据的任何问题 | -| 📝 **报告生成** | 一键生成完整的 Markdown 格式分析报告并下载 | - -## 🖼️ 界面预览 - -``` -┌────────────────────────────────────────────────────────────────────┐ -│ 📊 AI 数据分析师 │ -│ 上传数据,让 AI 帮你发现数据中的故事 │ -├────────────────────────────────────────────────────────────────────┤ -│ [📈 数据预览] [📊 智能可视化] [🤖 AI 分析] [💬 数据问答] [📝 生成报告] │ -├────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │ -│ │ 100 │ │ 7 │ │ 0 │ │ 5 │ │ -│ │ 数据行 │ │ 数据列 │ │ 缺失值 │ │ 数值列 │ │ -│ └──────┘ └──────┘ └──────┘ └──────┘ │ -│ │ -│ ┌─────────────────────────────────────────────────────────────┐ │ -│ │ 姓名 │ 部门 │ 年龄 │ 工龄 │ 月薪 │ 绩效评分 │ 满意度 │ │ -│ │ 张三 │ 技术部 │ 28 │ 3 │ 15000 │ 85.5 │ 4.2 │ │ -│ │ 李四 │ 市场部 │ 32 │ 5 │ 18000 │ 78.3 │ 3.8 │ │ -│ │ ... │ ... │ ... │ ... │ ... │ ... │ ... │ │ -│ └─────────────────────────────────────────────────────────────┘ │ -│ │ -└────────────────────────────────────────────────────────────────────┘ -``` - -## 🚀 快速开始 - -### 1. 进入项目目录 - -```bash -cd 示例项目-AI数据分析师 -``` - -### 2. 创建虚拟环境(推荐) - -```bash -python -m venv venv - -# Windows -venv\Scripts\activate - -# macOS/Linux -source venv/bin/activate -``` - -### 3. 安装依赖 - -```bash -pip install -r requirements.txt -``` - -### 4. 配置 API Key - -创建 `.env` 文件: - -```bash -echo "DEEPSEEK_API_KEY=sk-your-api-key" > .env -``` - -或直接在应用界面的侧边栏输入 API Key。 - -### 5. 运行应用 - -```bash -streamlit run app.py -``` - -浏览器会自动打开 http://localhost:8501 - -## 📁 项目结构 - -``` -示例项目-AI数据分析师/ -├── app.py # 主程序 (~600行) -├── requirements.txt # 项目依赖 -├── sample_data.csv # 示例数据(员工信息) -├── .env # 环境变量(需自行创建) -├── .gitignore # Git 忽略文件 -└── README.md # 项目说明 -``` - -## 🛠️ 技术架构 - -``` -┌─────────────────────────────────────────────────────────┐ -│ Streamlit UI │ -│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ -│ │数据预览 │ │智能可视化│ │ AI分析 │ │数据问答 │ │ -│ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │ -│ │ │ │ │ │ -├───────┼───────────┼───────────┼───────────┼─────────────┤ -│ ▼ ▼ ▼ ▼ │ -│ ┌─────────────────────────────────────────────────┐ │ -│ │ Pandas DataFrame │ │ -│ │ (数据处理与统计分析) │ │ -│ └─────────────────────────────────────────────────┘ │ -│ │ │ │ -│ ▼ ▼ │ -│ ┌─────────┐ ┌─────────────────────────────────────┐ │ -│ │ Altair │ │ DeepSeek API │ │ -│ │ (可视化)│ │ (AI 分析 / 问答 / 报告生成) │ │ -│ └─────────┘ └─────────────────────────────────────┘ │ -└─────────────────────────────────────────────────────────┘ -``` - -## 🔑 核心技术点 - -### 1. 数据处理与摘要生成 - -```python -def get_data_summary(df: pd.DataFrame) -> str: - """生成数据摘要供 AI 分析""" - summary = [] - - # 基本信息 - summary.append(f"数据集包含 {len(df)} 行和 {len(df.columns)} 列。") - - # 数值列统计 - numeric_cols = df.select_dtypes(include=['number']).columns - stats = df[numeric_cols].describe().to_string() - - # ... 更多统计信息 - return "\n".join(summary) -``` - -### 2. AI 分析的 Prompt 工程 - -```python -def analyze_with_ai(client, data_summary, analysis_type): - prompts = { - "general": """你是一个专业的数据分析师... -请从以下几个方面进行分析: -1. 📊 数据概况 -2. 🔍 关键发现 -3. 📈 建议可视化 -4. ⚠️ 注意事项 -5. 💡 进一步分析建议""", - - "correlation": """分析变量之间的相关性...""", - "anomaly": """检测数据中的异常值...""" - } - - response = client.chat.completions.create( - model="deepseek-chat", - messages=[ - {"role": "system", "content": prompts[analysis_type]}, - {"role": "user", "content": f"数据摘要:\n{data_summary}"} - ] - ) - return response.choices[0].message.content -``` - -### 3. 自动可视化生成 - -```python -def create_visualizations(df): - """根据数据类型自动选择合适的图表""" - charts = [] - numeric_cols = df.select_dtypes(include=['number']).columns - cat_cols = df.select_dtypes(include=['object']).columns - - # 数值分布 -> 直方图 - if numeric_cols: - hist_chart = alt.Chart(df).mark_bar().encode( - x=alt.X(f'{col}:Q', bin=True), - y='count()' - ) - charts.append(hist_chart) - - # 多数值变量 -> 散点图 + 相关性热力图 - # 分类+数值 -> 箱线图 - # ... - - return charts -``` - -### 4. 多轮对话的上下文管理 - -```python -def ask_data_question(client, data_summary, question, chat_history): - messages = [ - {"role": "system", "content": "你是数据分析助手..."}, - {"role": "user", "content": f"数据摘要:\n{data_summary}"}, - {"role": "assistant", "content": "我已了解数据,请问您想知道什么?"} - ] - - # 添加历史对话 - for msg in chat_history: - messages.append(msg) - - # 添加当前问题 - messages.append({"role": "user", "content": question}) - - return client.chat.completions.create( - model="deepseek-chat", - messages=messages - ) -``` - -### 5. Session State 管理 - -```python -# 初始化状态 -if "df" not in st.session_state: - st.session_state.df = None -if "analyses" not in st.session_state: - st.session_state.analyses = {} -if "qa_history" not in st.session_state: - st.session_state.qa_history = [] - -# 跨 Tab 共享数据 -df = st.session_state.df -``` - -## 📊 使用的 Streamlit 组件 - -| 组件 | 用途 | -|:---|:---| -| `st.tabs` | 多标签页布局 | -| `st.columns` | 统计卡片布局 | -| `st.file_uploader` | CSV 文件上传 | -| `st.dataframe` | 交互式数据表格 | -| `st.altair_chart` | Altair 图表渲染 | -| `st.chat_message` | 问答对话界面 | -| `st.chat_input` | 聊天输入框 | -| `st.session_state` | 状态管理 | -| `st.download_button` | 报告下载 | -| `st.spinner` | 加载动画 | -| `st.expander` | 可折叠区域 | - -## 🎨 Vibe Coding 开发过程 - -### 初始 Prompt - -> "帮我创建一个 AI 数据分析师应用,使用 DeepSeek API 和 Streamlit。 -> -> 功能需求: -> 1. 上传 CSV 文件,显示数据预览和统计 -> 2. 自动根据数据类型生成可视化图表(用 Altair) -> 3. AI 分析功能:综合分析、相关性分析、异常检测 -> 4. 自然语言问答,可以问关于数据的问题 -> 5. 生成 Markdown 格式的分析报告 -> -> 技术要求: -> - 使用 st.tabs 做多标签页布局 -> - 使用 st.session_state 管理状态 -> - 界面要美观,使用自定义 CSS" - -### 迭代优化 - -``` -Prompt 1: "给数据预览页添加统计卡片,显示行数、列数、缺失值等" - -Prompt 2: "让可视化更智能,根据数据类型自动选择图表类型" - -Prompt 3: "问答功能要支持多轮对话,AI 要记住之前的问题" - -Prompt 4: "报告生成功能要把之前的分析结果都整合进去" - -Prompt 5: "加一个示例数据选项,方便没有数据的用户体验" -``` - -## 🔧 扩展建议 - -如果你想进一步完善这个项目,可以考虑: - -1. **支持更多文件格式**:Excel、JSON、Parquet -2. **添加数据清洗功能**:缺失值处理、异常值处理 -3. **更丰富的可视化**:时间序列图、地理图 -4. **导出更多格式**:PDF、HTML、Word -5. **添加数据筛选器**:让用户选择分析哪些列/行 -6. **机器学习预测**:简单的回归/分类预测功能 - -## ⚠️ 注意事项 - -1. **数据大小**:大数据集(>10万行)可能导致界面卡顿 -2. **API 成本**:长文本分析和多轮问答会消耗更多 Token -3. **隐私安全**:敏感数据请在本地使用,不要上传到公共服务器 -4. **API Key 安全**:不要将 `.env` 提交到代码仓库 - -## 📚 参考资料 - -- [Streamlit 官方文档](https://docs.streamlit.io) -- [Altair 可视化文档](https://altair-viz.github.io) -- [Pandas 数据分析](https://pandas.pydata.org/docs/) -- [DeepSeek API 文档](https://platform.deepseek.com/api-docs) - -## 👤 作者 - -Python 程序设计课程设计 - 高级示例项目 - ---- - -**让数据说话,用 AI 倾听!** 📊🤖 - diff --git a/示例项目-AI数据分析师/app.py b/示例项目-AI数据分析师/app.py deleted file mode 100644 index 21ac70b..0000000 --- a/示例项目-AI数据分析师/app.py +++ /dev/null @@ -1,735 +0,0 @@ -""" -📊 AI 数据分析师 -================== -一个基于 DeepSeek API + Streamlit 的智能数据分析应用 - -功能特性: -- 📁 上传 CSV 数据文件 -- 📈 自动生成可视化图表 -- 🤖 AI 智能分析数据特征 -- 💬 自然语言问答数据 -- 📝 生成分析报告 - -技术栈: -- Streamlit: Web 界面 -- Pandas: 数据处理 -- Altair: 数据可视化 -- DeepSeek API: AI 分析 -""" - -import streamlit as st -import pandas as pd -import altair as alt -import json -from openai import OpenAI -import os -from dotenv import load_dotenv -from io import StringIO - -# 加载环境变量 -load_dotenv() - -# ============== 配置 ============== - -API_KEY = os.getenv("DEEPSEEK_API_KEY", "") -BASE_URL = "https://api.deepseek.com" -MODEL = "deepseek-chat" - -# ============== 页面配置 ============== - -st.set_page_config( - page_title="AI 数据分析师", - page_icon="📊", - layout="wide", - initial_sidebar_state="expanded" -) - -# ============== 自定义样式 ============== - -st.markdown(""" - -""", unsafe_allow_html=True) - -# ============== 辅助函数 ============== - -def get_data_summary(df: pd.DataFrame) -> str: - """生成数据摘要文本供 AI 分析""" - summary = [] - - # 基本信息 - summary.append(f"数据集包含 {len(df)} 行和 {len(df.columns)} 列。") - summary.append(f"\n列名:{', '.join(df.columns.tolist())}") - - # 数据类型 - summary.append(f"\n\n各列数据类型:") - for col in df.columns: - dtype = str(df[col].dtype) - null_count = df[col].isnull().sum() - summary.append(f"- {col}: {dtype}, 缺失值: {null_count}") - - # 数值列统计 - numeric_cols = df.select_dtypes(include=['number']).columns.tolist() - if numeric_cols: - summary.append(f"\n\n数值列统计摘要:") - stats = df[numeric_cols].describe().to_string() - summary.append(stats) - - # 分类列信息 - cat_cols = df.select_dtypes(include=['object', 'category']).columns.tolist() - if cat_cols: - summary.append(f"\n\n分类列信息:") - for col in cat_cols[:5]: # 最多显示5个 - unique_count = df[col].nunique() - top_values = df[col].value_counts().head(5).to_dict() - summary.append(f"- {col}: {unique_count} 个唯一值, 前5个: {top_values}") - - # 样本数据 - summary.append(f"\n\n前3行数据样本:") - summary.append(df.head(3).to_string()) - - return "\n".join(summary) - - -def analyze_with_ai(client: OpenAI, data_summary: str, analysis_type: str = "general") -> str: - """使用 AI 分析数据""" - - prompts = { - "general": """你是一个专业的数据分析师。请根据以下数据摘要,提供全面的数据分析洞察。 - -请从以下几个方面进行分析: -1. 📊 数据概况:数据的整体情况和质量评估 -2. 🔍 关键发现:数据中的重要模式和特征 -3. 📈 建议可视化:推荐适合这个数据集的图表类型 -4. ⚠️ 注意事项:数据中可能存在的问题或需要注意的地方 -5. 💡 进一步分析建议:可以深入探索的方向 - -请用清晰的结构和通俗易懂的语言回答。""", - - "correlation": """你是一个专业的数据分析师。请分析以下数据中各变量之间可能存在的相关性和关联。 - -请重点分析: -1. 哪些变量之间可能存在正相关或负相关? -2. 是否存在明显的因果关系假设? -3. 建议做哪些相关性分析? - -请用通俗易懂的语言解释。""", - - "anomaly": """你是一个专业的数据分析师。请分析以下数据中可能存在的异常值或异常模式。 - -请关注: -1. 数值是否有明显的异常值? -2. 数据分布是否有异常? -3. 是否存在数据质量问题? -4. 建议如何处理这些异常? - -请给出具体的分析和建议。""" - } - - system_prompt = prompts.get(analysis_type, prompts["general"]) - - response = client.chat.completions.create( - model=MODEL, - messages=[ - {"role": "system", "content": system_prompt}, - {"role": "user", "content": f"数据摘要:\n\n{data_summary}"} - ], - max_tokens=2000, - temperature=0.7 - ) - - return response.choices[0].message.content - - -def ask_data_question(client: OpenAI, data_summary: str, question: str, chat_history: list) -> str: - """根据数据回答用户问题""" - - system_prompt = """你是一个专业的数据分析助手。用户会就数据集提出问题,你需要根据提供的数据摘要来回答。 - -回答要求: -1. 基于数据事实回答,不要编造数据中没有的信息 -2. 如果数据摘要中没有足够信息回答问题,请诚实说明 -3. 尽可能提供具体的数字和分析 -4. 可以给出进一步分析的建议""" - - messages = [{"role": "system", "content": system_prompt}] - messages.append({"role": "user", "content": f"数据摘要:\n{data_summary}\n\n请记住这个数据摘要,我接下来会问你关于这个数据的问题。"}) - messages.append({"role": "assistant", "content": "好的,我已经了解了这个数据集的情况。请问您想了解什么?"}) - - # 添加对话历史 - for msg in chat_history: - messages.append(msg) - - # 添加当前问题 - messages.append({"role": "user", "content": question}) - - response = client.chat.completions.create( - model=MODEL, - messages=messages, - max_tokens=1500, - temperature=0.7 - ) - - return response.choices[0].message.content - - -def generate_report(client: OpenAI, data_summary: str, analyses: dict) -> str: - """生成完整的分析报告""" - - system_prompt = """你是一个专业的数据分析师,请根据数据摘要和已有的分析结果,生成一份完整的数据分析报告。 - -报告格式要求: -1. 使用 Markdown 格式 -2. 包含标题、摘要、详细分析、结论和建议 -3. 结构清晰,层次分明 -4. 语言专业但易懂 -5. 适当使用 emoji 增加可读性""" - - user_content = f"""数据摘要: -{data_summary} - -已有分析结果: -{json.dumps(analyses, ensure_ascii=False, indent=2)} - -请生成一份完整的数据分析报告。""" - - response = client.chat.completions.create( - model=MODEL, - messages=[ - {"role": "system", "content": system_prompt}, - {"role": "user", "content": user_content} - ], - max_tokens=3000, - temperature=0.7 - ) - - return response.choices[0].message.content - - -def create_visualizations(df: pd.DataFrame): - """根据数据自动生成可视化图表""" - charts = [] - - numeric_cols = df.select_dtypes(include=['number']).columns.tolist() - cat_cols = df.select_dtypes(include=['object', 'category']).columns.tolist() - - # 1. 数值分布直方图(第一个数值列) - if numeric_cols: - col = numeric_cols[0] - hist_chart = alt.Chart(df).mark_bar( - opacity=0.7, - color='#667eea' - ).encode( - alt.X(f'{col}:Q', bin=alt.Bin(maxbins=30), title=col), - alt.Y('count()', title='频数'), - tooltip=[alt.Tooltip(f'{col}:Q', bin=alt.Bin(maxbins=30)), 'count()'] - ).properties( - title=f'📊 {col} 分布直方图', - height=300 - ) - charts.append(('distribution', hist_chart, f'{col} 的数值分布')) - - # 2. 分类计数柱状图(第一个分类列) - if cat_cols: - col = cat_cols[0] - if df[col].nunique() <= 20: # 类别不要太多 - bar_chart = alt.Chart(df).mark_bar( - color='#764ba2' - ).encode( - x=alt.X(f'{col}:N', sort='-y', title=col), - y=alt.Y('count()', title='计数'), - tooltip=[col, 'count()'] - ).properties( - title=f'📈 {col} 分类计数', - height=300 - ) - charts.append(('category', bar_chart, f'{col} 各类别的计数')) - - # 3. 散点图(如果有多个数值列) - if len(numeric_cols) >= 2: - col1, col2 = numeric_cols[0], numeric_cols[1] - color_col = cat_cols[0] if cat_cols and df[cat_cols[0]].nunique() <= 10 else None - - scatter_encoding = { - 'x': alt.X(f'{col1}:Q', title=col1), - 'y': alt.Y(f'{col2}:Q', title=col2), - 'tooltip': [col1, col2] - } - - if color_col: - scatter_encoding['color'] = alt.Color(f'{color_col}:N', title=color_col) - scatter_encoding['tooltip'].append(color_col) - - scatter_chart = alt.Chart(df).mark_circle( - size=60, - opacity=0.6 - ).encode( - **scatter_encoding - ).properties( - title=f'🔵 {col1} vs {col2} 散点图', - height=350 - ).interactive() - - charts.append(('scatter', scatter_chart, f'{col1} 与 {col2} 的关系')) - - # 4. 箱线图(数值列按分类) - if numeric_cols and cat_cols: - num_col = numeric_cols[0] - cat_col = cat_cols[0] - if df[cat_col].nunique() <= 10: - box_chart = alt.Chart(df).mark_boxplot( - color='#11998e' - ).encode( - x=alt.X(f'{cat_col}:N', title=cat_col), - y=alt.Y(f'{num_col}:Q', title=num_col), - color=alt.Color(f'{cat_col}:N', legend=None) - ).properties( - title=f'📦 {num_col} 按 {cat_col} 分组箱线图', - height=300 - ) - charts.append(('boxplot', box_chart, f'{num_col} 在不同 {cat_col} 下的分布')) - - # 5. 相关性热力图(如果有多个数值列) - if len(numeric_cols) >= 3: - corr_df = df[numeric_cols].corr().reset_index().melt(id_vars='index') - corr_df.columns = ['var1', 'var2', 'correlation'] - - heatmap = alt.Chart(corr_df).mark_rect().encode( - x=alt.X('var1:N', title=''), - y=alt.Y('var2:N', title=''), - color=alt.Color('correlation:Q', - scale=alt.Scale(scheme='redblue', domain=[-1, 1]), - title='相关系数'), - tooltip=['var1', 'var2', alt.Tooltip('correlation:Q', format='.2f')] - ).properties( - title='🔥 相关性热力图', - height=300 - ) - charts.append(('heatmap', heatmap, '各数值变量间的相关性')) - - return charts - - -# ============== 初始化 Session State ============== - -if "df" not in st.session_state: - st.session_state.df = None - -if "data_summary" not in st.session_state: - st.session_state.data_summary = None - -if "analyses" not in st.session_state: - st.session_state.analyses = {} - -if "qa_history" not in st.session_state: - st.session_state.qa_history = [] - -# ============== 侧边栏 ============== - -with st.sidebar: - st.markdown("## 🔧 设置") - - # API Key 输入 - api_key_input = st.text_input( - "DeepSeek API Key", - value=API_KEY, - type="password", - help="输入你的 DeepSeek API Key" - ) - - if api_key_input: - API_KEY = api_key_input - - st.divider() - - # 文件上传 - st.markdown("## 📁 数据上传") - - uploaded_file = st.file_uploader( - "上传 CSV 文件", - type=['csv'], - help="支持 CSV 格式的数据文件" - ) - - # 或使用示例数据 - use_sample = st.checkbox("使用示例数据", value=False) - - if use_sample: - # 生成示例数据 - import numpy as np - np.random.seed(42) - - sample_df = pd.DataFrame({ - '姓名': [f'员工{i}' for i in range(1, 101)], - '部门': np.random.choice(['技术部', '市场部', '财务部', '人事部', '运营部'], 100), - '年龄': np.random.randint(22, 55, 100), - '工龄': np.random.randint(1, 20, 100), - '月薪': np.random.randint(8000, 50000, 100), - '绩效评分': np.round(np.random.uniform(60, 100, 100), 1), - '满意度': np.round(np.random.uniform(1, 5, 100), 1) - }) - - st.session_state.df = sample_df - st.session_state.data_summary = get_data_summary(sample_df) - st.success("✅ 已加载示例数据") - - elif uploaded_file is not None: - try: - df = pd.read_csv(uploaded_file) - st.session_state.df = df - st.session_state.data_summary = get_data_summary(df) - st.session_state.analyses = {} # 重置分析结果 - st.session_state.qa_history = [] # 重置问答历史 - st.success(f"✅ 成功加载 {len(df)} 行数据") - except Exception as e: - st.error(f"❌ 文件加载失败: {str(e)}") - - # 显示数据信息 - if st.session_state.df is not None: - st.divider() - st.markdown("### 📊 数据概览") - df = st.session_state.df - st.markdown(f"- **行数**: {len(df)}") - st.markdown(f"- **列数**: {len(df.columns)}") - st.markdown(f"- **数值列**: {len(df.select_dtypes(include=['number']).columns)}") - st.markdown(f"- **分类列**: {len(df.select_dtypes(include=['object', 'category']).columns)}") - -# ============== 主界面 ============== - -st.markdown('

📊 AI 数据分析师

', unsafe_allow_html=True) -st.markdown("*上传数据,让 AI 帮你发现数据中的故事*") - -# 检查 API Key -if not API_KEY: - st.warning("⚠️ 请在侧边栏输入你的 DeepSeek API Key") - st.stop() - -# 检查数据 -if st.session_state.df is None: - st.info("👈 请在侧边栏上传 CSV 文件或使用示例数据") - - # 显示使用说明 - with st.expander("📖 使用说明", expanded=True): - st.markdown(""" - ### 欢迎使用 AI 数据分析师! - - **功能介绍:** - 1. **📈 数据预览** - 查看数据基本信息和统计摘要 - 2. **📊 智能可视化** - 自动生成适合数据的图表 - 3. **🤖 AI 分析** - AI 深度分析数据特征和洞察 - 4. **💬 数据问答** - 用自然语言询问关于数据的问题 - 5. **📝 生成报告** - 一键生成完整的分析报告 - - **开始使用:** - 1. 在左侧边栏输入你的 DeepSeek API Key - 2. 上传 CSV 文件或勾选"使用示例数据" - 3. 切换不同标签页探索各项功能 - """) - st.stop() - -# 创建 OpenAI 客户端 -client = OpenAI(api_key=API_KEY, base_url=BASE_URL) -df = st.session_state.df - -# 创建标签页 -tab1, tab2, tab3, tab4, tab5 = st.tabs([ - "📈 数据预览", - "📊 智能可视化", - "🤖 AI 分析", - "💬 数据问答", - "📝 生成报告" -]) - -# ============== Tab 1: 数据预览 ============== -with tab1: - st.header("📈 数据预览") - - # 统计卡片 - col1, col2, col3, col4 = st.columns(4) - - with col1: - st.markdown(f""" -
-

{len(df)}

-

数据行数

-
- """, unsafe_allow_html=True) - - with col2: - st.markdown(f""" -
-

{len(df.columns)}

-

数据列数

-
- """, unsafe_allow_html=True) - - with col3: - missing = df.isnull().sum().sum() - st.markdown(f""" -
-

{missing}

-

缺失值数量

-
- """, unsafe_allow_html=True) - - with col4: - numeric_cols = len(df.select_dtypes(include=['number']).columns) - st.markdown(f""" -
-

{numeric_cols}

-

数值列数量

-
- """, unsafe_allow_html=True) - - st.markdown("---") - - # 数据表格 - st.subheader("📋 数据表格") - st.dataframe(df, use_container_width=True, height=400) - - # 统计摘要 - col_left, col_right = st.columns(2) - - with col_left: - st.subheader("📊 数值列统计") - numeric_df = df.select_dtypes(include=['number']) - if not numeric_df.empty: - st.dataframe(numeric_df.describe(), use_container_width=True) - else: - st.info("没有数值列") - - with col_right: - st.subheader("📝 列信息") - info_df = pd.DataFrame({ - '列名': df.columns, - '数据类型': df.dtypes.astype(str).values, - '非空值数': df.count().values, - '唯一值数': [df[col].nunique() for col in df.columns] - }) - st.dataframe(info_df, use_container_width=True, hide_index=True) - -# ============== Tab 2: 智能可视化 ============== -with tab2: - st.header("📊 智能可视化") - st.markdown("*根据数据特征自动生成适合的图表*") - - charts = create_visualizations(df) - - if not charts: - st.warning("数据列类型不足以生成可视化图表") - else: - for i, (chart_type, chart, description) in enumerate(charts): - st.markdown(f"**{description}**") - st.altair_chart(chart, use_container_width=True) - if i < len(charts) - 1: - st.divider() - -# ============== Tab 3: AI 分析 ============== -with tab3: - st.header("🤖 AI 智能分析") - - analysis_type = st.selectbox( - "选择分析类型", - options=[ - ("general", "🔍 综合分析 - 全面了解数据特征"), - ("correlation", "🔗 相关性分析 - 探索变量间关系"), - ("anomaly", "⚠️ 异常检测 - 发现数据问题") - ], - format_func=lambda x: x[1] - ) - - if st.button("🚀 开始 AI 分析", type="primary", use_container_width=True): - with st.spinner("AI 正在分析数据,请稍候..."): - try: - result = analyze_with_ai( - client, - st.session_state.data_summary, - analysis_type[0] - ) - st.session_state.analyses[analysis_type[0]] = result - st.success("✅ 分析完成!") - except Exception as e: - st.error(f"❌ 分析出错: {str(e)}") - - # 显示分析结果 - if analysis_type[0] in st.session_state.analyses: - st.markdown("### 📋 分析结果") - st.markdown(st.session_state.analyses[analysis_type[0]]) - - # 显示历史分析 - other_analyses = {k: v for k, v in st.session_state.analyses.items() if k != analysis_type[0]} - if other_analyses: - st.divider() - with st.expander("📚 查看其他分析结果"): - for key, value in other_analyses.items(): - type_names = {"general": "综合分析", "correlation": "相关性分析", "anomaly": "异常检测"} - st.markdown(f"#### {type_names.get(key, key)}") - st.markdown(value) - st.divider() - -# ============== Tab 4: 数据问答 ============== -with tab4: - st.header("💬 数据问答") - st.markdown("*用自然语言询问关于数据的任何问题*") - - # 示例问题 - with st.expander("💡 示例问题"): - st.markdown(""" - - 这个数据集的主要特征是什么? - - 哪个部门的平均薪资最高? - - 年龄和工资之间有什么关系? - - 数据中有哪些异常值? - - 如何提高员工满意度? - """) - - # 显示对话历史 - for msg in st.session_state.qa_history: - avatar = "👤" if msg["role"] == "user" else "🤖" - with st.chat_message(msg["role"], avatar=avatar): - st.markdown(msg["content"]) - - # 问题输入 - if question := st.chat_input("输入你关于数据的问题..."): - # 显示用户问题 - with st.chat_message("user", avatar="👤"): - st.markdown(question) - - # AI 回答 - with st.chat_message("assistant", avatar="🤖"): - with st.spinner("思考中..."): - try: - answer = ask_data_question( - client, - st.session_state.data_summary, - question, - st.session_state.qa_history - ) - st.markdown(answer) - - # 保存对话历史 - st.session_state.qa_history.append({"role": "user", "content": question}) - st.session_state.qa_history.append({"role": "assistant", "content": answer}) - - except Exception as e: - st.error(f"❌ 回答出错: {str(e)}") - - # 清空对话按钮 - if st.session_state.qa_history: - if st.button("🗑️ 清空对话历史"): - st.session_state.qa_history = [] - st.rerun() - -# ============== Tab 5: 生成报告 ============== -with tab5: - st.header("📝 数据分析报告") - - if not st.session_state.analyses: - st.info("💡 请先在「AI 分析」标签页进行分析,然后再生成报告") - else: - st.markdown("*基于已有分析结果生成完整的数据分析报告*") - - if st.button("📄 生成分析报告", type="primary", use_container_width=True): - with st.spinner("正在生成报告,请稍候..."): - try: - report = generate_report( - client, - st.session_state.data_summary, - st.session_state.analyses - ) - st.session_state.report = report - st.success("✅ 报告生成完成!") - except Exception as e: - st.error(f"❌ 生成报告出错: {str(e)}") - - # 显示报告 - if "report" in st.session_state: - st.markdown("---") - st.markdown(st.session_state.report) - - # 下载按钮 - st.download_button( - label="📥 下载报告 (Markdown)", - data=st.session_state.report, - file_name="数据分析报告.md", - mime="text/markdown" - ) - -# ============== 页脚 ============== -st.divider() -st.caption("Made with ❤️ using DeepSeek API + Streamlit | Python 程序设计课程设计示例") - diff --git a/示例项目-AI数据分析师/requirements.txt b/示例项目-AI数据分析师/requirements.txt deleted file mode 100644 index 1f57f78..0000000 --- a/示例项目-AI数据分析师/requirements.txt +++ /dev/null @@ -1,7 +0,0 @@ -streamlit>=1.28.0 -openai>=1.0.0 -python-dotenv>=1.0.0 -pandas>=2.0.0 -altair>=5.0.0 -numpy>=1.24.0 - diff --git a/示例项目-AI数据分析师/sample_data.csv b/示例项目-AI数据分析师/sample_data.csv deleted file mode 100644 index 3bf69d3..0000000 --- a/示例项目-AI数据分析师/sample_data.csv +++ /dev/null @@ -1,30 +0,0 @@ -姓名,部门,年龄,工龄,月薪,绩效评分,满意度 -张三,技术部,28,3,15000,85.5,4.2 -李四,市场部,32,5,18000,78.3,3.8 -王五,财务部,45,15,35000,92.1,4.5 -赵六,技术部,26,2,12000,88.7,4.0 -钱七,人事部,38,10,25000,76.5,3.5 -孙八,运营部,29,4,14000,82.3,4.1 -周九,技术部,35,8,28000,95.2,4.8 -吴十,市场部,27,3,13500,79.8,3.9 -郑十一,财务部,42,12,32000,88.9,4.3 -王十二,技术部,31,6,22000,91.5,4.6 -李十三,人事部,36,9,24000,75.2,3.4 -张十四,运营部,24,1,10000,70.5,3.2 -刘十五,技术部,33,7,25000,89.3,4.4 -陈十六,市场部,29,4,16000,81.7,4.0 -杨十七,财务部,48,18,42000,94.8,4.7 -黄十八,技术部,27,2,14000,86.2,4.1 -赵十九,人事部,41,13,28000,77.9,3.6 -钱二十,运营部,30,5,17000,83.4,4.2 -孙廿一,技术部,25,1,11000,72.8,3.3 -周廿二,市场部,34,7,21000,85.6,4.3 -吴廿三,财务部,39,11,30000,90.2,4.5 -郑廿四,技术部,28,3,16000,87.1,4.2 -王廿五,人事部,43,14,29000,78.5,3.7 -李廿六,运营部,26,2,12500,74.3,3.4 -张廿七,技术部,37,9,27000,93.6,4.7 -刘廿八,市场部,31,5,19000,80.9,3.9 -陈廿九,财务部,46,16,38000,91.8,4.6 -杨三十,技术部,29,4,18000,88.4,4.3 - diff --git a/示例项目-角色扮演聊天室/.env_example b/示例项目-角色扮演聊天室/.env_example deleted file mode 100644 index 995fc5c..0000000 --- a/示例项目-角色扮演聊天室/.env_example +++ /dev/null @@ -1,9 +0,0 @@ -# DeepSeek API Key 配置示例 -# ================================ -# 使用方法: -# 1. 将此文件复制并重命名为 .env -# 2. 将下面的 sk-xxx... 替换为你的真实 API Key -# ================================ - -DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - diff --git a/示例项目-角色扮演聊天室/.gitignore b/示例项目-角色扮演聊天室/.gitignore deleted file mode 100644 index fe0b7a4..0000000 --- a/示例项目-角色扮演聊天室/.gitignore +++ /dev/null @@ -1,21 +0,0 @@ -# 环境变量(包含敏感信息) -.env - -# Python -__pycache__/ -*.py[cod] -*$py.class -*.so -.Python -venv/ -ENV/ - -# IDE -.vscode/ -.idea/ -*.swp -*.swo - -# macOS -.DS_Store - diff --git a/示例项目-角色扮演聊天室/README.md b/示例项目-角色扮演聊天室/README.md deleted file mode 100644 index 8afa2f1..0000000 --- a/示例项目-角色扮演聊天室/README.md +++ /dev/null @@ -1,220 +0,0 @@ -# 🎭 AI 角色扮演聊天室 - -一个基于 DeepSeek API + Streamlit 构建的角色扮演聊天应用,支持多种预设角色和自定义角色创建。 - -![Python](https://img.shields.io/badge/Python-3.10+-blue.svg) -![Streamlit](https://img.shields.io/badge/Streamlit-1.28+-red.svg) -![DeepSeek](https://img.shields.io/badge/DeepSeek-API-green.svg) - -## ✨ 功能特性 - -- 🎭 **多种预设角色**:傲娇猫娘、智慧老者、毒舌AI、科学怪人等 -- ✨ **自定义角色**:创建你想象中的任何角色 -- 💬 **多轮对话**:保留对话历史,角色会记住上下文 -- ⚡ **流式输出**:打字机效果,实时显示 AI 回复 -- 🎨 **美观界面**:精心设计的 UI,渐变色彩和动画效果 - -## 🖼️ 界面预览 - -``` -┌─────────────────────────────────────────────────────────────┐ -│ 🎭 角色设置 │ 🎭 AI 角色扮演聊天室 │ -│ ───────────── │ ───────────────────── │ -│ 🔑 API 配置 │ │ -│ [DeepSeek API Key] │ 🐱 │ -│ ───────────── │ 正在与 小喵 对话 │ -│ 🎭 选择角色 │ │ -│ [🐱 傲娇猫娘 ▼] │ ──────────────────────────── │ -│ │ │ -│ ┌─────────────────┐ │ 👤: 你好呀! │ -│ │ 🐱 小喵 │ │ │ -│ │ 你是一个傲娇的 │ │ 🐱: 哼,才不是特意来跟你打招 │ -│ │ 猫娘... │ │ 呼的呢!...喵~ (。・ω・。) │ -│ └─────────────────┘ │ │ -│ │ ──────────────────────────── │ -│ [🗑️ 清空对话历史] │ [输入你想说的话... ] │ -└─────────────────────────────────────────────────────────────┘ -``` - -## 🚀 快速开始 - -### 1. 克隆/下载项目 - -```bash -cd 示例项目-角色扮演聊天室 -``` - -### 2. 创建虚拟环境(推荐) - -```bash -python -m venv venv - -# Windows -venv\Scripts\activate - -# macOS/Linux -source venv/bin/activate -``` - -### 3. 安装依赖 - -```bash -pip install -r requirements.txt -``` - -### 4. 配置 API Key - -复制环境变量示例文件: - -```bash -cp .env.example .env -``` - -编辑 `.env` 文件,填入你的 DeepSeek API Key: - -``` -DEEPSEEK_API_KEY=sk-your-actual-api-key -``` - -> 💡 **获取 API Key**:访问 [DeepSeek 开放平台](https://platform.deepseek.com),注册账号后在控制台创建。 - -### 5. 运行应用 - -```bash -streamlit run app.py -``` - -应用将在浏览器中自动打开,默认地址:http://localhost:8501 - -## 📁 项目结构 - -``` -示例项目-角色扮演聊天室/ -├── app.py # 主程序 -├── requirements.txt # 项目依赖 -├── .env.example # 环境变量示例 -├── .env # 环境变量(需自行创建,不要提交!) -├── .gitignore # Git 忽略文件 -└── README.md # 项目说明 -``` - -## 🎭 预设角色介绍 - -| 角色 | 名称 | 特点 | -|:---:|:---|:---| -| 🐱 | 傲娇猫娘·小喵 | 傲娇但可爱,句尾带"喵~",会用颜文字 | -| 🧙 | 智慧老者·玄清子 | 富有哲理,喜欢引用古诗词 | -| 🤖 | 毒舌AI·犀利哥 | 说话犀利一针见血,但有建设性 | -| 👨‍🔬 | 科学怪人·Dr.Eureka | 疯狂科学家,热衷科学分析 | -| 🎮 | 游戏解说·电竞小王 | 充满激情,使用游戏术语 | -| 📚 | 文艺青年·林小诗 | 说话有诗意,会即兴创作 | - -## 🛠️ 技术实现 - -### 核心技术点 - -1. **DeepSeek API 调用** - - 使用 OpenAI SDK 兼容接口 - - 流式输出(Streaming)实现打字机效果 - -2. **Streamlit 组件** - - `st.chat_message` - 聊天消息展示 - - `st.chat_input` - 聊天输入框 - - `st.session_state` - 对话历史管理 - - `st.write_stream` - 流式输出渲染 - -3. **角色扮演机制** - - System Prompt 定义角色性格和说话方式 - - 多轮对话保持角色一致性 - -### 关键代码解析 - -#### 流式输出实现 - -```python -stream = client.chat.completions.create( - model=MODEL, - messages=messages_for_api, - stream=True, # 启用流式输出 -) - -response = st.write_stream( - chunk.choices[0].delta.content or "" - for chunk in stream - if chunk.choices[0].delta.content -) -``` - -#### 对话历史管理 - -```python -# 初始化 -if "messages" not in st.session_state: - st.session_state.messages = [] - -# 添加消息 -st.session_state.messages.append({"role": "user", "content": prompt}) - -# 构建 API 请求 -messages_for_api = [ - {"role": "system", "content": system_prompt} # 角色设定 -] + st.session_state.messages # 历史消息 -``` - -## 🎨 自定义角色指南 - -创建一个好的自定义角色,需要在角色设定中包含: - -1. **身份定义**:角色是谁,背景是什么 -2. **性格特点**:外向/内向、温柔/严厉等 -3. **说话方式**:口癖、常用词、语气 -4. **对用户态度**:如何称呼用户,关系定位 -5. **特殊行为**:是否使用emoji、颜文字等 - -### 示例:创建一个"中二少年"角色 - -``` -你是一个中二病少年,自称"黑暗骑士·雷恩"。你的特点: -- 认为自己拥有被封印的黑暗力量 -- 经常用"我的右手又在疼了..."这样的台词 -- 说话夸张,喜欢用"区区凡人"称呼用户 -- 会假装痛苦地按住眼睛说"黑暗之眼快要觉醒了" -- 其实很好说话,问什么都会认真回答(虽然用中二的方式) -``` - -## 📝 开发心得 - -这个项目使用 **Vibe Coding** 方式开发,主要通过自然语言描述需求,让 AI 代码编辑器生成代码。 - -**开发过程中的 Prompt 示例:** - -> "帮我创建一个角色扮演聊天应用,使用 DeepSeek API 和 Streamlit。 -> 要求:左侧边栏选择角色,支持自定义角色,聊天界面要美观, -> 使用流式输出,要保存对话历史。" - -**迭代优化:** - -> "给界面加上渐变色效果,让角色卡片更好看一些" - -> "添加一个清空对话的按钮" - -## ⚠️ 注意事项 - -1. **保护 API Key**:不要将 `.env` 文件提交到代码仓库 -2. **控制成本**:DeepSeek API 按 Token 计费,长对话会消耗更多 Token -3. **角色设定**:过长的 System Prompt 会增加每次请求的成本 - -## 📚 参考资料 - -- [DeepSeek API 文档](https://platform.deepseek.com/api-docs) -- [Streamlit 官方文档](https://docs.streamlit.io) -- [OpenAI Python SDK](https://github.com/openai/openai-python) - -## 👤 作者 - -Python 程序设计课程设计 - 示例项目 - ---- - -**Happy Vibe Coding! 🚀** - diff --git a/示例项目-角色扮演聊天室/app.py b/示例项目-角色扮演聊天室/app.py deleted file mode 100644 index 57cc3fa..0000000 --- a/示例项目-角色扮演聊天室/app.py +++ /dev/null @@ -1,379 +0,0 @@ -""" -AI 角色扮演聊天室 -================ -一个基于 DeepSeek API + Streamlit 的角色扮演聊天应用 - -功能特性: -- 🎭 多种预设角色可选 -- ✨ 支持自定义角色 -- 💬 多轮对话,保留历史 -- ⚡ 流式输出,打字机效果 -- 🎨 美观的聊天界面 -""" - -import streamlit as st -from openai import OpenAI -import os -from dotenv import load_dotenv - -# 加载环境变量 -load_dotenv() - -# ============== 配置区域 ============== - -# DeepSeek API 配置 -API_KEY = os.getenv("DEEPSEEK_API_KEY", "") -BASE_URL = "https://api.deepseek.com" -MODEL = "deepseek-chat" - -# 预设角色配置 -PRESET_CHARACTERS = { - "🐱 傲娇猫娘": { - "name": "小喵", - "avatar": "🐱", - "system_prompt": """你是一个傲娇的猫娘,名叫小喵。你的性格特点: -- 说话时经常在句尾加上"喵~" -- 表面上高冷傲娇,其实内心很温柔 -- 偶尔会用"哼"、"才不是呢"这样的口癖 -- 对主人(用户)有点小傲娇,但会认真回答问题 -- 会用一些可爱的颜文字,如 (。・ω・。) 、(=^・ω・^=) -请保持角色扮演,用可爱傲娇的方式回应用户。""" - }, - "🧙 智慧老者": { - "name": "玄清子", - "avatar": "🧙", - "system_prompt": """你是一位睿智的老者,道号玄清子,已修行百年。你的特点: -- 说话富有哲理,喜欢用比喻和寓言 -- 经常引用古诗词或经典语录 -- 对人生有深刻的洞察 -- 语气平和从容,有种看透世事的淡然 -- 会称呼用户为"施主"或"年轻人" -请以智慧老者的身份,用富有哲理的方式回应用户。""" - }, - "🤖 毒舌AI": { - "name": "犀利哥", - "avatar": "🤖", - "system_prompt": """你是一个毒舌但有道理的AI助手,叫犀利哥。你的特点: -- 说话直接犀利,一针见血 -- 喜欢吐槽,但吐槽中带着真知灼见 -- 会用幽默讽刺的方式指出问题 -- 虽然嘴毒但其实是刀子嘴豆腐心 -- 偶尔会说"我说的对吧?"来确认 -请保持毒舌但有建设性的风格回应用户。注意:吐槽要有分寸,不要真的伤害用户。""" - }, - "👨‍🔬 科学怪人": { - "name": "Dr. Eureka", - "avatar": "👨‍🔬", - "system_prompt": """你是一个疯狂但天才的科学家,叫 Dr. Eureka。你的特点: -- 对科学充满狂热的热情 -- 说话时经常穿插科学术语和公式 -- 喜欢说"Eureka!"(我发现了!) -- 会把日常问题用科学角度来分析 -- 经常有一些异想天开但有道理的想法 -- 语气夸张,充满戏剧性 -请以疯狂科学家的身份,用充满科学热情的方式回应用户。""" - }, - "🎮 游戏解说": { - "name": "电竞小王", - "avatar": "🎮", - "system_prompt": """你是一个热情的游戏主播/解说,叫电竞小王。你的特点: -- 说话充满激情和能量 -- 经常使用游戏术语和梗 -- 喜欢用"老铁"、"兄弟们"称呼用户 -- 会把问题类比成游戏场景 -- 偶尔会喊出"666"、"太强了"等口头禅 -- 语气热血,像在解说比赛一样 -请以游戏解说的风格,用充满激情的方式回应用户。""" - }, - "📚 文艺青年": { - "name": "林小诗", - "avatar": "📚", - "system_prompt": """你是一个文艺气息浓厚的青年,叫林小诗。你的特点: -- 说话富有诗意和文学性 -- 喜欢引用诗词、文学作品 -- 对生活中的小事有独特的感悟 -- 偶尔会即兴写一两句诗 -- 语气温柔感性,有点小忧郁 -- 喜欢用省略号营造氛围感 -请以文艺青年的身份,用充满诗意的方式回应用户。""" - } -} - -# ============== 页面配置 ============== - -st.set_page_config( - page_title="AI 角色扮演聊天室", - page_icon="🎭", - layout="wide", - initial_sidebar_state="expanded" -) - -# ============== 自定义样式 ============== - -st.markdown(""" - -""", unsafe_allow_html=True) - -# ============== 初始化 Session State ============== - -if "messages" not in st.session_state: - st.session_state.messages = [] - -if "current_character" not in st.session_state: - st.session_state.current_character = None - -if "character_config" not in st.session_state: - st.session_state.character_config = None - -# ============== 侧边栏 ============== - -with st.sidebar: - st.title("🎭 角色设置") - - # API Key 输入 - st.subheader("🔑 API 配置") - api_key_input = st.text_input( - "DeepSeek API Key", - value=API_KEY, - type="password", - help="请输入你的 DeepSeek API Key" - ) - - if api_key_input: - API_KEY = api_key_input - - st.divider() - - # 角色选择 - st.subheader("🎭 选择角色") - - # 预设角色选择 - character_options = ["🎨 自定义角色"] + list(PRESET_CHARACTERS.keys()) - selected_character = st.selectbox( - "预设角色", - options=character_options, - index=0 if st.session_state.current_character is None else ( - character_options.index(st.session_state.current_character) - if st.session_state.current_character in character_options - else 0 - ) - ) - - # 自定义角色设置 - if selected_character == "🎨 自定义角色": - st.markdown("---") - st.markdown("**✨ 创建你的专属角色**") - - custom_name = st.text_input("角色名称", placeholder="例如:小助手") - custom_avatar = st.selectbox( - "选择头像", - options=["🤖", "👽", "🦊", "🐼", "🦁", "🐸", "👻", "🎃", "🌟", "💫"], - index=0 - ) - custom_prompt = st.text_area( - "角色设定", - placeholder="描述角色的性格、说话方式、特点等...\n\n例如:你是一个活泼开朗的助手,喜欢用emoji表情,说话很有活力...", - height=150 - ) - - if custom_name and custom_prompt: - st.session_state.character_config = { - "name": custom_name, - "avatar": custom_avatar, - "system_prompt": custom_prompt - } - st.session_state.current_character = "🎨 自定义角色" - else: - # 使用预设角色 - st.session_state.character_config = PRESET_CHARACTERS[selected_character] - st.session_state.current_character = selected_character - - # 显示角色信息 - config = PRESET_CHARACTERS[selected_character] - st.markdown(f""" -
-

{config['avatar']} {config['name']}

-

{config['system_prompt'][:100]}...

-
- """, unsafe_allow_html=True) - - st.divider() - - # 清空对话按钮 - if st.button("🗑️ 清空对话历史", use_container_width=True): - st.session_state.messages = [] - st.rerun() - - # 显示统计信息 - st.divider() - st.caption(f"📊 当前对话: {len(st.session_state.messages)} 条消息") - -# ============== 主界面 ============== - -st.title("🎭 AI 角色扮演聊天室") - -# 检查配置 -if not API_KEY: - st.warning("⚠️ 请在侧边栏输入你的 DeepSeek API Key") - st.info(""" - **如何获取 API Key?** - 1. 访问 [DeepSeek 开放平台](https://platform.deepseek.com) - 2. 注册并登录账号 - 3. 进入控制台创建 API Key - """) - st.stop() - -if not st.session_state.character_config: - st.info("👈 请在侧边栏选择一个角色或创建自定义角色") - st.stop() - -# 显示当前角色信息 -current_config = st.session_state.character_config -col1, col2 = st.columns([1, 4]) -with col1: - st.markdown(f"

{current_config['avatar']}

", unsafe_allow_html=True) -with col2: - st.markdown(f"### 正在与 **{current_config['name']}** 对话") - st.caption("试着和 TA 聊聊天吧!") - -st.divider() - -# 创建 OpenAI 客户端 -client = OpenAI(api_key=API_KEY, base_url=BASE_URL) - -# 显示对话历史 -for message in st.session_state.messages: - avatar = current_config["avatar"] if message["role"] == "assistant" else "👤" - with st.chat_message(message["role"], avatar=avatar): - st.markdown(message["content"]) - -# 用户输入 -if prompt := st.chat_input("输入你想说的话..."): - # 添加用户消息 - st.session_state.messages.append({"role": "user", "content": prompt}) - with st.chat_message("user", avatar="👤"): - st.markdown(prompt) - - # 构建完整的消息列表 - messages_for_api = [ - {"role": "system", "content": current_config["system_prompt"]} - ] + st.session_state.messages - - # 调用 API 并流式输出 - with st.chat_message("assistant", avatar=current_config["avatar"]): - try: - stream = client.chat.completions.create( - model=MODEL, - messages=messages_for_api, - stream=True, - max_tokens=2000, - temperature=0.8, # 稍高的温度让角色更有个性 - ) - - response = st.write_stream( - chunk.choices[0].delta.content or "" - for chunk in stream - if chunk.choices[0].delta.content - ) - - # 保存助手回复 - st.session_state.messages.append({"role": "assistant", "content": response}) - - except Exception as e: - st.error(f"❌ 调用 API 出错: {str(e)}") - st.info("请检查 API Key 是否正确,以及网络连接是否正常。") - -# ============== 底部信息 ============== - -st.divider() - -with st.expander("💡 使用提示"): - st.markdown(""" - **如何获得更好的角色扮演体验?** - - 1. **选择合适的角色**:不同角色有不同的说话风格和个性 - 2. **融入角色设定**:尝试用符合角色世界观的方式提问 - 3. **自定义角色**:发挥创意,创建你想要的任何角色 - 4. **多轮对话**:角色会记住之前的对话内容 - - **自定义角色技巧:** - - 明确角色的性格特点 - - 定义说话方式和口癖 - - 设定角色的背景故事 - - 指定角色对用户的称呼 - """) - -st.caption("Made with ❤️ using DeepSeek API + Streamlit | Python 程序设计课程设计示例") - diff --git a/示例项目-角色扮演聊天室/requirements.txt b/示例项目-角色扮演聊天室/requirements.txt deleted file mode 100644 index 52ce1f1..0000000 --- a/示例项目-角色扮演聊天室/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -streamlit>=1.28.0 -openai>=1.0.0 -python-dotenv>=1.0.0 -