基于DeepSeek Web接口的AI批量写作自动化方案

基于DeepSeek Web接口的AI批量写作自动化方案 在实际的 AI 辅助创作领域尤其是长篇内容生成直接调用官方 API 虽然稳定但往往伴随着成本、配额和网络环境的限制。许多创作者和开发者都在寻找一种更灵活、更经济的方式能够利用像 DeepSeek 这类强大模型的能力进行批量的、定制化的内容创作。这不仅仅是调用一个接口那么简单它涉及到如何模拟交互、管理上下文、处理长文本以及构建稳定的自动化流程。本文将围绕如何在不依赖官方 API 的情况下利用现有工具和技巧搭建一套面向长篇小说、故事等批量写作的本地化或低成本解决方案。我们将从理解 DeepSeek 的 Web 交互模式开始逐步深入到自动化脚本的编写、上下文管理策略、长文本分割与续写的工程实践最后探讨如何将零散的技巧整合成一个可用的写作工具原型。整个过程会避开任何需要特殊网络访问或违反服务条款的操作专注于基于公开可访问的 Web 界面进行合法合规的自动化探索。1. 理解 DeepSeek Web 交互的核心机制要实现“免 API”调用首要任务是理解目标服务是如何通过浏览器与用户交互的。这并非逆向工程而是观察和分析正常的网络请求流程以便用程序模拟人的操作。1.1 常规 Web 聊天会话的请求流程当你通过浏览器访问 DeepSeek 的 Web 聊天界面时背后发生了一系列 HTTP 请求。我们的目标是识别出其中最关键的两个发起新会话的请求和发送消息/获取回复的请求。通过浏览器的开发者工具F12 打开选择“网络/Network”标签在正常聊天过程中可以观察到类似以下的请求初始化或会话列表请求通常是一个GET请求用于获取当前用户的会话列表或初始化聊天上下文。消息发送与流式响应请求这是一个POST请求将用户的问题和上下文信息发送到服务器服务器以流式Stream或非流式方式返回模型的思考过程和最终回复。关键点在于找到请求的URL、方法Method、请求头Headers和请求体Body。请求体中通常包含了会话 ID、消息历史、模型参数如max_tokens,temperature等信息。1.2 模拟请求的关键认证与令牌Web 服务为了识别用户会使用认证机制最常见的是 Cookie 或 Authorization Token。在 DeepSeek 的 Web 界面中认证信息很可能存储在 Cookie 中。Cookie当你登录后浏览器会保存一个包含会话信息的 Cookie。在模拟请求时你需要将这个 Cookie 值添加到你的程序发出的 HTTP 请求头中。Token有些服务会使用Bearer Token放在Authorization请求头中。这需要从登录后的响应或页面 JavaScript 中提取。对于免 API 方案我们通常采用携带浏览器 Cookie 的方式进行模拟。这意味着你需要先手动登录一次然后从浏览器中复制出关键的 Cookie 字符串用于你的脚本。请注意此方法仅适用于个人学习和自动化测试且你必须拥有该账户的合法使用权。大规模、高频次的自动化请求可能违反服务条款需谨慎评估。1.3 处理流式响应与上下文管理DeepSeek 的 Web 版通常采用 Server-Sent Events (SSE) 或类似技术进行流式输出。这意味着服务器会保持连接打开并持续发送数据块。在模拟时你需要能够处理这种分块传输的数据流并从中解析出完整的回复。此外Web 聊天依赖于上下文。服务器需要知道当前对话属于哪个“会话”以及之前聊了些什么。这通常通过请求体中的conversation_id或messages数组包含历史记录来实现。在批量写作中维护一个连贯的、可能非常长的上下文是核心挑战。2. 环境准备与工具选择在开始编写自动化脚本前需要搭建一个合适的开发环境。我们将选择 Python 作为主要语言因为它拥有丰富的网络请求和数据处理库。2.1 基础 Python 环境确保你的系统已安装 Python推荐 3.8 及以上版本。我们将使用pip安装必要的库。# 创建一个新的虚拟环境可选但推荐 python -m venv deepseek_writer_env # 激活虚拟环境 # Windows: deepseek_writer_env\Scripts\activate # Linux/Mac: source deepseek_writer_env/bin/activate2.2 核心依赖库安装执行以下命令安装核心库pip install requests httpx aiohttp beautifulsoup4requests/httpx/aiohttp用于发送 HTTP 请求。requests同步且简单httpx支持同步/异步且更现代aiohttp适用于高性能异步场景。初学者可从requests开始。beautifulsoup4用于解析 HTML 页面例如如果需要从页面提取初始 Token 或会话信息。对于处理流式响应httpx和aiohttp有更好的原生支持。2.3 辅助工具浏览器开发者工具你需要熟练使用 Chrome 或 Edge 浏览器的开发者工具DevTools。打开 DeepSeek Web 聊天页面并登录。按 F12 打开 DevTools。切换到Network网络标签。勾选“Preserve log”保留日志。在聊天框发送一条消息。在网络请求列表中寻找类型为fetch或xhr的请求其名称可能包含 “chat” 或 “conversation”。点击该请求查看其Headers和Payload或Request 标签页。3. 构建基础请求脚本从单次对话开始我们的第一步是编写一个能成功发送一条消息并获取回复的 Python 脚本。这需要从 DevTools 中捕获关键信息。3.1 捕获请求参数假设你在 Network 标签中找到了发送消息的请求我们称其为POST https://chat.deepseek.com/api/chat/completions。查看 Headers:Cookie: 这是最重要的信息之一。复制整个Cookie请求头的值。User-Agent: 模拟浏览器行为可以复制浏览器的 User-Agent。Content-Type: 通常是application/json。Origin和Referer: 有时需要可以一并复制。查看 Payload (Request Body):请求体通常是 JSON 格式可能包含以下关键字段{ messages: [ {role: user, content: 你好请写一个故事开头。} ], model: deepseek-chat, stream: true, temperature: 0.7, max_tokens: 2048 }messages: 对话历史数组每个元素包含role(user/assistant) 和content。model: 指定使用的模型。stream: 是否为流式输出。temperature: 创造性参数。max_tokens: 生成的最大 token 数。3.2 编写 Python 请求代码基于以上信息我们可以编写一个同步版本的脚本import requests import json # 从浏览器 DevTools 中复制的信息 CHAT_URL https://chat.deepseek.com/api/chat/completions # 示例URL需替换为实际地址 COOKIE_STR your_copied_cookie_string_here # 替换为你的 Cookie USER_AGENT Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ... # 你的浏览器 UA headers { Cookie: COOKIE_STR, User-Agent: USER_AGENT, Content-Type: application/json, Origin: https://chat.deepseek.com, Referer: https://chat.deepseek.com/, } def send_chat_request(prompt): 发送单条消息并获取回复非流式 data { messages: [{role: user, content: prompt}], model: deepseek-chat, # 根据实际情况调整 stream: False, # 先使用非流式简化处理 temperature: 0.8, max_tokens: 2000 } try: response requests.post(CHAT_URL, headersheaders, jsondata, timeout30) response.raise_for_status() # 检查 HTTP 错误 result response.json() # 解析回复内容结构可能为 result[choices][0][message][content] reply result.get(choices, [{}])[0].get(message, {}).get(content, ) return reply except requests.exceptions.RequestException as e: print(f请求失败: {e}) if hasattr(e, response) and e.response is not None: print(f响应状态码: {e.response.status_code}) print(f响应内容: {e.response.text}) return None except json.JSONDecodeError as e: print(fJSON 解析失败: {e}) print(f原始响应: {response.text}) return None if __name__ __main__: user_input 写一个关于未来都市中一名仿生人侦探的故事开头300字左右。 reply send_chat_request(user_input) if reply: print(AI 回复) print(reply) else: print(未能获取回复。)关键点与风险提示URL 和 CookieCHAT_URL和COOKIE_STR必须替换为你从实际页面捕获的值。这些值可能会随着网站更新而改变。流式处理上述代码将stream设为False。如果设为True你需要处理response.iter_lines()来逐行读取 SSE 数据块并拼接出完整回复。这更复杂但能获得更快的首字响应体验。会话管理这个简单的请求没有携带conversation_id。在真实的 Web 交互中你可能需要先创建一个会话或从列表中获取一个会话 ID并在后续请求中携带它以维持多轮对话的上下文。这通常需要分析创建会话的请求。合规性此脚本模拟了浏览器行为。请确保你的使用频率和目的符合 DeepSeek 服务条款。过度频繁的请求可能导致 IP 或账户被暂时限制。3.3 处理流式响应如果服务端强制或你希望使用流式响应代码需要调整import requests def send_chat_request_stream(prompt): 发送消息并处理流式响应 data { messages: [{role: user, content: prompt}], model: deepseek-chat, stream: True, # 启用流式 temperature: 0.8, max_tokens: 2000 } full_reply try: with requests.post(CHAT_URL, headersheaders, jsondata, streamTrue, timeout60) as response: response.raise_for_status() for line in response.iter_lines(): if line: decoded_line line.decode(utf-8) # SSE 格式通常以 data: 开头 if decoded_line.startswith(data: ): json_str decoded_line[6:] # 去掉 data: if json_str.strip() [DONE]: break try: chunk json.loads(json_str) content chunk.get(choices, [{}])[0].get(delta, {}).get(content, ) if content: full_reply content print(content, end, flushTrue) # 逐字打印 except json.JSONDecodeError: continue print() # 换行 return full_reply except requests.exceptions.RequestException as e: print(f\n请求失败: {e}) return None # 使用方式 if __name__ __main__: reply send_chat_request_stream(继续写这个侦探故事的下一个场景。)4. 实现批量写作与长文本管理单次对话解决了基础通信问题但批量写作和长篇创作需要更高级的策略。4.1 批量任务队列与错误处理对于批量写作例如根据一个提纲生成 10 个章节的开头我们需要管理一个任务队列并加入健壮的错误处理和延迟避免触发反爬机制。import time import random from typing import List def batch_writing(prompts: List[str], output_file: str “output.txt”): 批量处理写作提示 results [] for i, prompt in enumerate(prompts): print(f”处理任务 {i1}/{len(prompts)}: {prompt[:50]}...”) reply send_chat_request(prompt) # 使用之前定义的非流式函数 if reply: results.append({ “index”: i, “prompt”: prompt, “reply”: reply }) # 将结果实时写入文件 with open(output_file, ‘a’, encoding‘utf-8’) as f: f.write(f” 章节 {i1} \n”) f.write(f”提示: {prompt}\n”) f.write(f”内容:\n{reply}\n\n”) print(f” 任务 {i1} 完成已保存。”) else: print(f” 任务 {i1} 失败。”) results.append({ “index”: i, “prompt”: prompt, “reply”: “ERROR” }) # 重要的延迟避免请求过快 delay random.uniform(5, 15) # 随机延迟 5-15 秒 print(f” 等待 {delay:.1f} 秒...\n”) time.sleep(delay) return results # 示例使用 chapter_prompts [ “第一章雨夜仿生人侦探李维在霓虹闪烁的街道上发现一具没有身份信息的尸体。请详细描写场景和初步发现。”, “第二章李维回到他的事务所分析从尸体上提取的加密数据碎片。请描写他的分析过程和第一个线索。”, “第三章线索指向一家顶尖的生物科技公司‘涅槃’。李维决定潜入调查。请描写他制定计划和准备装备的过程。”, ] batch_writing(chapter_prompts, “novel_chapters.txt”)4.2 长文本的“续写”策略模型有上下文长度限制例如 32K tokens。当写作内容超过这个限制时不能简单地将整个故事历史都塞进去。需要智能的上下文窗口管理。策略一摘要式上下文在每次请求时不发送全部历史而是发送故事的核心设定摘要固定。最近 1-2 个章节的完整内容。当前章节之前的一段摘要例如用 AI 对之前所有内容生成一个简短摘要。新的写作指令。def build_context_for_continuation(full_history: str, current_chapter_outline: str, model_context_window: int 28000): 构建续写的上下文消息 # 假设 full_history 是之前所有已生成文本的拼接 # 我们需要截取最近的部分并确保总长度不超过限制 # 1. 系统提示定义角色和写作风格 system_prompt “你是一位专业的科幻小说作家擅长描写细节和构建悬疑氛围。请根据给定的故事摘要和最近情节继续创作。” # 2. 计算可用空间粗略按字符数更精确应用 tokenizer available_chars model_context_window * 3 # 粗略估算: 1 token ≈ 3-4 字符留有余地 # 3. 优先保留最近的内容例如最后 5000 字符 recent_content full_history[-5000:] if len(full_history) 5000 else full_history # 4. 如果空间还够可以添加一个更早内容的 AI 摘要这里需要另一个函数生成摘要简化处理 earlier_summary generate_summary(full_history[:-5000]) if len(full_history) 5000 else “” # 5. 组装最终的用户提示 user_prompt f”故事背景摘要{earlier_summary}\n\n最近情节{recent_content}\n\n请根据以上内容继续创作接下来的部分{current_chapter_outline}。要求保持风格一致情节连贯。” messages [ {“role”: “system”, “content”: system_prompt}, {“role”: “user”, “content”: user_prompt} ] return messages # 模拟的摘要生成函数实际中可能需要调用一次 AI def generate_summary(long_text: str, max_length500) - str: 简化版的摘要生成实际项目中应更智能 if len(long_text) max_length: return long_text # 这里可以替换为调用 AI 生成摘要或者使用简单的截取提示 # 例如 return send_chat_request(f”请用不超过{max_length}字概括以下内容\n{long_text}”) return long_text[:max_length] “...”策略二章节独立大纲控制另一种更稳定的方法是让每个章节相对独立生成依靠一个详细的大纲来保证整体连贯性。AI 只根据当前章节的详细大纲和极简的前情提要来写作。这降低了上下文管理的复杂度但对大纲的质量要求更高。4.3 文件与进度持久化批量写作可能耗时很长必须支持中断恢复。可以将进度和已生成的内容保存到 JSON 文件中。import json import os STATE_FILE “writing_state.json” def load_state(): if os.path.exists(STATE_FILE): with open(STATE_FILE, ‘r’, encoding‘utf-8’) as f: return json.load(f) return {“completed_indices”: [], “results”: []} def save_state(completed_indices, results): state { “completed_indices”: completed_indices, “results”: results, “last_updated”: time.strftime(“%Y-%m-%d %H:%M:%S”) } with open(STATE_FILE, ‘w’, encoding‘utf-8’) as f: json.dump(state, f, ensure_asciiFalse, indent2) def resilient_batch_writing(prompts: List[str]): 支持断点续传的批量写作 state load_state() completed set(state.get(“completed_indices”, [])) all_results state.get(“results”, []) for i, prompt in enumerate(prompts): if i in completed: print(f”跳过已完成的任务 {i1}.”) continue print(f”处理任务 {i1}/{len(prompts)}...”) reply send_chat_request(prompt) if reply: result {“index”: i, “prompt”: prompt, “reply”: reply} all_results.append(result) completed.add(i) # 实时保存到独立文件 with open(f”chapter_{i1}.txt”, ‘w’, encoding‘utf-8’) as f: f.write(reply) else: print(f”任务 {i1} 失败将在下次重试。”) # 可以选择将失败任务也记录但不加到 completed # 保存进度状态 save_state(list(completed), all_results) time.sleep(random.uniform(8, 12)) print(“所有任务处理完毕。”) return all_results5. 常见问题排查与优化在实际操作中你会遇到各种问题。下面是一个排查指南。5.1 请求失败与错误码问题现象可能原因检查与解决思路HTTP 403 Forbidden1. Cookie 过期或无效。2. 请求头信息不完整或被识别为爬虫。3. IP 地址被限制。1. 重新登录获取新的 Cookie。2. 检查并补全User-Agent,Origin,Referer等头信息。3. 增加请求延迟模拟更真实的人类操作间隔。HTTP 400 Bad Request1. 请求体 JSON 格式错误。2. 缺少必需的参数。3. 参数值超出范围如max_tokens过大。4. 上下文超长context length错误。1. 使用json.dumps()确保格式正确或直接用json参数。2. 对照浏览器捕获的 Payload检查字段是否齐全。3. 调整max_tokens等参数到合理值。4. 减少messages中的历史内容长度采用摘要策略。HTTP 429 Too Many Requests请求频率过高。显著增加请求间隔例如 30-60 秒加入随机延迟。考虑使用多个账号如果合规轮询。HTTP 5xx服务器错误服务端问题。等待一段时间后重试。检查服务状态页面如果有。连接超时网络不稳定或服务器响应慢。增加timeout参数实现重试机制。重试机制示例import requests from tenacity import retry, stop_after_attempt, wait_exponential retry(stopstop_after_attempt(3), waitwait_exponential(multiplier1, min4, max10)) def send_chat_request_with_retry(prompt): # ... 原有的请求代码 ... response requests.post(..., timeout60) if response.status_code 429: # 对于 429触发重试并且 tenacity 的指数等待会生效 raise Exception(“Rate limited”) response.raise_for_status() return response.json()5.2 回复质量不佳或偏离主题问题现象可能原因优化策略故事前后矛盾上下文窗口有限AI 忘记了很早的设定。1.强化系统提示在system消息中明确核心设定世界观、主角特征、故事基调。2.动态摘要在每次请求的上下文里包含一个由 AI 生成的、关于之前所有关键情节的简短摘要。3.分段大纲提供更详细的章节级大纲让 AI 每次只创作一小段减少偏离。文风不稳定不同的提示词导致 AI 切换风格。1.固定风格指令在system消息中详细定义文风例如“模仿海明威的简洁风格”。2.提供范例在最初的对话中提供一段你期望风格的文本作为示例。内容重复或循环AI 陷入某种生成循环。1.调整temperature适当提高temperature如 0.8-1.0增加随机性。2.修改提示词在续写指令中加入“避免重复之前的情节”、“开拓新的冲突”等引导。3.注入新元素主动在提示词中引入新角色、新事件或转折点。5.3 性能与稳定性优化异步请求如果需要处理大量独立任务可以使用aiohttp进行异步请求但务必注意控制并发数避免被封。import aiohttp import asyncio async def async_send_chat(session, prompt): async with session.post(CHAT_URL, headersheaders, json{“messages”: [...]}) as resp: return await resp.json() async def main(prompts): async with aiohttp.ClientSession() as session: tasks [async_send_chat(session, p) for p in prompts] # 限制并发数例如 semaphore asyncio.Semaphore(3) results await asyncio.gather(*tasks, return_exceptionsTrue) # 处理结果本地缓存对相同的提示词或中间摘要结果进行缓存避免重复请求。日志记录详细记录每个请求的输入、输出、耗时和错误便于后期分析和调试。6. 从脚本到工具构建本地写作辅助界面将上述脚本封装成一个简单的命令行工具或图形界面可以提升易用性。6.1 命令行工具设计可以创建一个 Python 脚本接受大纲文件、输出目录等参数。# writer_cli.py import argparse import sys def main(): parser argparse.ArgumentParser(description“DeepSeek 批量写作助手”) parser.add_argument(‘—outline’, ‘-o’, requiredTrue, help‘包含写作提纲的文本文件路径每行一个章节提示’) parser.add_argument(‘—output-dir’, ‘-d’, default‘./output’, help‘输出目录’) parser.add_argument(‘—model’, ‘-m’, default‘deepseek-chat’, help‘模型名称’) parser.add_argument(‘—delay’, typefloat, default10.0, help‘请求间隔秒数’) args parser.parse_args() # 读取提纲 with open(args.outline, ‘r’, encoding‘utf-8’) as f: prompts [line.strip() for line in f if line.strip()] print(f”读取到 {len(prompts)} 个章节提纲。”) # 调用批量写作函数... # resilient_batch_writing(prompts) if __name__ ‘__main__’: main()使用方式python writer_cli.py -o novel_outline.txt -d ./my_novel6.2 简易图形界面使用 Tkinter对于不熟悉命令行的用户一个简单的 GUI 更有吸引力。# writer_gui.py (简化示例) import tkinter as tk from tkinter import scrolledtext, filedialog, messagebox import threading # ... 导入之前的写作函数 ... class WritingApp: def __init__(self, root): self.root root root.title(“AI 写作助手”) # 提纲输入区 tk.Label(root, text“章节提纲每行一个:”).grid(row0, column0, sticky‘w’) self.outline_text scrolledtext.ScrolledText(root, width60, height15) self.outline_text.grid(row1, column0, columnspan2, padx5, pady5) # 按钮 tk.Button(root, text“开始生成”, commandself.start_writing).grid(row2, column0, pady5) tk.Button(root, text“加载提纲文件”, commandself.load_outline).grid(row2, column1, pady5) # 日志输出区 tk.Label(root, text“生成日志:”).grid(row3, column0, sticky‘w’) self.log_text scrolledtext.ScrolledText(root, width60, height20, state‘disabled’) self.log_text.grid(row4, column0, columnspan2, padx5, pady5) def log(self, message): self.log_text.config(state‘normal’) self.log_text.insert(tk.END, message ‘\n’) self.log_text.see(tk.END) self.log_text.config(state‘disabled’) self.root.update() def load_outline(self): filepath filedialog.askopenfilename(filetypes[(“Text files”, “*.txt”)]) if filepath: with open(filepath, ‘r’, encoding‘utf-8’) as f: content f.read() self.outline_text.delete(‘1.0’, tk.END) self.outline_text.insert(‘1.0’, content) self.log(f”已加载提纲文件: {filepath}”) def start_writing(self): outline_content self.outline_text.get(‘1.0’, tk.END).strip() if not outline_content: messagebox.showwarning(“警告”, “请输入或加载章节提纲”) return prompts [line for line in outline_content.split(‘\n’) if line.strip()] self.log(f”开始处理 {len(prompts)} 个章节...”) # 在新线程中运行避免界面卡死 thread threading.Thread(targetself.run_batch_writing, args(prompts,)) thread.daemon True thread.start() def run_batch_writing(self, prompts): # 这里调用之前编写的 resilient_batch_writing 函数 # 并将 self.log 函数传递进去用于输出日志 # ... 具体实现 ... pass if __name__ ‘__main__’: root tk.Tk() app WritingApp(root) root.mainloop()7. 重要注意事项与最佳实践在实施此类项目时必须时刻关注合规性、伦理和可持续性。严格遵守服务条款仔细阅读 DeepSeek 等平台的使用条款。明确禁止自动化访问的切勿尝试。即使条款允许也应将请求频率控制在合理、模拟人类行为的水平避免对服务造成负担。尊重版权与原创AI 生成的内容版权归属尚不明确。此工具应用于辅助创作、激发灵感或生成初稿最终作品应由人类作者进行大量的修改、润色和原创性注入形成具有独创性的新作品。内容安全审核AI 可能生成不符合预期或含有不当内容的结果。在批量生成后务必进行人工审核特别是对于公开发布的内容。数据备份与版本管理写作过程漫长务必定期备份生成的内容、进度状态和配置文件。可以使用 Git 管理你的提纲和生成的文本。技术迭代与更新Web 接口和参数可能会随时变更。你的脚本需要有一定的适应性当发现请求失败时应重新检查网络请求格式。探索官方途径如果创作需求量大且稳定长期来看了解和评估官方的 API 服务如果提供是更可靠、更高效的选择。虽然本文探讨免 API 方案但官方 API 通常提供更稳定的服务、更清晰的计费模式和更全面的技术支持。通过将网络请求模拟、上下文管理、批量调度和错误处理结合起来你可以构建一个功能强大的本地化 AI 写作辅助工具。这个工具的核心价值在于将你的创意体现在详细的大纲和提示词中与 AI 强大的文本生成能力相结合并让你能完全掌控生成流程和数据。记住工具只是辅助精彩的故事最终源于你的构思和把控。