当前位置: 首页 > news >正文

Goink v1.1.1 技术架构深度拆解:国产大模型如何驱动一个真正的 AI 长篇写作桌面应用

Goink v1.1.1 技术架构深度拆解:国产大模型如何驱动一个真正的 AI 长篇写作桌面应用

7 个国产大模型内置模板 + ONNX 本地语义搜索 + 自研 ReAct Agent 引擎 + 33 个 MCP 工具,<60MB 安装包开箱即用。本文从代码层面拆解 Goink 的核心架构设计。


写在前面:为什么通用 AI 聊天写不了长篇小说

如果你用 ChatGPT 或 DeepSeek 聊过天,你会觉得 AI 很聪明。但如果你试着让它帮你写一篇十万字的小说——

写到第五章,它忘了主角在第三章养的那只猫叫什么。

你手动翻了几百条聊天记录,把角色设定重新贴给它。第十章时,它又搞混了两个配角的师徒关系。你设的伏笔散落在对话的犄角旮旯里,别说 AI 记不住,你自己都快忘了。

核心矛盾:LLM 的单次上下文窗口再大(百万 token 已经很常见),也无法替代一个持久化的、结构化的、可自动维护的创作状态数据库。这是通用聊天产品的根本天花板——它们把一切都塞进对话流里,而长篇创作需要的是一套区别于对话流的独立状态管理。

Goink 是我为了解决这个问题写的。它不是一个套壳的 AI 聊天客户端,而是一个专门为长篇小说创作设计的桌面 AI 系统,核心技术目标就一个:让 AI 在写作过程中自动追踪、维护、查证所有创作状态,不让作者操这个心。

这篇文章会从技术视角拆解 Goink 的架构设计,重点放在如何将国产大模型的能力深度嵌入一个具体的创作场景,以及在这个过程中踩过的坑和做出的关键决策。


一、整体架构:三层分离,各司其职

┌─────────────────────────────────────────┐ │ React 19 前端 │ │ 对话 UI + Monaco 编辑器 + G6 图可视化 │ │ + 六套可视化面板 + Diff 审批 │ ├─────────────────────────────────────────┤ │ Wails v2 绑定层 (app/) │ │ Go 方法 → 前端 API │ ├─────────────────────────────────────────┤ │ Go 后端 (internal/) │ │ ReAct Agent 引擎 + 33 MCP 工具 │ │ + 六维记忆数据库 + Git 版本管理 │ │ + ONNX Runtime 本地推理 │ ├─────────────────────────────────────────┤ │ SQLite + sqlite-vec 向量索引 │ │ + Git 文件存储 │ └─────────────────────────────────────────┘

选择 Wails 而不是 Electron 的原因很明确:安装包体积。Electron 的 Chromium 运行时动辄上百 MB,而 Wails 利用系统自带的 WebView,Goink 的跨平台安装包不到 60MB。

Go 做后端也带来了一个关键优势:编译为原生二进制,无运行时依赖。用户不需要装 Python、Node.js、数据库或任何环境,一个 exe/dmg/AppImage 打开即用。


二、Agent 引擎设计:ReAct 循环 + 工具自主决策

Goink 的 Agent 引擎没有使用 LangChain 或任何第三方框架,而是在 Go 中自研了一个 ReAct(Reasoning + Acting)循环。

核心流程

用户输入 → LLM 流式推理 → 解析 tool_calls → 执行工具 ↑ ↓ └──────────── 工具结果追加回消息列表 ←────────────────┘ (循环直到 LLM 不再调用工具)

关键设计决策:

  1. 事件驱动的流式推送:Agent 的每一步状态变化(思考过程、内容生成、工具调用开始/执行中/完成/失败、Token 用量)都通过 WailsEventsEmit实时推送到前端。用户看到的不只是"AI 在打字",而是能看到 AI 正在查什么资料、调用什么工具、思考什么——整个过程对用户透明。

  2. 安全机制:死循环检测(最近 4 轮工具调用 ≤2 种模式且全为只读时触发)、连续 3 次系统异常自动禁用工具、最大 50 轮工具调用限制——这些是实战中遇到频繁工具调用死循环后逐步加入的。

  3. 子 Agent 系统:主 Agent 可以启动子 Agent 处理特定任务(审稿 Agent 四维检查、记忆 Agent 多维度检索),子 Agent 运行在独立上下文环境中,不污染主对话。子 Agent 和主 Agent 复用同一个Run()方法,差异仅在于 RunOptions 中的 AgentType、ParentTurnID 和 AllowedTools。

主流程代码片段(简化)

func(a*Agent)Run(ctx context.Context,msgs[]Message,opts RunOptions)error{forturn:=0;turn<maxTurns;turn++{// 1. 注入系统提示词 + 小说状态快照 + Skill 常驻注入systemMsgs:=a.buildSystemMessages(opts)// 2. 调用 LLM 流式接口stream,err:=a.client.CreateChatCompletionStream(ctx,allMsgs)// 3. 解析响应:文本内容 vs 工具调用content,toolCalls:=a.processStream(stream)// 4. 无工具调用 → 本轮结束iflen(toolCalls)==0{break}// 5. 并行执行工具调用results:=a.executeTools(ctx,toolCalls)// 6. 安全检测(死循环、异常率)ifa.detectLoop(recentTurns){break}// 7. 结果追加回消息列表,继续循环allMsgs=append(allMsgs,results...)}}

三、国产大模型全链路落地:7 个 Provider 内置模板

这是 Goink 在模型集成方面最有价值的部分——如何在一个桌面应用中实现对多个国产大模型的统一接入和智能调度

当前内置的 7 个 Provider

Provider代表模型上下文窗口输出上限ThinkingVision
DeepSeekdeepseek-v4-pro1M384K✅ high/max-
豆包(火山引擎)doubao-seed-2-1-pro256K256K
Qwen(通义千问)qwen3.7-max1M64K
GLM(智谱)glm-5.1200K128K-
MiniMaxMiniMax-M31M128K
MiMo(小米)mimo-v2.5-pro1M128K-
Kimi(月之暗面)kimi-k2.7-code262K128K

统一抽象层设计

所有 Provider 通过 OpenAI 兼容 API 接入,但每个有自己的"毛刺"需要处理:

  • Qwen(阿里云 DashScope):需要自定义请求构造,阿里云的 API 格式有细微差异(BuildRequest钩子)
  • MiniMax:同样的 OpenAI 兼容但请求体格式不完全一致(BuildRequest钩子)
  • MiMo(小米):需要自定义请求头(BuildHeaders钩子)
  • 豆包(火山引擎):标准 OpenAI 格式,但 endpoint 路径不同

解决方案是在llm/client.go中设计了 Provider 级别的拦截器链:

typeProviderstruct{IDstringNamestringChatURLstringModels[]Model BuildRequestfunc(*http.Request,*ChatRequest)// 可选钩子BuildHeadersfunc(*http.Request)// 可选钩子}

用户在前端界面选择 Provider → 填入 API Key → 自动发现可用模型列表 → 一键切换。底层 Provider 的差异对用户完全透明。

为什么这是有意义的

很多"AI 写作工具"其实只是内置了一个模型(通常是 GPT)的 API Key,你换不了模型。Goink 的设计理念是:模型是基础设施,用户应该有选择权。不同模型在中文文学创作上的表现确实有差异——有的擅长对话描写,有的擅长情节推进,有的便宜适合打草稿。7 个 Provider 内置模板 + 自定义 Provider 支持,让用户可以根据自己的预算和效果偏好灵活组合。

更重要的是,这 7 个 Provider全部是国产品牌。在当前的 AI 应用格局下,这意味着用户不需要任何海外支付方式就能用好用的 AI 写作工具。


四、本地语义搜索:将国产 NLP 模型打包进桌面应用

Goink 的 RAG 系统是另一个展示"模型落地"的典型案例。

技术选型

  • 嵌入模型:BAAI 的bge-small-zh-v1.5,int8 量化版,512 维向量
  • 推理引擎:ONNX Runtime,通过 Go 绑定github.com/yalue/onnxruntime_go调用
  • 向量存储:sqlite-vec,创建虚拟表vec_novel_{id},cosine 距离度量
  • 分块策略:BERT WordPiece Tokenizer,420 tokens/块,50 token 重叠,段落边界优先切分
  • 重排序:MMR(最大边际相关性),λ=0.7,兼顾相关性和多样性

全链路流程图

源文本 → WordPiece 分词 → 段落/句子边界切块 → ONNX 推理 → CLS Pooling + L2 归一化 → sqlite-vec 写入 → 向量索引 ↓ 用户查询 → BGE 指令前缀 → ONNX 推理 → 向量搜索 → MMR 重排 → 结果

BGE 指令前缀的设计很关键:查询时加前缀,文档不加。这是 BGE 模型的设计约定——"为这个句子生成表示以用于检索相关文章:"只在查询侧追加,告诉模型"这是一个问题,请用检索模式编码"。

全局单例 + 异步加载

ONNX Runtime 的初始化在桌面应用中有个特殊问题:加载模型和运行时库可能需要几秒钟,如果同步加载会阻塞 GUI 渲染。

Goink 的解决方案:

var(embedder*OnnxEmbedder embedderOnce sync.Once embedderCh=make(chanstruct{}))funcInitEmbedder(){embedderOnce.Do(func(){gofunc(){embedder=loadEmbedder()close(embedderCh)// 初始化完成,广播信号}()})}funcGetEmbedder()*OnnxEmbedder{<-embedderCh// 阻塞等待初始化完成returnembedder}

GUI 先渲染,ONNX 在后台异步加载。等加载完成后,界面的搜索功能自动变为可用。用户感知不到加载过程。

离线运行的价值

整个语义搜索链路完全在用户本机完成——不需要调用任何 embedding API,不需要联网。这对目标用户(写作者)意味着:

  1. 隐私:你的小说内容永远不会离开你的电脑去做向量化
  2. 零成本:不按 token 计费,搜索多少次都行
  3. 离线可用:没有网络照样搜

BGE 模型约 100MB(int8 量化后),推理时 CPU 即可,不需要 GPU。在现代 CPU 上,单次查询的 embedding 耗时在毫秒级。


五、为什么需要结构化记忆,而不只是更大的上下文

百万 token 上下文窗口已经很普及了。但你试试把一部几十万字的小说的全部章节、角色设定、伏笔列表、地点描述、读者认知状态全部塞进 system prompt 里——LLM 对长文本的中间部分的注意力天然衰减,而且每次调用都要为这几十万 token 付费。

Goink 的解决方案是结构化记忆 + 按需检索,而不是全量注入:

记忆维度存储结构检索策略
角色档案 + 有向关系图AI 主动查数据库
伏笔目标章节 + 重要度 + 状态按回收章节排序
故事弧线节点链 + 进度状态按关联章节查询
地点包含树 + 连通图按名称/层级查询
读者认知已知/悬念/误解按状态过滤
创作偏好全局 + 单书两层语义搜索匹配

AI 写作时不是"一次性读完所有资料",而是像人类作者一样,需要什么查什么——需要确认角色关系时调search_characters,需要找之前埋的伏笔时调list_timeline,需要确认某段前文时调search_story_memory(语义搜索)。

这 33 个 MCP 工具就是 AI 的"手脚",让它能自主地在创作过程中维护状态,而不是靠用户手动贴设定。

写完自动维护:三层保障

写完整章内容后,AI 并不只是把文本写入文件就完事。系统分三层确保状态被正确更新:

  1. System Prompt 指令:系统提示词中明确要求 AI 在写完后检查角色变化、伏笔回收、弧线推进
  2. 动态状态注入:每轮对话开头,将当前小说状态快照(角色列表摘要、待回收伏笔、弧线进度)注入系统消息
  3. 审稿子 Agent:独立的 review Agent,用四维标准(角色一致性、伏笔回收、弧线推进、读者认知)扫描新章,发现问题后输出修正建议

三层设置的原因是:单靠 system prompt 不够可靠(LLM 可能忽略),单靠状态注入不够全面(只有摘要信息),单靠子 Agent 太慢。三层叠加后,状态遗漏率大幅降低。


六、Git 版本管理 + Diff 审批:让 AI 的修改可控

这是另一个从实战中长出来的需求。

早期版本中,AI 可以直接修改章节文件。后果是:有时候改对了,有时候偷偷改坏了,你不知道。于是加入了Diff 审批机制

  1. AI 生成修改时,不是直接写入,而是生成 search/replace 操作
  2. 后端对目标文件执行替换,生成 Git Diff
  3. 前端展示 Diff 视图(逐行对比),用户点"批准"才实际 commit
  4. 用户点"拒绝"则 revert,文件恢复原样

全部文件操作都被 Git 追踪。每次对话结束自动 commit,随时可以git log查看历史或git revert回退到任意版本。

每次对话自动 commit → 随时回退,写作者的"无限撤销"。


七、实际运行数据

项目自 2026 年 6 月初开源,到目前(7 月中旬)在 GitHub 上获得了99 Stars17 Forks。最新版本 v1.1.1 的跨平台安装包累计下载超过 300 次(Windows 为主力平台,占 80%+)。

技术栈:Go 1.25 + Wails v2.12 + React 19 + TypeScript 6 + Tailwind CSS 4 + SQLite + ONNX Runtime 1.26

代码规模:约 40,000 行 Go + 22,000 行 TypeScript/TSX


八、总结:从模型到产品的最后一公里

Goink 做的事情本质上不复杂——把国产大模型的能力封装进一个桌面应用,让写作者不用关心 prompt engineering、不用手动维护设定、不用在几十万字的聊天记录里翻找信息。

但从技术实现角度看,把这件事做好确实需要解决一系列工程问题:

  • Agent 循环的可靠性:防止死循环、处理异常、流式推送状态
  • 多 Provider 的兼容性:每个国产模型的 API 都有自己的 quirks
  • 本地推理的集成:ONNX Runtime 的 Go 绑定、异步加载、分词器实现
  • 结构化记忆的持久化:六维数据的 schema 设计、append-only 历史追踪
  • 写入安全的保障:Diff 审批、Git 回退、沙箱隔离

如果你也在做"大模型 + 桌面应用"方向的产品,或者对 Agent 架构设计感兴趣,欢迎来 GitHub 交流:github.com/sigpanic/goink。

项目使用 AGPL v3 开源,Skill 方法论仓库 goink-skills 也欢迎社区贡献写作方法论。


本文基于 Goink v1.1.1 编写。如果你也在做 AI 桌面应用或对 Agent 架构感兴趣,欢迎在评论区交流,也欢迎来 GitHub 点个 Star。

http://www.cnnetsun.cn/news/3538862.html

相关文章:

  • 数字隐私保护的终极解决方案:如何用ExifCleaner彻底清除600+文件格式的隐藏元数据
  • 28. 量子计算体系 镱离子阱量子比特:多普勒冷却至西绪福斯冷却极限突破
  • 2026 主流淘客 APP 功能对比:导购返利、领优惠券模块技术差异
  • OrcaPlayground 环境搭建与踩坑实录:从零跑通四足机器人 RL 训练
  • C语言机器人编程:高阶机器人开发的核心基础
  • 角色与虚拟人创作终极指南:Awesome-AIGC-3D人物生成技术全解析
  • 理解distilgpt2架构:GPT-2精简版的6层Transformer模型深度解析
  • Ptex错误处理与调试:常见问题解决方案大全
  • 嵌入式GPMC接口配置:时序计算、WAIT引脚与高级功能实战指南
  • 审计全量数据怎么查异常?统计离群、关联规则与图异常三种方法的工程对比
  • TMS320F28002x内存控制器与DCSM安全模块深度解析与工程实践
  • 从SQL到可视化图表:drawDB数据库设计入门指南
  • 深入理解pngjs的图像解析原理:从像素数据到完整PNG文件
  • MCSManager应用市场实战:从零开始部署600+游戏服务器的完整指南
  • EVE-NG 懒人版7.0发布
  • 绿联电池保护电路专利解析:提升过流保护精度与可靠性
  • GPT-3-Encoder快速入门:5分钟学会在Node.js中使用BPE编码器
  • Claude AI深度整合Office三件套提升办公效率
  • Socket.IO Redis Emitter:如何实现多服务器实时通信的终极指南
  • 招聘数据采集与人才画像——多平台JD抓取、技能词频分析与薪资趋势预测实战
  • 深入 RocketMQ 内核:事务消息——分布式事务的终极解法(四)
  • 3个理由告诉你为什么VSCode Python扩展是Python开发者的必备神器
  • 2026生鲜零售小程序十大方案测评:库存、配送、自提与会员怎么选?含零代码SAAS、AI编程、源码定制
  • 今天不解决风格漂移,明天就重写全部AI内容——紧急启动AI风格一致性防火墙的5个信号
  • 【AI写作避重黄金法则】:20年技术专家亲授7大原创性强化技巧,查重率直降92%
  • 如何永久保存微信聊天记忆:从数据提取到年度报告完整教程
  • uniapp.4
  • 终极企业级AI可视化编辑器:Onlook完整实战指南
  • WPS AI排版避坑清单:这8个“智能推荐”正在悄悄毁掉你的文档专业性(含字体嵌入漏洞、段前间距陷阱、目录生成断链详解)
  • MVVM Helpers分组功能全解析:Grouping类实现优雅数据展示