基于多智能体架构的AI网文创作平台:Hermes Writer全栈开发实践
1. 项目概述一个为网文作者打造的AI创作“副驾驶”如果你和我一样是个对写故事有热情但又时常被卡文、角色塑造、世界观设定这些“大工程”折磨得焦头烂额的创作者那么今天聊的这个项目可能会让你眼前一亮。它不是另一个简单的AI写作助手而是一个野心勃勃的、试图将整个网文创作流程“工业化”的智能平台——Hermes Writer。简单来说你可以把它理解为一个为你配备了“专业编剧团队”的私人工作室。这个团队里有负责策划剧情的“编剧”有专门塑造角色的“演员指导”有构建世界的“美术设定”还有负责文字润色和最终质检的“编辑”。而“你”作为总导演也就是作者只需要提出核心创意然后通过一个直观的界面来协调、审核并最终拍板这个“AI团队”产出的内容。它的核心价值在于将AI从“一个模糊的对话对象”变成了“一套分工明确、可被精确调度的生产工具”这背后依赖的正是其独特的Hermes Agent 多智能体架构。这个项目完全开源技术栈选型非常现代且务实前端用Next.js 16构建享受React服务端组件和App Router带来的开发体验与性能优势样式是Tailwind CSS 4搭配高度定制化的shadcn/ui组件库保证了UI的精致与一致性数据层用Prisma ORM操作SQLite开发阶段轻便后续切换生产级数据库也容易AI能力则接入了NVIDIA的NIM API直接调用GLM和Kimi这类顶尖的大语言模型。整套东西跑下来从克隆代码到本地看到界面大概也就十分钟的事。它适合所有阶段的网文作者新手可以用它来快速学习一套完整的创作方法论克服无从下笔的恐惧老手则可以把它当作一个强大的“灵感加速器”和“内容生产副驾驶”把重复性的构思劳动交给AI自己更专注于核心创意和最终把控。2. 核心架构解析为什么是“多智能体”在深入代码之前我们必须先搞懂这个项目最核心的设计思想多智能体Multi-Agent系统。市面上绝大多数AI写作工具本质上是“单点突破”。你给一个指令比如“写一段仙侠小说的打斗场景”它生成一段文字。这很好但局限性也很明显它缺乏“记忆”和“分工”每次交互都是孤立的难以维护一个长篇故事所需的、贯穿始终的一致性角色性格、世界观规则、剧情伏笔等。Hermes Writer的解法非常聪明将网文创作这个复杂任务拆解成多个专业子任务并为每个子任务训练或者说配置一个专门的“智能体Agent”。这就像组建一个剧组而不是指望一个全能的天才搞定所有事。2.1 Hermes Agent 架构深度拆解项目文档里那张架构图很直观但我想结合我的开发经验为你解读一下每个Agent的“人设”和它们之间协同工作的“工作流”这能帮你更好地理解后续的代码实现。 Hermes赫尔墨斯主控Agent这是整个系统的“大脑”和“调度中心”。它不直接生成任何具体内容比如一段对话或一个场景它的核心职责是流程编排和上下文管理。举个例子当你命令系统“为我的玄幻小说《星辰变》生成第三章”时Hermes会接手这个模糊的指令并分解为一系列有序的子任务调用Planner剧情策划师基于前两章的大纲和内容规划第三章的核心情节、冲突点和高潮位置。调用Character角色管家获取本章节会出场的主要角色如主角“秦羽”、反派“项央”的详细档案包括性格、说话风格、当前实力境界等。调用WorldBuilder世界观构建师获取与本章节相关的世界观设定比如“潜龙大陆的修炼等级体系”、“本场战斗发生的‘洪荒’区域的地理特点”。将以上所有信息剧情大纲、角色档案、世界观整理成一份详细的、结构化的“创作指令”交给Writer内容创作者。Writer生成初稿后Hermes会先将稿件交给Editor文字编辑进行润色再交给Reviewer质量审核员从读者视角进行逻辑和趣味性审查。最后Hermes将审核后的版本呈现给你并记录下整个任务链中每个Agent的输入输出形成可追溯的“任务历史”。你可以把Hermes看作一个极其称职的项目经理它确保每个专业环节都被正确触发并且上游环节的产出能无缝传递给下游环节。️ Planner剧情策划师它的Prompt指令被设计得非常像一位资深网文编辑。它接收的输入包括故事类型如“都市异能”、已有大纲、前文内容、目标章节数。它的输出不是一个简单的段落而是一个结构化的章节规划可能包括章节标题吸引人的标题。核心目标本章要完成什么剧情推进例如主角发现神秘玉佩的秘密。情节点序列用几个关键场景串联起本章如“日常铺垫 - 冲突触发 - 探索解谜 - 小高潮战斗 - 留下新悬念”。伏笔设置在本章中需要埋下哪些为后续章节服务的线索。情绪曲线本章希望带给读者的情绪变化紧张-放松-震惊。实操心得在调试Planner Agent时最大的坑是防止它生成过于俗套或跳跃的剧情。我们的经验是在它的系统指令System Prompt里加入明确的约束比如“避免使用‘突然一道黑影闪过’这类陈词滥开篇”“确保情节转折有前文铺垫符合角色当前动机”。同时要提供足够多的前文摘要作为上下文否则它很容易“失忆”写出前后矛盾的情节。✍️ Writer内容创作者 Editor文字编辑这是最容易被混淆的两个Agent。Writer是“创作型选手”负责从无到有根据Planner提供的大纲和Hermes整合的上下文生成丰富的叙述、对话和描写。它的重点是“生产内容”。 而Editor是“修正型选手”它不添加新情节只对现有文本进行打磨。它的工作可能包括语法与错别字修正基础但重要。风格统一确保全文的叙述视角如第一人称、语言风格偏白话还是偏文雅一致。节奏优化调整过长的描述性段落强化关键动作和对话的节奏感。词汇升级将“很好”替换为“精妙绝伦”将“跑得很快”替换为“身形如电般疾掠而出”。在实现上Writer和Editor会使用不同的Prompt模板。Writer的Prompt更开放鼓励发散Editor的Prompt则更收敛强调“遵循原文意图进行优化”。 Character角色管家 WorldBuilder世界观构建师这两个Agent是维护故事“一致性”的基石。它们本质上是结构化数据的生成与管理工具。Character Agent当你需要创建一个新角色时你可以给出一个简单描述如“一个出身寒门但坚韧不拔的少年剑客”。Character Agent会生成一份包含姓名、年龄、外貌、性格特质、核心动机、成长弧光、口头禅、技能体系等字段的详细档案。这份档案会被存入数据库。之后每当Writer要写这个角色的对话或行为时Hermes都会从数据库中调取这份档案并作为上下文喂给Writer确保角色“人设不崩”。WorldBuilder Agent同理用于生成和管理“修炼体系”、“世界地图”、“势力分布”、“特殊宝物”等设定。例如你可以让它基于“东方玄幻”和“灵气复苏”两个标签生成一套从“炼气期”到“大乘期”的详细修炼等级每个等级的特征、突破难点、实力表现都清晰定义。✅ Reviewer质量审核员这是从“读者视角”出发的质检关口。它的任务不是修改文字而是评估和打分。它会从以下几个维度给生成的章节初稿评分逻辑连贯性情节发展是否符合前文设定和角色动机吸引力开篇是否抓人章节结尾是否有悬念文笔流畅度阅读起来是否顺畅网文特性是否包含了足够的“爽点”、“期待感”等网文核心要素 Reviewer会生成一份评分报告和具体的修改建议如“中间段落的日常描写略显冗长建议压缩以加快节奏”这份报告会反馈给HermesHermes可以据此决定是否让Editor进行二次修改或者直接提示作者进行人工干预。2.2 技术栈选型的背后逻辑为什么用这套技术组合这绝不是简单的“追新”而是经过权衡的务实选择。Next.js 16 (App Router)这是项目的基石。App Router带来的服务端组件RSC能力至关重要。像作品列表、章节内容这些大量数据的渲染可以直接在服务端完成生成静态HTML发送到浏览器首屏加载速度极快且对SEO友好。同时它的API Routes功能让我们能非常自然地在同一个项目中实现后端逻辑那些/api/agents/generate等接口前后端一体化管理部署简单。TypeScript Prisma网文创作涉及复杂的数据关系一部作品Novel有多个章节Chapter多个角色Character一套世界观WorldSetting以及大量的AI任务记录AgentTask。TypeScript的强类型和Prisma的强类型ORM是天作之合。在prisma/schema.prisma中定义好模型关系后不仅数据库操作安全省心而且整个前端到后端的类型都是联动的极大减少了低级错误。SQLite开发初期和轻量级部署的首选。它只是一个文件无需安装和配置复杂的数据库服务。配合Prisma本地开发体验流畅。项目也预留了扩展性DATABASE_URL环境变量可以轻松替换为PostgreSQL或MySQL的连接字符串。Zustand TanStack Query状态管理采用组合拳。Zustand用于管理全局的、简单的UI状态比如侧边栏是否折叠、当前主题是明是暗。而TanStack Query原React Query则专门负责管理服务器状态即从API获取的数据。它会自动处理缓存、后台刷新、请求去重等复杂问题。例如当你修改了一个章节内容并保存后TanStack Query可以自动在后台重新获取作品数据更新UI而你无需手动操作状态。NVIDIA NIM API这是AI能力的来源。选择NIM而非直接调用OpenAI或国内其他厂商的API一个重要考虑是性能和稳定性。NIM提供了优化后的推理端点对于GLM、Kimi这类模型响应速度通常更有保障。同时一个API密钥可以切换多个模型GLM-4, GLM-5, Kimi-2.5给了用户根据需求是追求创意还是追求逻辑和预算进行选择的空间。3. 从零开始本地部署与核心功能实操理论说得再多不如亲手跑起来看看。我们一步步来把这个“AI编剧团队”请到你的本地电脑上。3.1 环境准备与项目启动首先确保你的开发环境符合要求。Node.js 18是必须的我强烈推荐使用Bun作为包管理和运行时工具它的安装速度和执行效率比npm/yarn快得多而且原生支持TypeScript和.env文件与这个项目是绝配。# 1. 安装Bun (如果尚未安装) # 在终端执行以下命令具体请参考 bun.sh 官网 curl -fsSL https://bun.sh/install | bash # 2. 克隆项目代码 git clone https://github.com/dav-niu474/Hermes-Writer.git cd Hermes-Writer # 3. 安装项目依赖 bun install # 使用 bun install 通常比 npm install 快一个数量级 # 4. 配置AI模型密钥 cp .env.example .env.local # 用文本编辑器打开 .env.local 文件接下来是最关键的一步配置AI密钥。打开.env.local文件你需要填入NVIDIA_API_KEY。这个密钥需要你去 NVIDIA AI Foundation Models 官网注册并获取。通常NVIDIA会提供一定的免费额度供开发者试用。将密钥填入DATABASE_URLfile:./db/custom.db NVIDIA_API_KEY你的_实际_NVIDIA_API_密钥_在这里 NVIDIA_BASE_URLhttps://integrate.api.nvidia.com/v1 # NEXTAUTH_SECRET 和 NEXTAUTH_URL 在初期可以先注释掉等需要用户功能时再配置保存文件后初始化数据库并启动开发服务器# 5. 初始化数据库Prisma会根据schema创建SQLite文件并生成客户端 bun run db:push # 6. 启动开发服务器 bun run dev如果一切顺利打开浏览器访问http://localhost:3000你应该能看到Hermes Writer的界面了。默认是暗色主题整体布局非常清晰。3.2 创建你的第一部AI辅助作品启动后我们直奔核心功能体验一下多智能体是如何协作的。进入创作空间在左侧导航栏点击“创作空间”或中间的“开始创作”按钮。新建作品点击“新建作品”填写基本信息。例如作品标题《我在仙界搞科研》作品类型选择“玄幻·科幻”这会影响后续AI生成内容的风格倾向。简介一句话描述如“一个现代理工男穿越到仙界用科学思维解构修仙法则引发一系列啼笑皆非又颠覆认知的故事。”启动Hermes生成开篇创建成功后你会进入三栏创作空间。中间是主编辑器右侧就是AI助手面板。确保顶部的“主控Agent”下拉菜单选中了“Hermes”。在AI助手的输入框里你可以用自然语言下达指令。例如输入“请为这部作品生成一个详细的故事大纲和前两章内容。”点击发送。这时请注意观察界面。你会看到状态提示Hermes正在调度。首先Planner Agent会被触发生成一份包含核心冲突、主角目标、前期主线剧情分章的大纲。这个大纲会以结构化的形式显示在左侧的“章节大纲视图”中。接着Hermes会依次调度Character Agent和WorldBuilder Agent为主角可能还有初始反派创建角色卡并为“仙界”构建基础的修炼体系、势力分布等世界观设定。这些内容可以在对应的“角色”和“世界观”面板中查看。最后Writer Agent会依据以上所有材料开始撰写第一章的正文。你会看到文字以流式响应的方式逐字逐句地出现在编辑器中体验非常流畅。与AI协同编辑第一章生成后你可以直接在上面修改。如果想针对某一段落进行优化可以选中那段文字然后在右侧AI助手面板切换Agent为“Editor”输入指令如“将这段打斗描写得更具画面感一些”Editor就会针对你选中的文本进行润色。你也可以切换为“Writer”输入“在当前位置让主角意外发现一个不符合仙界物理规律的遗迹”让它进行续写。使用角色对话功能这是非常有趣的功能。在“角色”面板中点击你已经创建好的主角角色卡通常会有一个“对话”按钮。点击后你可以模拟与这个角色进行对话。AI会基于该角色的性格档案由Character Agent生成来回应你。这不仅是获取灵感的工具更是深度挖掘角色内心、测试角色人设一致性的绝佳方式。踩坑实录在早期测试中我们发现如果一次性让Hermes生成太多内容比如“直接生成前十章”容易出现上下文溢出Token超限和后续剧情偏离主线的问题。最佳实践是采用“迭代式创作”先让Hermes生成一个总体大纲和第一章。你审核、修改并确认后再基于已有的、你认可的内容指令它生成第二章。这样每一步的上下文都是坚实和准确的AI也不容易“跑偏”。3.3 核心代码模块解读理解了操作流程我们再深入到几个关键代码模块看看这些炫酷的功能是如何实现的。1. AI客户端与多模型切换 (src/lib/ai.ts)这个文件封装了与NVIDIA NIM API的通信。核心是一个createChatCompletion函数它接收模型名称、消息列表即Prompt等参数。// 简化后的核心逻辑示例 import { OpenAI } from openai; // NVIDIA NIM API兼容OpenAI格式 const nvidiaClient new OpenAI({ apiKey: process.env.NVIDIA_API_KEY, baseURL: process.env.NVIDIA_BASE_URL, }); export async function createChatCompletion( model: glm-4 | glm-5 | kimi-2.5, // 可切换的模型 messages: Array{ role: system | user | assistant; content: string }, stream: boolean true // 默认启用流式响应 ) { const response await nvidiaClient.chat.completions.create({ model: model, messages: messages, stream: stream, temperature: 0.7, // 创造性参数 max_tokens: 2000, }); if (stream) { // 处理流式数据逐块返回给前端 return handleStreamingResponse(response); } else { return response.choices[0].message.content; } }前端的模型切换UI其实就是调用这个函数时传入不同的model参数。system角色的消息通常用来定义Agent的“人设”和指令user消息则是具体的任务要求。2. Agent任务编排中枢 (src/app/api/agents/generate/route.ts)这是后端处理AI生成请求的核心入口。它是一个Next.js App Router的API Route。// 极度简化的流程示意 export async function POST(request: Request) { const { agentType, novelId, instruction } await request.json(); // 1. 身份验证如果启用 // const session await getServerSession(authOptions); // 2. 根据agentType从数据库获取相关上下文 const novel await db.novel.findUnique({ where: { id: novelId }, include: { chapters: true, characters: true, worldSettings: true }, }); // 3. 构建对应Agent的Prompt let systemPrompt ; let userPrompt ; switch (agentType) { case hermes: systemPrompt HERMES_SYSTEM_PROMPT; // 定义Hermes职责的长文本 userPrompt 作品《${novel.title}》的指令${instruction}。请协调其他Agent完成任务。; break; case planner: systemPrompt PLANNER_SYSTEM_PROMPT; userPrompt 基于以下信息为作品《${novel.title}》规划剧情${novel.synopsis}...; break; // ... 其他Agent cases } // 4. 调用AI客户端 const stream await createChatCompletion(glm-4, [ { role: system, content: systemPrompt }, { role: user, content: userPrompt }, ], true); // 5. 返回流式响应前端实时显示 return new Response(stream); }关键点每个Agent的systemPrompt是其灵魂所在需要精心设计。例如Planner的Prompt会详细规定它输出大纲的JSON结构Character的Prompt会要求它输出包含特定字段的角色卡。3. 三栏可调节布局的实现创作空间的三栏布局大纲/编辑器/AI助手采用了CSS Grid结合react-resizable-panels库实现。代码在src/components/platform/workspace-view.tsx中。import { Panel, PanelGroup, PanelResizeHandle } from react-resizable-panels; export function WorkspaceView() { return ( PanelGroup directionhorizontal {/* 左侧 - 大纲面板 */} Panel defaultSize{20} minSize{10} ChapterOutlinePanel / /Panel PanelResizeHandle / {/* 这是可拖拽的分隔条 */} {/* 中间 - 编辑器面板 */} Panel defaultSize{60} TextEditor content{content} onChange{updateContent} / /Panel PanelResizeHandle / {/* 右侧 - AI助手面板 */} Panel defaultSize{20} minSize{15} AIAssistantPanel / /Panel /PanelGroup ); }这种实现方式给了作者极大的灵活性可以根据当前专注的任务比如梳理大纲时拉宽左侧专注写作时全屏编辑器自由调整空间分配。4. 开发进阶自定义Prompt与数据持久化当你熟悉了基本操作后肯定会不满足于默认的AI表现。Hermes Writer提供了强大的自定义能力。4.1 深入定制你的Agent Prompt项目的Phase 2计划中提到了“Prompt模板系统”在现有代码中这通常体现为在src/lib/types.ts或一个专门的prompts.ts文件中定义的一系列模板字符串。例如你觉得默认的Writer Agent写的对话不够生动你可以找到Writer的System Prompt进行修改// 假设在 src/lib/prompts.ts 中 export const WRITER_SYSTEM_PROMPT 你是一位专业的网络小说作家尤其擅长创作${genre}题材。请遵循以下准则进行创作 1. **角色一致性**严格遵循提供的角色档案。角色“${characterName}”的性格是${characterTraits}说话时应${speechStyle}。 2. **世界观沉浸**将“${worldSetting}”自然地融入描写不要生硬说明。 3. **情节推进**紧扣“${plotPoints}”这个情节要点进行展开。 4. **网文节奏**每300-500字需要有一个小亮点或悬念避免大段平淡叙述。 5. **输出要求**直接输出纯文本正文不要包含任何章节标题、提示语或元信息。 ;然后在调用Writer时用实际的变量作品类型genre、角色名characterName等替换掉模板中的占位符${...}形成最终的Prompt。你完全可以复制这个文件创建自己的custom-prompts.ts并在AI调用处引用从而实现对你专属“写作风格”的打磨。4.2 数据模型与关系设计持久化层是保证所有创作内容不丢失的关键。我们看一下Prisma Schema的核心部分 (prisma/schema.prisma)model Novel { id String id default(cuid()) title String genre String synopsis String? coverUrl String? createdAt DateTime default(now()) updatedAt DateTime updatedAt // 核心关系一部作品拥有多个章节、角色和世界观设定 chapters Chapter[] characters Character[] worldSettings WorldSetting[] agentTasks AgentTask[] // 记录所有AI操作历史 } model Chapter { id String id default(cuid()) novelId String novel Novel relation(fields: [novelId], references: [id], onDelete: Cascade) title String content String db.Text // 使用Text类型存储长内容 order Int // 章节序号 summary String? // AI生成的章节摘要用于快速回顾 wordCount Int default(0) createdAt DateTime default(now()) } model Character { id String id default(cuid()) novelId String novel Novel relation(fields: [novelId], references: [id], onDelete: Cascade) name String description String db.Text traits Json // 使用JSON字段存储复杂的性格特质、能力等 // 例如traits {personality: [坚韧, 乐观], skill: [剑术精通]} } model AgentTask { id String id default(cuid()) novelId String novel Novel relation(fields: [novelId], references: [id], onDelete: Cascade) agentType String // hermes, planner, writer... prompt String db.Text // 发送给AI的完整Prompt response String db.Text // AI的完整回复 metadata Json? // 额外的元数据如使用的模型、耗时等 createdAt DateTime default(now()) }这个设计清晰地反映了业务逻辑。onDelete: Cascade确保了删除作品时其下的所有章节、角色等数据会被自动清理避免了数据孤儿。Json类型的字段如traits,metadata提供了极大的灵活性可以存储非结构化的复杂数据非常适合AI生成的内容。5. 常见问题与排查技巧实录在实际部署和开发过程中你可能会遇到以下典型问题。这里记录了我踩过的坑和解决方案。5.1 AI生成相关问题问题1AI生成的内容偏离预期或质量不稳定。排查思路这几乎总是Prompt的问题。首先打开“Agent任务历史”视图找到那次生成任务仔细检查发送给AI的完整Prompt。看看系统指令是否清晰用户指令是否包含了所有必要上下文如前文摘要、角色设定。解决技巧提供更具体的示例在System Prompt中加入一两段你期望的写作风格的示例文本。使用“分步思考”指令对于复杂任务在User Prompt中要求AI先列出步骤再执行。例如“请先分析主角当前的情绪状态和动机然后基于此创作一段他与反派的对话。”调整温度参数在src/lib/ai.ts的createChatCompletion调用中尝试降低temperature如从0.7调到0.3会让输出更稳定、更可预测调高则会更有创造性但也更随机。切换模型不同模型有不同特长。GLM-4可能更均衡Kimi-2.5在长上下文和理解复杂指令上可能更强。在创作空间右上角切换试试。问题2生成长章节时中断或响应非常慢。排查检查网络并查看浏览器开发者工具中Network标签页的响应。如果是流式响应中途断开可能是触发了模型的最大输出Token限制。解决在AI调用处减少max_tokens参数或者将任务拆分。例如不要一次性生成5000字的完整章节而是先让Planner生成详细分场景再让Writer逐个场景生成。5.2 开发与部署问题问题3运行bun run db:push时出现Prisma错误。排查最常见的是数据库文件被占用或Schema有冲突。解决确保开发服务器(bun run dev)已停止。删除prisma/dev.db文件如果存在和node_modules/.prisma目录。重新运行bun install和bun run db:push。如果问题依旧检查prisma/schema.prisma文件是否有语法错误。问题4部署到Vercel后应用无法写入SQLite数据库。核心原因Vercel等Serverless平台是无状态的每次函数执行都可能在一个全新的容器中文件系统的写入在函数执行结束后不会保留。SQLite的本地文件模式在此环境下无效。标准解决方案切换为服务端数据库这是生产环境的必由之路。将DATABASE_URL环境变量改为一个远程数据库连接字符串如PostgreSQLVercel推荐使用其集成的Vercel Postgres或Neon。修改Prisma Schema将provider从sqlite改为postgresql并运行prisma generate和prisma db push来迁移Schema。使用Vercel Blob或S3存储文件如果你需要存储上传的封面图片等需要使用Vercel Blob、AWS S3或类似的对象存储服务而非本地public目录。问题5Next.js构建失败错误与模块或类型相关。排查仔细阅读构建错误日志。常见于依赖版本冲突或TypeScript类型未更新。解决运行bun run lint检查代码规范。删除node_modules和bun.lockb重新运行bun install。运行bun run db:generate确保Prisma客户端类型是最新的。检查next.config.js如果有的配置是否正确。这个项目为我们展示了一个非常清晰的路径如何将前沿的AI Agent思想与成熟的全栈开发技术结合解决一个垂直领域网文创作的实际痛点。从技术选型到架构设计再到具体的交互实现它都做出了良好的示范。你可以直接使用它来辅助创作更可以将其作为一个多智能体应用Multi-Agent Application的绝佳学习范本去理解Agent编排、上下文管理、Prompt工程这些核心概念是如何在真实代码中落地的。无论是想体验AI创作的作者还是想探索Agentic AI的开发者Hermes Writer都提供了一个扎实的起点。