构建智能体如此容易-400行代码搭建一个24小时不间断写小说的AI机器人
摘要
本文介绍了如何使用Python和Tkinter结合本地大语言模型(LLM)构建一个全自动小说创作AI机器人。这个应用仅用不到400行代码就实现了从创意生成到自动写作的全流程,可以24小时不间断地创作小说。文章详细讲解了关键技术点、代码实现以及解决各种挑战的技巧,最后展望了未来可能的发展方向。无论你是AI爱好者还是Python开发者,都能从中获取有价值的经验和灵感。
完整代码见文章末尾。
生成小说片段示例
南宋末年的京城汴梁,朝局纷争不断。宰相赵鼎忠心耿耿辅佐幼主,却屡遭奸佞秦桧的排挤打压。翁蒙之,一位年轻英俊且武艺高强的护卫,自小便在赵府长大,与赵家子女情同手足。他敏锐地察觉到朝廷中暗流涌动,那股欲加害赵鼎全家的气息日益浓烈。翁蒙之每日穿梭于赵府与朝堂之间,暗中打探消息。这日清晨,他刚从秦桧的官邸归来,神色凝重。府中的小厮见状,纷纷猜测是否又有新的变故。
“今日在相府议事时,我注意到秦大人对幼主提及‘三月之约’。”翁蒙之心生警觉,匆匆走进赵鼎书房,将所见所闻细细道来,“此话甚是玄妙,似有深意。”
赵鼎听罢,沉思片刻:“那便是三月初三,在先皇驾崩百日之时……”他望向翁蒙之,眼中闪过一丝忧色。“秦相此举,莫不是欲借机除去忠臣?”
翁蒙之心领神会,“我已探得消息,此次‘三月之约’恐不只是祭奠仪式这般简单。秦桧欲在那日邀您前往郊外亭台,或有密谋。”
赵鼎点头:“看来是时候提前筹谋了。”他握紧茶杯,“蒙之啊,你平日里便多加留意,若有什么异样,务必第一时间告知我。”
翁蒙之应声离去,心中暗下决心。他知道,这场关乎赵府存亡的棋局,已在悄然间拉开帷幕。翁蒙之离开赵府后,并未直接回自己的住处。他沿着汴梁蜿蜒的街道疾步而行,目光如炬,似在搜寻着什么。沿途行人匆忙穿梭,却难掩京城笼罩下的不安氛围。他来到城郊一座酒肆前停下脚步,在这家常来光顾的小店里,有一位老友是秦府中的厨子,与他素有交情。
翁蒙之推门而入,店内弥漫着酒香和热菜的香气。店小二一见是他,连忙笑着招呼:“公子好!”
“给我一碗温酒。”翁蒙之坐在靠窗的位置,目光投向忙碌的后厨。“老李呢?今日怎么不见他。”
不一会儿,一位瘦削、精明的老者探头出来,正是老李。老李一眼认出翁蒙之,眼中闪过一丝惊喜,“翁公子来了啊!许久未见了。”说罢便端着酒壶过来为他斟上一杯。
“近日城中风声鹤唳,老友你还好?”翁蒙之一饮而尽杯中美酒。
老李将酒壶放下,在桌上坐下。“还算安好。只是秦府上下皆小心翼翼,近来又添了不少新面孔,都是些不熟悉的人。”
翁蒙之心中一动:“可有什么可疑之处?”
老李轻声说道,“前几日见府中一位新人频繁出入书房和后院,尤其在夜间。我虽不敢多问,却也听闻那人在秦大人面前颇受重用。”翁蒙之微微蹙眉,“此人可有来历?莫非是秦桧新收的亲信?”他轻抿一口温酒,目光深邃。
老李摇摇头:“听说是他远房侄子,名叫秦佑。据说此人善于察言观色,处事圆滑。不过我总觉得……”他稍作停顿,“这人心思不似常人。”
翁蒙之心中一凛,若真有此人在暗中助力,秦桧的布局更加深不可测。“老友你可曾听闻秦佑夜间往来的方向?是否都与赵府有关?”
老李沉吟片刻:“确实有几个夜晚,见他行色匆匆向西而去。那方向正是通往赵府所在的官道。”
翁蒙之顿时心生疑惑,“莫不是他在暗中联络赵鼎?此人来头不小。”他起身踱步,若有所思。
“公子可是察觉什么?”老李望着他的背影问道。
翁蒙之停步片刻:“我料秦佑与赵府往来甚密,或是试探,或是挑拨。这日夜晚,你不妨再留意几分。”
老李点头,“明日一早,我会将所见告知于你。”
翁蒙之转身离去,在月光下身影渐远。他心中盘算着下一步的对策:若秦佑确为赵府使者,则赵鼎或已有所察觉;若是挑拨离间,则需谨慎应对。无论何种情形,皆不可掉以轻心。翁蒙之回到赵府时已是月上梢头。他径直来到赵鼎书房,将老李提供的信息详尽道来。赵鼎听后沉思良久:“秦佑夜间频访赵府……看来这局棋并非表面那般简单。”他站起身踱步于窗前,“秦桧此举,或是试探我等虚实,或是欲借此人之力分化我们。”
翁蒙之点头赞同:“大人所言极是。若是挑拨离间,秦佑或许正是最佳人选。此人善于察言观色,行事谨慎,在秦府中颇受信赖;但若与赵府暗通款曲,则更显高明。”他稍作停顿,“我料那夜秦佑所去之处,必有所图。”
“蒙之你说得不错。”赵鼎点头。“此人心机深沉,不似寻常之人。莫不是秦桧故意派此人来试探我们与幼主的关系?”
翁蒙之心念一动:“大人若有意确认此事,不妨让令郎前往郊游时暗中相约秦佑。如此既可探知对方真实意图,又不失礼数。”
赵鼎眸光微亮:“此计甚好。”他微微一笑,“不过还需谨慎行事,莫让人察觉破绽。”
翁蒙之领命而出,心中已然有了计划。“明日一早我便前往郊外与秦佑相约。既在亭台间相会,便让他知晓赵府并非易与。”
次日清晨,天色微明,翁蒙之带着几个随从来到郊外亭台附近。此处是幼主和众臣议政的常选之地,背靠青山、前临湖水,风景绝佳。他选了一处隐蔽之所稍作停留,静候秦佑到来。
不一会儿,一个身着青衫的年轻人缓步而来,正是秦佑。他见四周无人注意,便朝着翁蒙之藏身之处行礼道:“公子可是来赴约?”
翁蒙之现身微笑:“果然是聪明人。”他走上前,二人在亭下相对而立。“听闻秦大人欲邀赵府郊游,不知是何缘由?”秦佑微微一笑,目光如炬:“公子此言差矣。相爷邀赵府郊游,实则是为了与幼主商讨‘三月之约’的具体事宜。”他轻摇折扇,“这日于亭台间叙谈,既显诚意,又不失礼数,何乐而不为?”
翁蒙之闻言心中一动:“如此说来,秦大人确有意借祭奠之机与赵相商议大事。不过,公子可有闻及那‘三月之约’的具体内容?”
秦佑从容答道:“三月初三郊游之时,幼主将与众臣共赏先皇百日祭礼,并在亭台间叙谈国事。相爷欲借此机会与赵府交换条件,或许能解朝廷纷争。”
翁蒙之微微点头:“公子所言极是。然而,秦大人此举究竟意在试探?还是别有用心?”他目光深邃,“是否已有所图,却未明说?”
秦佑轻抚折扇,略显思索:“此事或真如赵府所疑,秦相欲借机挑拨幼主与忠臣之谊。但公子可曾想过,若赵府能化解成见,未必不可携手共济?”
翁蒙之心念一动:“公子此言颇有深意。莫非秦佑已窥得朝廷暗潮?”
秦佑浅笑:“公子聪慧,确是如此。”他望向湖水,“幼主年少志远,若能化解赵府与秦府之嫌隙,或可使天下共济。”
翁蒙之目光闪烁:“那公子以为如何,方能使双方信之不疑?”
秦佑略一沉吟:“三月初三于亭台间相会之时,何不让令郎暗中携宝物前往,以表诚意。如此既显忠诚,又不失体面,幼主与赵府或能共商国是。”
翁蒙之点头赞许:“公子所言极妙。”他稍作停顿,“不过秦佑还需小心提防,莫让人察觉破绽。”
秦佑笑道:“公子放心,我自有安排。三月初三午时,令郎可携宝物前来亭台相会,幼主与赵府或能共商国是。”
翁蒙之微笑致谢:“多谢公子提醒。”他转身离去,“既为试探,则需谨慎行事;若有机缘,亦不可错过。”翁蒙之离去后,秦佑微微一笑,转身走向亭台深处。他轻声自语:“幼主年少志远,若能化解赵府与秦府之嫌隙,或可使天下共济。”然而,他的目光中闪过一丝不易察觉的忧色。
自动输出小说文件(generated_novels文件夹)
引言
随着大语言模型的快速发展,AI创作已经不再是科幻小说中的场景。特别是开源大模型的出现,让个人开发者也能够构建强大的AI应用。本文将展示如何使用不到400行Python代码,结合本地运行的大语言模型,构建一个可以全自动、连续不断地创作小说的AI机器人。
核心知识点和代码实现
1. 系统架构
这个AI小说创作系统由以下几个核心组件构成:
- UI界面:使用Tkinter构建直观的用户界面
- 本地LLM调用:通过API调用本地部署的大语言模型
- (其中1个生成模型用于生成提示词;1个推理模型用于写作内容)
- 两个模型通过ollama下载,其中qwq是32B模型,笔者的GPU是16G显存,专业的DELL图形工作站,对电脑配置要求较高,建议如果电脑配置一般可以换 ollama run deepseek-r1(7b),系统GPU至少4G显存。
- ollama pull qwq:latest
- ollama pull huihui_ai/qwen2.5-1m-abliterated:14b
- 自动创意生成:自动生成多样化的小说创作需求
- 连续创作机制:实现不间断的创作循环
- 自动保存功能:将创作结果自动保存为txt文件
2. 界面设计
界面使用Tkinter库构建,主要包含以下部分:
# 创建主窗口和容器
root = tk.Tk()
root.title("长篇小说写作助手")
root.geometry("1000x800")
# 创建输入区域(写作要求和目标字数)
prompt_entry = tk.Text(prompt_container, width=50, height=3, font=('Microsoft YaHei UI', 10))
word_count_entry = tk.Entry(word_count_frame, width=10)
# 控制按钮区域
generate_button = tk.Button(button_frame, text="开始生成", command=generate_text)
stop_button = tk.Button(button_frame, text="停止生成", command=stop_generation)
auto_generate_button = tk.Button(button_frame, text="自动生成", command=toggle_auto_generate)
# 输出显示区域
output_text = scrolledtext.ScrolledText(output_frame, wrap=tk.WORD, width=100, height=30)
整个界面采用分区设计,直观易用,通过状态标签提供实时反馈。
3. 与本地大模型的交互
系统通过HTTP API与本地部署的OLLAMA大语言模型进行交互,支持流式响应:
def generate_user_prompt():
try:
api_url = 'http://localhost:11434/api/generate'
prompt = '''你是一个创意写作专家,请生成一个有趣的小说写作要求...'''
request_data = {
"model": model_name,
"prompt": prompt,
"temperature": 0.9,
"stream": False
}
response = requests.post(api_url, json=request_data, timeout=30)
result = response.json()
new_prompt = result.get('response', '').strip()
# 更新提示词输入框
prompt_entry.delete("1.0", tk.END)
prompt_entry.insert("1.0", new_prompt)
return True
except Exception as e:
update_status(f"生成写作要求时出错:{str(e)}")
return False
对于小说内容的生成,使用流式响应处理,实现实时显示生成内容:
# 处理流式响应
for line in response.iter_lines():
if not is_generating:
break
if line:
data = json.loads(line.decode('utf-8'))
text_chunk = data.get('response', '')
output_text.insert(tk.END, text_chunk)
output_text.see(tk.END) # 自动滚动到最新内容
root.update_idletasks() # 更新UI
new_content += text_chunk
4. 自动创作循环
系统的核心特点是实现了全自动创作循环,包含以下步骤:
- 自动生成创意写作需求
- 基于需求生成小说内容
- 达到目标字数后自动保存
- 重新调用大模型生成新的创意需求并开始下一篇
关键代码:
# 自动生成的处理函数
def auto_generate():
global is_auto_generating
is_auto_generating = True
auto_generate_button.config(text="停止自动生成")
# 开始第一轮生成
if generate_user_prompt():
generate_text()
# 保存内容并继续循环
def save_content_to_file():
# ...保存文件代码...
# 如果是自动生成模式,则继续生成下一个故事
if is_auto_generating:
root.after(2000, lambda: continue_auto_generate())
# 继续自动生成的方法
def continue_auto_generate():
if is_auto_generating and not is_generating:
if generate_user_prompt():
generate_text()
5. 多线程处理
为了保持UI的响应性,文本生成过程在单独的线程中执行:
def generate_text():
global is_generating
is_generating = True
# 开始定期更新状态
periodic_status_update()
# 创建一个新线程来执行生成过程
thread = threading.Thread(target=generate_text_thread)
thread.daemon = True
thread.start()
疑难点技巧
1. 处理流式响应
与传统的一次性返回不同,流式响应需要特殊处理。我们采用迭代处理响应行的方式,逐步更新界面:
for line in response.iter_lines():
if line:
data = json.loads(line.decode('utf-8'))
text_chunk = data.get('response', '')
output_text.insert(tk.END, text_chunk)
output_text.see(tk.END)
2. 非阻塞UI更新
为了避免在生成过程中UI冻结,我们采用了以下策略:
- 使用多线程分离UI和生成过程
- 定期更新UI而不是连续更新
- 使用
root.update_idletasks()
确保UI响应性
def periodic_status_update():
if is_generating:
word_count = len(re.findall(r'[\u4e00-\u9fff]', generated_content)) + len(re.findall(r'\b[a-zA-Z]+\b', generated_content))
update_status(f"正在生成中...当前已生成约{word_count}字")
update_timer = root.after(500, periodic_status_update)
3. 优雅的停止机制
在AI生成过程中,实现优雅的停止是一个挑战。我们设计了多层次的检查机制:
# 停止生成的函数
def stop_generation():
global is_generating
is_generating = False
update_status("用户已停止生成")
# 在生成过程中多处检查停止标志
if not is_generating:
break
4. 字数统计的精确性
为了准确计算中英文混合文本的字数,我们使用正则表达式分别统计:
def is_writing_complete(content, target_word_count):
# 计算中文字符数(每个中文字符算一个字)
chinese_chars = re.findall(r'[\u4e00-\u9fff]', content)
# 计算英文单词数(假设英文单词由空格分隔)
english_words = re.findall(r'\b[a-zA-Z]+\b', content)
# 总字数 = 中文字符数 + 英文单词数
total_words = len(chinese_chars) + len(english_words)
return total_words >= target_word_count
总结与未来展望
这个项目展示了如何用少量代码构建一个功能强大的AI创作工具。关键成功因素:
- 简洁而强大的架构:分离UI和业务逻辑
- 灵活的大模型调用:通过API接口可以轻松切换不同模型
- 自动化创作循环:实现了从创意生成到写作完成的闭环
未来可能的改进方向包括:
- 多模型集成:支持多种大语言模型并进行结果比较
- 风格定制:允许用户选择不同的写作风格和流派
- 内容编辑:增加人工干预和编辑功能
- 记忆增强:为长篇创作增加更好的上下文管理
- 导出多格式:支持多种格式如epub、docx等
- 质量评估:增加自动评估生成内容质量的功能
结语
这个项目证明,借助现代AI技术和简洁的Python代码,构建具有创造力的AI智能体已经变得异常简单。通过400行代码,我们创建了一个可以持续创作的小说机器人,为AI辅助创作开辟了新的可能性。无论你是希望提高创作效率的作家,还是对AI应用感兴趣的开发者,这个项目都提供了宝贵的参考和起点。
你可以在GitHub上找到完整代码,欢迎下载、使用和改进这个项目,共同探索AI创作的无限可能。
完整代码及部署方法见Github代码仓链接