from flask import Flask, render_template, request, jsonify import os import requests import time import threading app = Flask(__name__) # 预定义的响应文本 responses = { "btn1": "你好!欢迎使用这个文本逐字显示演示。这是按钮1的响应内容。", "btn2": "这是按钮2的响应内容。逐字显示效果可以让信息呈现更加生动有趣。", "btn3": "按钮3被点击了!这个功能可以用来创建聊天机器人或者交互式故事。", "btn4": "感谢您测试这个功能。逐字显示模拟了人类打字的效果,增强了用户体验。" } # DeepSeek API 配置 #DEEPSEEK_API_URL = "https://api.deepseek.com/" # 请确认实际API地址 DEEPSEEK_API_URL = "https://api.deepseek.com/chat/completions" # 请确认实际API地址 DEEPSEEK_API_KEY = os.getenv('DEEPSEEK_API_KEY') # 从系统环境变量读取 @app.route('/') def index(): return render_template('index.html') @app.route('/get_response', methods=['POST']) def get_response(): data = request.json button_id = data.get('button_id') response_text = responses.get(button_id, "未知按钮") # 返回整个文本,前端会处理逐字显示 return jsonify({"text": response_text}) @app.route('/call_deepseek', methods=['POST']) def call_deepseek(): user_input = request.json.get('user_input') if not user_input: return jsonify({"error": "No input provided"}), 400 try: # 调用 DeepSeek API headers = { "Authorization": f"Bearer {DEEPSEEK_API_KEY}", "Content-Type": "application/json" } payload = { "model": "deepseek-v4-pro", # 根据实际情况调整 "messages": [ {"role": "user", "content": user_input} ], # "temperature": 0.7 "thinking": {"type": "enabled"}, "reasoning_effort": "high", "stream": False } response = requests.post(DEEPSEEK_API_URL, json=payload, headers=headers) response.raise_for_status() # 解析响应 - 根据DeepSeek API实际返回结构调整 api_response = response.json() reply_content = api_response['choices'][0]['message']['content'] return jsonify({"text": reply_content}) except requests.exceptions.RequestException as e: return jsonify({"error": f"API调用失败: {str(e)}"}), 500 if __name__ == '__main__': app.run(debug=True) 改用流式,其他地方如何相应调整 我们被问到一个问题:代码中有一个Flask应用,调用DeepSeek API目前的请求是非流式的("stream": False)。用户希望改用流式,问“其他地方如何相应调整”。需要分析前端和后端的修改。前端负责接收流式数据并逐步显示,后端需要返回流式响应(SSE或分块传输)。用户给出了后端代码,但没有前端代码。我们需要提供调整建议。输出应该是中文,详细说明后端和前端需要改动的地方。 要将 DeepSeek API 调用改为流式(stream: True),你的后端和前端都需要做相应调整。下面我会分别说明具体的改动方法。 一、后端调整(Flask) 当前代码是非流式的一次性请求,返回完整 JSON。改为流式后,需要: 修改 payload:将 "stream": False 改为 "stream": True(可以省略该字段,默认为 False,所以必须显式设为 True)。 修改响应方式:后端不能直接 return jsonify(...),而要返回一个流式响应(Response 对象,设置 content_type='text/event-stream' 或 'text/plain'),并逐步向前端发送数据块(data chunks)。 逐块处理 API 响应流:DeepSeek API 会返回 SSE(Server-Sent Events)格式的数据,每行以 data: 开头,最后以 data: [DONE] 结束。你需要解析这些行,提取出每次的内容增量(delta),再转发给前端。 修改后的后端代码示例 python from flask import Flask, render_template, request, Response, jsonify import os import requests import json @app.route('/call_deepseek_stream', methods=['POST']) def call_deepseek_stream(): user_input = request.json.get('user_input') if not user_input: return jsonify({"error": "No input provided"}), 400 def generate(): headers = { "Authorization": f"Bearer {DEEPSEEK_API_KEY}", "Content-Type": "application/json" } payload = { "model": "deepseek-v4-pro", "messages": [{"role": "user", "content": user_input}], "stream": True, # 启用流式 "thinking": {"type": "enabled"}, "reasoning_effort": "high" } try: # 发送流式请求 response = requests.post(DEEPSEEK_API_URL, json=payload, headers=headers, stream=True) response.raise_for_status() # 逐行读取 API 返回的 SSE 数据 for line in response.iter_lines(decode_unicode=True): if line: # 去掉 "data: " 前缀 if line.startswith('data: '): data_str = line[6:] else: data_str = line # 检查结束标志 if data_str == '[DONE]': break try: chunk = json.loads(data_str) # 根据 DeepSeek API 响应结构提取内容增量 delta = chunk['choices'][0]['delta'] content = delta.get('content', '') if content: # 将每段内容发送给前端(SSE 格式) yield f"data: {json.dumps({'text': content})}\n\n" except json.JSONDecodeError: continue except Exception as e: yield f"data: {json.dumps({'error': str(e)})}\n\n" return Response(generate(), content_type='text/event-stream') 说明: 使用 requests.post(..., stream=True) 保持连接,逐行读取响应。 用生成器 generate() 不断 yield 符合 SSE 格式的数据给前端。 每收到一个 delta 中的 content,就立即转发。 前端通过 EventSource 或 fetch + ReadableStream 接收。 二、前端调整 前端原本可能是用 fetch 或 axios 等待完整 JSON 响应。流式场景下需要改为逐块接收并实时更新页面文字。 1. 使用 fetch + ReadableStream(推荐) javascript async function callDeepSeekStream(userInput) { const response = await fetch('/call_deepseek_stream', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ user_input: userInput }) }); const reader = response.body.getReader(); const decoder = new TextDecoder('utf-8'); let buffer = ''; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); // 按行分割 SSE 消息(每条消息以 \n\n 结束) const lines = buffer.split('\n\n'); buffer = lines.pop(); // 剩余未完整的数据留到下次 for (const line of lines) { if (line.startsWith('data: ')) { const dataStr = line.slice(6); if (dataStr === '[DONE]') continue; try { const data = JSON.parse(dataStr); if (data.text) { // 累加显示到页面上(例如追加到某个 div) appendTypingText(data.text); // 这里需要你自己实现累加逐字效果 } if (data.error) { console.error(data.error); } } catch (e) { console.warn('Parse error', e); } } } } } 2. 与现有“逐字显示”逻辑的配合 你之前的前端应该有一个函数(例如 displayTextCharacterByCharacter),用于逐个字符显示完整文本。在流式场景下,你每次收到一小段 data.text 就直接追加到目标容器中,并继续触发逐字动画——但需要注意,追加的内容本身可能已经是一个词或一句话,如果你希望模拟“一个一个字符出现”的平滑效果,可以这样做: 维护一个全局的打字队列,每次收到新片段时,将片段加入队列。 由一个“打字机”定时器逐字从队列头部取出并显示。 或者更简单:直接实时追加(不做逐字延迟),因为流式本身已经是一块一块到达,视觉上已经接近打字效果。如果需要更细粒度,可用如下简单方法: javascript let messageContainer = document.getElementById('chat-output'); let currentText = ''; function appendStreamChunk(chunkText) { // 将新收到的字符逐步添加到界面(如果需要逐个字符动画) for (let i = 0; i < chunkText.length; i++) { setTimeout(() => { messageContainer.textContent += chunkText[i]; }, i * 30); // 每个字符延迟 30ms } } 实际改进:可以使用 requestAnimationFrame 或更优雅的异步队列,但原理相似。 三、其他注意事项 超时设置:流式响应可能持续较长时间,需确保 Flask 和反向代理(如 nginx)的超时配置足够长。 错误处理:流式传输中如果 API 中断,需向前端发送错误消息并关闭连接。 原有非流式接口:可以保留原 /call_deepseek 作为非流式备用。 API 路由:建议新建 /call_deepseek_stream 路由,避免破坏已有前端调用。 CORS:如果前端独立部署,需要在 Flask 中配置 CORS 支持流式响应。 四、总结改动点 模块 改动内容 后端 - payload 中 stream: True - 使用 requests.post(..., stream=True) - 逐行解析 SSE 数据包 - 返回 Response(generate(), content_type='text/event-stream') 前端 - 使用 fetch + ReadableStream 读取块 - 解析 SSE 格式 - 实时将收到的文字片段累加到页面(可选逐字动画) 流式改造后,用户体验会更接近实时聊天,且首字延迟大大降低。如果有前端原有代码,我可以帮你具体适配。 repokuanit.com dsapi逐字显示演示

文本逐字显示演示

点击按钮查看逐字显示效果

皖ICP备2024070331号-1

$$ \sum_{n=1}^{\infty} \frac{1}{n^2} = \frac{\pi^2}{6} $$

这是前端代码,如何修改,给出完整repo.py,和index.html 我们被问到:用户提供了一个前端index.html(已经包含了一些调用后端/get_response和/call_deepseek的逻辑),现在希望将后端改为流式(DeepSeek API流式),并且要求给出完整的repo.py和index.html。需要给出修改后的完整代码文件。 分析需求:原后端是Flask app,已有非流式/call_deepseek。现要改为流式,并提供完整的前端适配。用户的前端目前用的是fetch获取完整响应然后typeText。现在需要改成流式:前端应该收到流式数据块并实时追加显示。 我们需要提供两个文件: repo.py(即后端的Python文件) index.html(修改后的前端文件) 需要注意的是,原前端有一个逐字显示效果typeText,它是对整个文本进行逐字动画。但是在流式场景下,我们可能希望收到每个小块后直接追加文本(或者也做逐字效果)。通常会简化:直接将每个chunk追加到显示区域,不叠加额外的逐字动画,因为网络流本身已经是分块到达,看起来像打字效果。或者可以保留逐字效果,但比较复杂。建议直接即时显示每个chunk,可以不用原有的typeText的setInterval逐字显示,而是简单追加内容。不过可以保持一个近似效果:每次收到chunk,追加到当前正在显示的消息末尾,没有额外的光标动画。也可以实现光标闪烁等。 为了简洁和兼容,我们修改前端:创建新的流式处理函数,调用新的后端路由/call_deepseek_stream,使用fetch + ReadableStream解析SSE,每收到一个data块,就将其中的文本追加到当前消息div中,并滚动到底部。 后端:新建/call_deepseek_stream路由,返回Response(generate(), content_type='text/event-stream'),generate函数解析DeepSeek流式响应。 同时保留原有的非流式按钮功能吗?用户没有要求删除,可以保留。 注意原前端有按钮1-4使用的是/get_response(本地预定义文本),这不需要改动。 我们需要确保后端API密钥从环境变量读取,正确设置请求参数。用户原payload中有一个字段"thinking": {"type": "enabled"},"reasoning_effort": "high",这些似乎是DeepSeek的特定参数,我们保留。 另外,模型名称用户使用"deepseek-v4-pro",可能不规范,但保留原样。 提供完整代码,包括导入和运行。 还要注意,Flask处理流式响应时,可能会遇到缓冲区问题,需要设置response直接返回生成器,不要用jsonify。 我们还要确保前端正确处理SSE格式:后端yield的格式是"data: {json}\n\n",前端解析时按行分割,注意data:前缀和后缀。 前端需要停止旧的逐字显示函数,新的显示方式:每次收到文本片段,直接追加到当前显示的消息内容中。同时,考虑到可能有多个对话轮次,每次发送新消息时创建一个新的div作为回复容器,然后流式追加。这是标准聊天界面的做法。 此外,原前端有一个addToDisplay用于显示用户消息,可以保留。然后创建一个全局变量currentResponseDiv指向当前正在接收的回复div。 写代码时要注意错误处理,流式中断、超时等。 最终输出:先给repo.py内容,再给index.html内容,用合适的标记分隔。 开始编写。 我们提供一个完整的流式对话版本:后端 Flask 支持 SSE 流式推送,前端使用 fetch + ReadableStream 实时接收并逐字显示(无额外延迟,自然形成打字效果)。 1. repo.py(后端) python from flask import Flask, render_template, request, Response, jsonify import os import requests import json app = Flask(__name__) # 预定义的按钮响应(非流式,保留原有功能) responses = { "btn1": "你好!欢迎使用这个文本逐字显示演示。这是按钮1的响应内容。", "btn2": "这是按钮2的响应内容。逐字显示效果可以让信息呈现更加生动有趣。", "btn3": "按钮3被点击了!这个功能可以用来创建聊天机器人或者交互式故事。", "btn4": "感谢您测试这个功能。逐字显示模拟了人类打字的效果,增强了用户体验。" } # DeepSeek API 配置 DEEPSEEK_API_URL = "https://api.deepseek.com/chat/completions" DEEPSEEK_API_KEY = os.getenv('DEEPSEEK_API_KEY') # 从环境变量读取 @app.route('/') def index(): return render_template('index.html') # 原有非流式按钮响应(预定义文本) @app.route('/get_response', methods=['POST']) def get_response(): data = request.json button_id = data.get('button_id') response_text = responses.get(button_id, "未知按钮") return jsonify({"text": response_text}) # 新增流式 DeepSeek 接口 @app.route('/call_deepseek_stream', methods=['POST']) def call_deepseek_stream(): user_input = request.json.get('user_input') if not user_input: return jsonify({"error": "No input provided"}), 400 def generate(): headers = { "Authorization": f"Bearer {DEEPSEEK_API_KEY}", "Content-Type": "application/json" } payload = { "model": "deepseek-v4-pro", # 用户原参数 "messages": [{"role": "user", "content": user_input}], "stream": True, "thinking": {"type": "enabled"}, "reasoning_effort": "high" } try: # 发送流式请求 response = requests.post(DEEPSEEK_API_URL, json=payload, headers=headers, stream=True) response.raise_for_status() # 逐行读取 SSE 数据 for line in response.iter_lines(decode_unicode=True): if not line: continue # 移除 "data: " 前缀 if line.startswith('data: '): data_str = line[6:] else: data_str = line if data_str == '[DONE]': break try: chunk = json.loads(data_str) delta = chunk['choices'][0].get('delta', {}) content = delta.get('content', '') if content: # 向前端发送 SSE 格式数据 yield f"data: {json.dumps({'text': content})}\n\n" except json.JSONDecodeError: continue except Exception as e: yield f"data: {json.dumps({'error': str(e)})}\n\n" return Response(generate(), content_type='text/event-stream') if __name__ == '__main__': app.run(debug=True) 2. index.html(前端) 完整的前端代码,支持流式接收并实时显示,同时保留原有的按钮预定义文本功能。 html 流式对话演示 - DeepSeek

逐字显示 + DeepSeek 流式对话

点击下方按钮(预定义文本)或输入内容后发送(流式 AI 回复)

皖ICP备2024070331号-1

$$ \sum_{n=1}^{\infty} \frac{1}{n^2} = \frac{\pi^2}{6} $$

使用说明 设置环境变量 bash export DEEPSEEK_API_KEY="你的真实 API Key" 安装依赖 bash pip install flask requests 运行后端 bash python repo.py 访问 http://127.0.0.1:5000,即可测试: 点击四个按钮 → 预定义文本(非流式逐字动画) 在文本框输入内容并点击“发送” → 调用 DeepSeek 流式 API,实时显示回复内容 主要改进点 模块 改动说明 后端 新增 /call_deepseek_stream 路由,使用 stream=True 请求 API,逐行解析 SSE 并 yield 给前端 前端 使用 fetch + ReadableStream 接收流式数据;每收到一个 data.text 就立即追加到当前回复容器中,自然形成打字效果 用户体验 保留原有按钮的逐字动画;流式消息不再额外添加延迟,网络到达速度即显示速度,首字响应更快 如果你希望流式消息也带有“逐字符延迟”的平滑效果,可以在前端收到 data.text 后,用 setTimeout 逐个字符追加。不过对于大多数场景,流式本身的块状到达已经足够自然。如有需要,我可以进一步调整代码。