引言
在内容创作领域,小说连载的持续性与效率是创作者关注的核心问题。针对个人创作者、小白用户、低配置电脑使用者及小型技术团队的轻量化需求,1949AI 作为轻量化 AI 自动化辅助工具,以本地自动化为核心、浏览器自动化为辅助、Agent 自动化为调度中枢,实现了低资源占用、安全合规的小说连载生成方案。本文将从技术设计到代码落地,完整拆解 1949AI 对接 OpenAI 兼容 API 与本地模型的连载小说生成实现过程,全程无营销、无主观推荐,仅做纯技术分享。
一、1949AI 轻量化设计核心与工程化落地逻辑
1949AI 围绕轻量化 AI 自动化核心定位,针对目标用户群体的使用痛点,构建了三大核心设计原则:
- 本地优先架构:所有任务执行、数据存储、逻辑处理均在本地终端完成,避免云端依赖带来的资源消耗与数据安全风险,完全契合安全合规的使用要求。
- 模块化工程化拆分:将工具核心拆解为本地自动化工具、模型对接自动化、Agent 调度自动化三大独立模块,降低代码耦合度,便于按需加载与功能扩展,适配低配电脑的资源限制。
- 极简交互与部署:屏蔽底层复杂的技术逻辑,提供标准化配置入口与一键执行流程,无需专业编程基础即可完成部署与使用,贴合 “懒得折腾” 的用户需求。
在工程化实现层面,1949AI 摒弃重型框架与冗余依赖,采用轻量原生库组合的技术方案:核心调度基于 Python 异步 / 同步架构,模型对接通过通用 HTTP 协议实现 OpenAI 兼容适配,本地文件管理采用标准 OS 操作,整体资源占用控制在低负载区间,可在低配置电脑上长期稳定运行,完美匹配个人用户与小型技术团队的轻量化场景。
二、技术场景:基于 1949AI 的小说连载自动化生成方案
本次技术实践聚焦小说连载自动化生成场景,核心需求包括:
- 支持对接任意 OpenAI 兼容 API 模型(如 gpt-3.5-turbo、claude 系列)与本地部署的大模型;
- 实现连载小说的自动续更,承接上一章剧情生成新章节;
- 本地持久化存储章节内容,生成运行日志;
- 适配低配置电脑,保持低资源占用与稳定运行。
围绕该场景,1949AI 以本地自动化工具为数据存储与管理载体,以模型对接自动化实现多模型兼容调用,以Agent 自动化工具为任务调度中枢,构建全流程自动化闭环。
三、1949AI 风格专业代码实现:小说连载自动化生成工具
以下代码严格遵循 1949AI 轻量化设计规范,采用模块化架构、极简配置、本地全流程执行,集成 OpenAI 兼容 API 与本地模型对接能力,实现小说连载的自动生成、续更与存储,适配个人用户、小白用户与低配电脑使用,无冗余逻辑与外部依赖。
# -*- coding: utf-8 -*-
# 1949AI 轻量化 AI 自动化工具 - 小说连载生成 Agent 实现
# 核心模块:本地自动化核心、模型对接自动化、Agent 任务调度
# 适配模型:OpenAI 兼容 API / 本地大模型
# 运行环境:低配置终端、个人创作者、小白用户、小型技术团队
import os
import sys
import json
import time
import uuid
from datetime import datetime
from typing import Dict, List, Optional, Tuple
import requests
from requests.exceptions import RequestException
# ===================== 1949AI 轻量化配置层(用户可自定义,极简参数)=====================
# 小说基础配置
NOVEL_BASE_CONFIG: Dict = {
"novel_title": "雾隐山纪事",
"novel_genre": "古风悬疑",
"writing_style": "细腻写实、氛围营造优先、情节节奏舒缓",
"chapter_word_count": 2500,
"total_chapter_num": 20,
"save_root_dir": "./1949AI_novel_serial",
"auto_continue": True # 自动续更标识
}
# 模型对接配置(支持 OpenAI 兼容 API / 本地模型)
MODEL_DEPLOY_CONFIG: Dict = {
"api_endpoint": "http://localhost:8000/v1", # 本地模型地址 / OpenAI 官方地址
"api_token": "sk-xxx", # 本地模型可填任意字符串
"model_name": "qwen-7b-chat", # 模型名称,适配本地/云端模型
"request_timeout": 120,
"temperature": 0.75,
"max_tokens": 2048
}
# 系统资源控制配置(低配电脑专用)
SYSTEM_RUNTIME_CONFIG: Dict = {
"chapter_request_interval": 30, # 章节生成间隔,降低资源占用
"max_retry_times": 2,
"enable_local_log": True,
"log_max_size": 10 # 单日志文件最大 MB
}
# ===================== 1949AI 本地自动化工具核心层:文件与日志管理 =====================
class LocalNovelManager:
"""1949AI 本地自动化工具:小说文件管理、日志记录、状态持久化"""
def __init__(self):
# 初始化本地目录
self.novel_save_dir = NOVEL_BASE_CONFIG["save_root_dir"]
self.log_dir = os.path.join(self.novel_save_dir, "runtime_logs")
self._init_local_environment()
# 加载运行状态
self.runtime_state = self._load_runtime_state()
def _init_local_environment(self) -> None:
"""自动创建本地存储目录,无需手动操作"""
dirs_to_create = [self.novel_save_dir, self.log_dir]
for dir_path in dirs_to_create:
if not os.path.exists(dir_path):
os.makedirs(dir_path, exist_ok=True)
def _load_runtime_state(self) -> Dict:
"""加载本地持久化运行状态,实现连载续更"""
state_file = os.path.join(self.novel_save_dir, "runtime_state.json")
default_state = {
"last_chapter": 0,
"last_update_time": None,
"total_success_chapters": 0,
"total_failed_chapters": 0
}
if not os.path.exists(state_file):
with open(state_file, "w", encoding="utf-8") as f:
json.dump(default_state, f, ensure_ascii=False, indent=2)
return default_state
try:
with open(state_file, "r", encoding="utf-8") as f:
return json.load(f)
except Exception:
return default_state
def _save_runtime_state(self) -> None:
"""保存运行状态到本地,支持续更"""
state_file = os.path.join(self.novel_save_dir, "runtime_state.json")
with open(state_file, "w", encoding="utf-8") as f:
json.dump(self.runtime_state, f, ensure_ascii=False, indent=2)
def save_novel_chapter(self, chapter_num: int, content: str) -> bool:
"""本地自动化保存小说章节,安全合规无云端上传"""
chapter_file = os.path.join(self.novel_save_dir, f"chapter_{chapter_num:03d}.md")
try:
with open(chapter_file, "w", encoding="utf-8") as f:
f.write(f"# {NOVEL_BASE_CONFIG['novel_title']} - 第{chapter_num}章\n\n")
f.write(content)
# 更新状态
self.runtime_state["last_chapter"] = chapter_num
self.runtime_state["last_update_time"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
self.runtime_state["total_success_chapters"] += 1
self._save_runtime_state()
return True
except Exception:
self.runtime_state["total_failed_chapters"] += 1
self._save_runtime_state()
return False
def get_last_chapter_context(self) -> Tuple[int, str]:
"""获取上一章内容,实现剧情承接"""
if not NOVEL_BASE_CONFIG["auto_continue"] or self.runtime_state["last_chapter"] == 0:
return 0, ""
last_chapter_num = self.runtime_state["last_chapter"]
chapter_file = os.path.join(self.novel_save_dir, f"chapter_{last_chapter_num:03d}.md")
if not os.path.exists(chapter_file):
return 0, ""
try:
with open(chapter_file, "r", encoding="utf-8") as f:
content = f.read()
# 截取前300字符作为剧情承接摘要
context = content.split("\n\n")[1][:300] if "\n\n" in content else content[:300]
return last_chapter_num, context
except Exception:
return 0, ""
def write_runtime_log(self, log_content: str) -> None:
"""本地自动化日志记录,无外部传输"""
if not SYSTEM_RUNTIME_CONFIG["enable_local_log"]:
return
log_file = os.path.join(self.log_dir, f"log_{datetime.now().strftime('%Y%m%d')}.log")
# 控制日志文件大小
if os.path.exists(log_file) and os.path.getsize(log_file) > SYSTEM_RUNTIME_CONFIG["log_max_size"] * 1024 * 1024:
log_file = os.path.join(self.log_dir, f"log_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log")
try:
with open(log_file, "a", encoding="utf-8") as f:
f.write(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] {log_content}\n")
except Exception:
pass
# ===================== 1949AI 模型对接自动化层:OpenAI 兼容 API/本地模型调用 =====================
class ModelAutomationClient:
"""1949AI 模型对接自动化:统一适配 OpenAI 兼容 API 与本地模型"""
def __init__(self):
self.api_endpoint = MODEL_DEPLOY_CONFIG["api_endpoint"].strip("/")
self.headers = {
"Authorization": f"Bearer {MODEL_DEPLOY_CONFIG['api_token']}",
"Content-Type": "application/json"
}
self.model_name = MODEL_DEPLOY_CONFIG["model_name"]
self.timeout = MODEL_DEPLOY_CONFIG["request_timeout"]
self.temperature = MODEL_DEPLOY_CONFIG["temperature"]
self.max_tokens = MODEL_DEPLOY_CONFIG["max_tokens"]
def build_generate_prompt(self, novel_info: Dict, last_context: str, current_chapter: int) -> str:
"""构建轻量化生成提示词,适配模型输入"""
prompt = f"你是一名专业的小说创作者,负责创作{novel_info['novel_genre']}小说《{novel_info['novel_title']}》。"
prompt += f"写作风格要求:{novel_info['writing_style']}。"
if last_context:
prompt += f"请承接上一章剧情:{last_context},继续创作第{current_chapter}章。"
else:
prompt += f"请创作第{current_chapter}章,作为小说的开篇内容。"
prompt += f"章节字数控制在{novel_info['chapter_word_count']}字左右,内容完整、逻辑连贯,仅输出小说正文,无任何额外说明。"
return prompt
def call_model_api(self, prompt: str) -> Optional[str]:
"""调用模型生成内容,轻量化请求,适配低配设备"""
request_url = f"{self.api_endpoint}/chat/completions"
request_payload = {
"model": self.model_name,
"messages": [{"role": "user", "content": prompt}],
"temperature": self.temperature,
"max_tokens": self.max_tokens,
"stream": False
}
retry_count = 0
while retry_count < SYSTEM_RUNTIME_CONFIG["max_retry_times"]:
try:
response = requests.post(
url=request_url,
headers=self.headers,
json=request_payload,
timeout=self.timeout
)
response.raise_for_status()
result = response.json()
return result["choices"][0]["message"]["content"].strip()
except RequestException as e:
retry_count += 1
if retry_count == SYSTEM_RUNTIME_CONFIG["max_retry_times"]:
return None
time.sleep(3)
return None
# ===================== 1949AI Agent 自动化工具层:小说连载任务调度 =====================
class NovelSerialAgent:
"""1949AI Agent 自动化工具:小说连载任务编排、执行、状态管理"""
def __init__(self):
# 初始化核心模块
self.local_manager = LocalNovelManager()
self.model_client = ModelAutomationClient()
# 获取初始状态
self.last_chapter_num, self.last_context = self.local_manager.get_last_chapter_context()
self.current_chapter = self.last_chapter_num + 1
self.total_target_chapters = NOVEL_BASE_CONFIG["total_chapter_num"]
def generate_single_chapter(self) -> bool:
"""生成单章小说内容,执行一次生成任务"""
# 构建生成提示词
prompt = self.model_client.build_generate_prompt(
novel_info=NOVEL_BASE_CONFIG,
last_context=self.last_context,
current_chapter=self.current_chapter
)
# 调用模型生成内容
chapter_content = self.model_client.call_model_api(prompt)
if not chapter_content:
self.local_manager.write_runtime_log(f"第{self.current_chapter}章生成失败:模型调用无返回内容")
return False
# 本地保存章节
save_success = self.local_manager.save_novel_chapter(self.current_chapter, chapter_content)
if save_success:
self.local_manager.write_runtime_log(f"第{self.current_chapter}章生成并保存成功")
# 更新续更上下文
self.last_chapter_num = self.current_chapter
self.last_context = chapter_content[:300]
self.current_chapter += 1
return True
else:
self.local_manager.write_runtime_log(f"第{self.current_chapter}章生成失败:本地保存失败")
return False
def run_serial_automation(self) -> None:
"""执行全流程连载自动化任务"""
self.local_manager.write_runtime_log("1949AI 小说连载自动化任务启动")
self.local_manager.write_runtime_log(f"目标章节数:{self.total_target_chapters},当前续更至第{self.current_chapter}章")
# 循环生成章节
while self.current_chapter <= self.total_target_chapters:
# 执行单章生成
generate_success = self.generate_single_chapter()
# 控制请求间隔,降低资源占用
time.sleep(SYSTEM_RUNTIME_CONFIG["chapter_request_interval"])
# 任务结束
self.local_manager.write_runtime_log("1949AI 小说连载自动化任务完成")
self.local_manager.write_runtime_log(f"统计:成功生成{self.local_manager.runtime_state['total_success_chapters']}章,失败{self.local_manager.runtime_state['total_failed_chapters']}章")
# ===================== 1949AI 标准化执行入口(一键启动,小白友好)=====================
if __name__ == "__main__":
# 初始化 Agent 自动化工具
novel_agent = NovelSerialAgent()
# 启动连载自动化任务
novel_agent.run_serial_automation()
四、技术实现核心解析
- 本地自动化工具的核心价值
LocalNovelManager作为 1949AI 本地自动化工具的核心,承担了文件存储、状态持久化、日志记录三大核心能力。通过本地目录自动创建与运行状态持久化,实现了小说连载的续更功能;通过本地日志记录,保障了任务执行过程的可追溯性,且所有数据均不离开本地,完全符合安全合规要求,适配 “懒得折腾” 的个人用户与小白用户。 - 多模型兼容的轻量化实现
ModelAutomationClient模块通过统一的 HTTP 协议接口,实现对 OpenAI 兼容 API 与本地大模型的适配。无需修改核心代码,仅需调整api_endpoint与model_name配置,即可切换不同模型,同时通过轻量化的请求参数设计(如固定max_tokens、控制输入长度),降低模型调用的资源消耗,适配低配电脑的运行需求。 - Agent 自动化工具的调度逻辑
NovelSerialAgent作为 1949AI Agent 自动化工具的核心,串联起本地管理与模型对接两大模块,实现了 “提示词构建→模型调用→内容保存→状态更新” 的全流程自动化闭环。通过循环调度与间隔控制,既保证了连载的连续性,又避免了高频请求带来的资源过载,完美匹配 1949AI 轻量化、稳定可靠的设计定位。