From 2a5602009be98f2292e1df1c0e0f869fdb66c564 Mon Sep 17 00:00:00 2001 From: YILING0013 Date: Sat, 1 Feb 2025 00:23:00 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=89=93=E5=8C=85=E8=84=9A?= =?UTF-8?q?=E6=9C=AC=E6=96=87=E4=BB=B6=E3=80=81README=E3=80=81requirements?= =?UTF-8?q?.txt=EF=BC=9B=E7=95=A5=E5=BE=AE=E6=94=B9=E5=8A=A8UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 264 +++++++++++++++++++++++---------------- main.spec | 55 ++++---- novel_generator.py | 15 ++- prompt_definitions.py | 2 +- requirements-default.txt | Bin 0 -> 392 bytes ui.py | 12 +- 6 files changed, 198 insertions(+), 150 deletions(-) create mode 100644 requirements-default.txt diff --git a/README.md b/README.md index a85c16f..fc85b5f 100644 --- a/README.md +++ b/README.md @@ -1,67 +1,85 @@ -**自动小说生成工具** -**核心功能:** +# **自动小说生成工具** -✅ **小说设定**(世界观、人物、剧情结构) -✅ **章节生成**(多步生成,确保逻辑连贯) -✅ **角色状态 & 伏笔管理**(追踪人物发展) -✅ **向量检索**(保证长篇小说上下文一致) -✅ **自定义知识库**(上传本地参考文档) -✅ **一致性检查**(防止剧情冲突) -✅ **GUI 友好交互**(可配置 & 直观操作) +> 一款基于大模型的多功能小说生成器,帮助你快速生成连贯、可控、可审校的长篇故事。 -# **部署与使用指南** +
-## **1. 环境要求** -在开始之前,请确保你的系统满足以下要求: -- **Python 3.8+** -- **pip 已安装**(Python 包管理器) -- **API 访问权限**(支持OpenAI API方式的任何AI,中文推荐使用DeepSeek) +| 功能点 | 描述 | +|-------|-----| +| 🚀 **小说设定** | 世界观 / 人物 / 剧情结构 | +| 📝 **章节生成** | 多步生成,确保逻辑连贯 | +| 👥 **角色状态 & 伏笔管理** | 追踪人物发展、重要事件 | +| 🔍 **向量检索** | 保证长篇小说上下文一致 | +| 📁 **自定义知识库** | 可上传本地参考文档 | +| ✅ **一致性检查** | 自动识别剧情冲突或矛盾 | +| 🖥 **GUI 友好交互** | 所见即所得,配置 & 操作简便 | + +
--- -## **2. 安装依赖** - -**进入项目目录,执行**: -```bash -pip install -r requirements.txt -``` -### 安装语句切分模型punkt(可选,默认程序运行后会自动加载) -**Python环境终端输入**: -```bash -python -import nltk -nltk.download('punkt') -``` - -等待下载完成(很小,下载很快的) - -**至此,环境配置完成。** +## **目录** +1. [环境要求](#环境要求) +2. [安装依赖](#安装依赖) +3. [项目结构](#项目结构) +4. [配置 API Key](#配置-api-key) +5. [运行程序](#运行程序) +6. [使用指南](#使用指南) +7. [生成文件管理](#生成文件管理) +8. [常见问题](#常见问题) --- -## **3. 项目结构** -克隆或下载本项目后,你会看到如下结构: -```plaintext +## **环境要求** +在开始之前,请确保你的系统满足以下条件: +- 推荐**Python 3.10+** +- 已安装 **pip**(Python 包管理器) +- 拥有 **API Key**(如 OpenAI 或 DeepSeek)或 **支持OpenAI调用方式的本地接口** + +--- + +## **安装依赖** +1. 在项目根目录下,打开终端或命令行 +2. 执行以下命令安装所有依赖: + ```bash + pip install -r requirements.txt + ``` +3. (可选)若需要手动安装 `nltk` 的 `punkt` 数据包: + ```bash + python + >>> import nltk + >>> nltk.download('punkt') + ``` + +--- + +## **项目结构** +克隆或下载本项目后,你将看到如下目录结构: + +``` . -├── main.py # 入口文件,运行 GUI -├── ui.py # 图形界面 -├── novel_generator.py # 章节生成核心逻辑 -├── consistency_checker.py # 一致性检查 (防止剧情冲突) -├── prompt_definitions.py # 预定义的 AI 提示词 -├── utils.py # 通用工具函数 (文件操作) -├── config_manager.py # 处理配置信息 (API Key, Base URL) -├── config.json # 用户配置文件 (可选) -└── vectorstore/ # (可选) 存储向量数据库 +├── main.py # 入口文件, 运行 GUI +├── ui.py # 图形界面 +├── novel_generator.py # 章节生成核心逻辑 +├── consistency_checker.py # 一致性检查, 防止剧情冲突 +|—— chapter_directory_parser.py #格式化目录 +├── prompt_definitions.py # 定义 AI 提示词 +├── utils.py # 常用工具函数, 文件操作 +├── config_manager.py # 管理配置 (API Key, Base URL) +├── config.json # 用户配置文件 (可选) +└── vectorstore/ # (可选) 本地向量数据库存储 ``` +> `vectorstore/` 文件夹将在程序运行后自动生成,存储向量检索的缓存数据。 + --- -## **4. 配置 API Key** -运行前,你需要**配置 API Key** 以便调用 OpenAI 或本地 LLM。 +## **配置 API Key** +你可以通过以下方式指定或修改 API Key: -### **方式 1:手动修改 `config.json`** -在 `config.json` 文件中填入: +### 方式 1:**修改 `config.json`** +打开 `config.json`,将对应字段替换为你的配置: ```json { "api_key": "your_openai_api_key", @@ -75,93 +93,119 @@ nltk.download('punkt') } ``` -### **方式 2:通过 GUI 直接输入** -- 启动程序后,在 GUI 中输入 `API Key` 并选择 `Base URL`,然后**点击 "保存配置"** 以存储到 `config.json`。 +### 方式 2:**通过 GUI 输入** +1. 运行 `main.py` 后会弹出图形界面 +2. 在界面输入 `API Key`、`Base URL`、模型名称、Temperature 等 +3. 点击 **“保存配置”** 按钮,自动生成或更新 `config.json` --- -## **5. 运行程序** -### **方式 1:使用 `Python` 运行** +## **运行程序** + +### **方式 1:使用 Python 解释器** ```bash python main.py ``` -程序启动后,你会看到一个图形界面,方便用户交互。 +执行后,GUI 将会启动,你可以在图形界面中进行各项操作。 + +### **方式 2:打包为可执行文件** +如果你想在无 Python 环境的机器上使用本工具,可以使用 **PyInstaller** 进行打包: -### **方式 2:打包成可执行文件** -如果你希望**打包成可执行文件**(避免 Python 依赖),可以使用 `PyInstaller`: ```bash pip install pyinstaller -pyinstaller --onefile --windowed main.py -``` -这样会在 `dist/` 目录下生成 `main.exe`(Windows)或 `main`(Linux/macOS)。 - -或者使用提供的`main.spec`,执行以下打包指令: -```bash pyinstaller main.spec ``` +打包完成后,会在 `dist/` 目录下生成可执行文件(如 Windows 下的 `main.exe`)。 --- -## **6. 使用指南** -### **步骤 1:设置小说参数** -在 GUI 界面: -1. **输入 API Key & Base URL**(或使用 `config.json`)。 -2. **选择模型**(如 `gpt-4o`)。 -3. **输入小说主题**(如 "未来世界中的 AI 革命")。 -4. **选择小说类型**(如 "科幻"、"奇幻"、"悬疑")。 -5. **设置章节数和每章字数**(如 10 章,每章 3000 字)。 -6. **选择存储路径**(建议创建 `novels/` 目录)。 +## **使用指南** -### **步骤 2:生成小说设定 & 目录** -点击 **"1. 生成设定 & 目录"**,系统将: -- 生成**世界观设定**(`Novel_setting.txt`)。 -- 生成**章节目录**(`Novel_directory.txt`)。 +1. **启动后,先完成基本参数设置:** + - **API Key & Base URL**(如 `https://api.openai.com/v1`) + - **模型名称**(如 `gpt-3.5-turbo`、`gpt-4o` 等) + - **Temperature**(0~1,决定文字创意程度) + - **主题(Topic)**(如 “废土世界的 AI 叛乱”) + - **类型(Genre)**(如 “科幻”/“魔幻”/“都市幻想”) + - **章节数**、**每章字数**(如 10 章,每章约 3000 字) + - **保存路径**(建议创建一个新的输出文件夹) -### **步骤 3:生成章节** -点击 **"2. 生成单章"**,系统将: -- 读取**上一章节内容**(`lastchapter.txt`)。 -- 通过**向量检索**查找相关背景信息。 -- **动态调整角色状态**(`character_state.txt`)。 -- **生成完整章节**,并保存到 `chapters/chapter_X.txt`。 +2. **点击「1. 生成设定 & 目录」** + - 系统将基于主题、类型等生成: + - `Novel_setting.txt`:**世界观 & 整体设定** + - `Novel_directory.txt`:**章节目录**(含标题、简要提示) + - 可以在生成后的文件中查看、修改或补充世界观设定和目录标题。 -### **步骤 4:一致性检查(可选)** -点击 **"3. 一致性审校"**,系统将: -- 检查**角色行为、剧情逻辑**是否前后矛盾。 -- 识别是否有**未解伏笔**,保证故事合理性。 +3. **点击「2. 生成章节草稿」** + - 在生成章节之前,你可以: + - **设置章节号**(如要写第 1 章,就填 `1`) + - **在“本章指导”输入框**中,填写对本章剧情的任何期望或指导 + - 点击按钮后,系统将: + - 自动读取前文与 `Novel_directory.txt` 的标题与简述 + - 调用向量检索回顾剧情,确保上下文连贯 + - 生成本章大纲 (`outline_X.txt`) 及正文 (`chapter_X.txt`) + - 生成完成后,可在左侧查看本章草稿内容。 + +4. **手动检查 & 编辑**(可选) + - 你可以在文本编辑器中修改 `chapter_X.txt` 的内容,使之更符合个人审美或剧情要求。 + +5. **点击「3. 定稿当前章节」** + - 系统将: + - **更新全局摘要**(`global_summary.txt`) + - **更新角色状态**(`character_state.txt`,包含人物发展、物品变动、剧情线索等) + - **更新向量检索库**,保证后续章节能够调用最新信息。 + +6. **一致性检查(可选)** + - 点击「4. 一致性审校」进行冲突检测,比如**角色逻辑、剧情前后矛盾**等。 + - 若有冲突,会在日志区输出详细说明。 + +7. **重复第 3~5 步** 直到所有章节完成! --- -## **7. 生成文件管理** -所有生成的文件存储在你选择的目录下: -```plaintext +## **生成文件管理** + +在你指定的输出文件夹中,程序会自动生成并维护以下文件/目录: + +``` output_directory/ -├── Novel_setting.txt # 小说世界观 & 角色设定 -├── Novel_directory.txt # 章节目录 -├── lastchapter.txt # 最新章节 (供 AI 参考) -├── character_state.txt # 角色状态 (道具、情感、技能) -├── global_summary.txt # 小说摘要 -└── chapters/ # 所有章节 - ├── chapter_1.txt - ├── chapter_2.txt - ├── chapter_3.txt - └── ... +├── Novel_setting.txt # 世界观 & 整体设定 +├── Novel_directory.txt # 小说章节目录 +├── character_state.txt # 角色状态/物品/伏笔等追踪 +├── global_summary.txt # 整体剧情摘要 (用于后续上下文) +├── outlines/ # 存放各章大纲 (outline_1.txt 等) +├── chapters/ # 存放每一章成稿 (chapter_1.txt 等) +└── vectorstore/ # 向量检索数据库 (可清空重置) ``` +- **`character_state.txt`**:记录角色的动机、能力、持有物品等关键信息 +- **`global_summary.txt`**:每次定稿后都会更新,保证剧情可被后续章节引用 +- **`chapters/`**:每一章的正文会独立保存,方便你随时手动修改 + --- -## **8. 可能遇到的问题** -### **1. `Chroma' object has no attribute 'persist'`** -**原因:** `Chroma` 版本问题。 -**解决方案:** -```bash -pip uninstall chromadb -pip install chromadb==0.3.21 # 或尝试其他版本 -``` -如果仍然报错,可以在 `novel_generator.py` 里**注释 `store.persist()`**。 +## **常见问题** + +#### 1. **`Chroma' object has no attribute 'persist'` 错误** + +- **原因**:Chroma 库版本不匹配 +- **解决办法**: + ```bash + pip uninstall chromadb + pip install chromadb==0.3.21 + ``` + 或者在 `novel_generator.py` 中找到 `store.persist()` 并注释掉,如果你的版本不支持此方法。 --- -### **2. 生成内容不符合预期** -**可能的原因:** -- 主题不够清晰,可以在 `topic` 字段中添加详细设定(如 `“废土世界 + AI 叛乱”`)。 -- 角色设定较少,可手动在 `Novel_setting.txt` 里补充。 +#### 2. **生成内容与预期不符** + +- **可能原因**: + 1. 主题或类型过于宽泛,模型难以把握重点 + 2. 角色和世界观设定不够详细,可在 `Novel_setting.txt` 中增补更多细节 +- **建议**: + - 在 GUI 的“本章指导”输入框中填写更明确的剧情走向或重点描述,让模型更好地理解和发挥 + +--- + +若你还有其他问题或需求,欢迎在项目 Issues 中提出。 \ No newline at end of file diff --git a/main.spec b/main.spec index 63fdbfd..93ae127 100644 --- a/main.spec +++ b/main.spec @@ -1,34 +1,31 @@ # -*- mode: python ; coding: utf-8 -*- -from PyInstaller.utils.hooks import collect_submodules +from PyInstaller.utils.hooks import collect_all + +datas = [] +binaries = [] +hiddenimports = ['typing_extensions', + 'langchain-openai', + 'langgraph', + 'openai', + 'nltk', + 'sentence_transformers', + 'scikit-learn', + 'langchain-community', + 'pydantic', + 'pydantic.deprecated.decorator', + 'tiktoken_ext.openai_public', + 'tiktoken_ext' + ] +tmp_ret = collect_all('chromadb') +datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] + a = Analysis( ['main.py'], pathex=[], - binaries=[], - datas=[ - ('vectorstore', 'vectorstore') - ], - hiddenimports=['typing_extensions', - 'langchain-openai', - 'langgraph', - 'openai', - 'chromadb', - 'nltk', - 'sentence_transformers', - 'scikit-learn', - 'langchain-community', - 'pydantic', - 'pydantic.deprecated.decorator', - *collect_submodules('chromadb'), - 'chromadb.utils.embedding_functions.onnx_mini_lm_l6_v2', - 'chromadb.telemetry.product.posthog', - 'chromadb.api.segment', - 'chromadb.db.impl', - 'chromadb.db.impl.sqlite', - 'chromadb.migrations', - 'chromadb.migrations.embeddings_queue' - - ], + binaries=binaries, + datas=datas, + hiddenimports=hiddenimports, hookspath=[], hooksconfig={}, runtime_hooks=[], @@ -43,8 +40,8 @@ exe = EXE( a.scripts, [], exclude_binaries=True, - name='AI_NovelGenerator_V1.1', - debug=False, + name='AI_NovelGenerator_V1.2.3', + debug=True, bootloader_ignore_signals=False, strip=False, upx=True, @@ -63,5 +60,5 @@ coll = COLLECT( strip=False, upx=True, upx_exclude=[], - name='AI_NovelGenerator_V1.1', + name='AI_NovelGenerator_V1.2.3' ) diff --git a/novel_generator.py b/novel_generator.py index 898f8fd..dd02e31 100644 --- a/novel_generator.py +++ b/novel_generator.py @@ -42,20 +42,27 @@ def debug_log(prompt: str, response_content: str): logging.info(f"[Response >>>] {response_content}\n") # ============ 向量检索相关 ============ -VECTOR_STORE_DIR = "vectorstore" +VECTOR_STORE_DIR = os.path.join(os.getcwd(), "vectorstore") +if not os.path.exists(VECTOR_STORE_DIR): + os.makedirs(VECTOR_STORE_DIR) def clear_vector_store(): """ - 清空本地向量库(删除 vectorstore 文件夹)。 + 清空本地向量库(删除 vectorstore 文件夹内的内容)。 需要在UI中加一个二次确认弹窗,防止误删。 """ if os.path.exists(VECTOR_STORE_DIR): try: import shutil - shutil.rmtree(VECTOR_STORE_DIR) + for filename in os.listdir(VECTOR_STORE_DIR): + file_path = os.path.join(VECTOR_STORE_DIR, filename) + if os.path.isfile(file_path) or os.path.islink(file_path): + os.unlink(file_path) + elif os.path.isdir(file_path): + shutil.rmtree(file_path) logging.info("Local vector store has been cleared.") except Exception as e: - logging.warning(f"Failed to remove vector store: {e}") + logging.warning(f"Failed to clear vector store: {e}") else: logging.info("No vector store found to clear.") diff --git a/prompt_definitions.py b/prompt_definitions.py index f9ee96b..00a8366 100644 --- a/prompt_definitions.py +++ b/prompt_definitions.py @@ -67,7 +67,7 @@ novel_directory_prompt = """\ 第{number_of_chapters}章 :< text > 请严格按照上述格式输出每一章的名称,最好在重要情节标题后增加提示性简述, -若要加更详细的简述,用“ - ”分隔,如“第2章 :阴影浮现 - 主要角色冲突爆发”。 +若要加更详细的简述,用“ - ”分隔,举例如“第n章 :< text > - 主要角色冲突爆发,角色A发生xx意外”。 请直接输出,不要使用Markdown语法。 """ diff --git a/requirements-default.txt b/requirements-default.txt new file mode 100644 index 0000000000000000000000000000000000000000..d4ff65e5770ec8914ecf9b70f6b97834685eaed8 GIT binary patch literal 392 zcmZ{g-3o$06oltG=ur%RBJiST5i`@Jbj3BOm#=1yC=`UK>+XCrb9}!lv>4&hp~M*{ z9C^jq;lMk?78~4n(xZWtB^=ig*CIOH`Q