【文字三国志:第一篇】天命重构,大语言模型(LLM)动态生成文言风格的叙事文本的文字游戏

前述,前言,预览效果

最后一篇放出程序和源码,敬请期待。

一、项目定位与技术目标

1.1 项目定位

这是一款基于 Web 的回合制策略/叙事游戏,面向中文玩家群体。游戏设定在三国的虚构历史分支中,玩家需要在政治、军事、外交、占星等多个维度进行决策,每个选择都将影响世界走向。

核心体验 :系统通过大语言模型(LLM)动态生成文言风格的叙事文本,并在关键时刻给出"蝴蝶效应"提示,让玩家感受到决策的深远影响。

大模型如果配置失败则返回错误信息,如下图所示:

1.2 技术目标

为了保证项目的长期可维护性和团队协作效率,我确立了以下技术原则:

目标 实现方式 收益
类型安全 TS + Prisma 编译时发现错误,IDE 智能提示
高可维护性 三层架构分离 修改 UI 不影响逻辑,更换数据库无痛
可观测性 日志 + SSE + Cron 问题可追溯,状态实时可见
可扩展性 插件化设计 新增功能不破坏现有代码

二、核心子系统详解

2.1 子系统全景图

#mermaid-svg-5074H9RkUtJY0WFx{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5074H9RkUtJY0WFx .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5074H9RkUtJY0WFx .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5074H9RkUtJY0WFx .error-icon{fill:#552222;}#mermaid-svg-5074H9RkUtJY0WFx .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5074H9RkUtJY0WFx .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5074H9RkUtJY0WFx .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5074H9RkUtJY0WFx .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5074H9RkUtJY0WFx .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5074H9RkUtJY0WFx .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5074H9RkUtJY0WFx .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5074H9RkUtJY0WFx .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5074H9RkUtJY0WFx .marker.cross{stroke:#333333;}#mermaid-svg-5074H9RkUtJY0WFx svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5074H9RkUtJY0WFx p{margin:0;}#mermaid-svg-5074H9RkUtJY0WFx .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-5074H9RkUtJY0WFx .cluster-label text{fill:#333;}#mermaid-svg-5074H9RkUtJY0WFx .cluster-label span{color:#333;}#mermaid-svg-5074H9RkUtJY0WFx .cluster-label span p{background-color:transparent;}#mermaid-svg-5074H9RkUtJY0WFx .label text,#mermaid-svg-5074H9RkUtJY0WFx span{fill:#333;color:#333;}#mermaid-svg-5074H9RkUtJY0WFx .node rect,#mermaid-svg-5074H9RkUtJY0WFx .node circle,#mermaid-svg-5074H9RkUtJY0WFx .node ellipse,#mermaid-svg-5074H9RkUtJY0WFx .node polygon,#mermaid-svg-5074H9RkUtJY0WFx .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5074H9RkUtJY0WFx .rough-node .label text,#mermaid-svg-5074H9RkUtJY0WFx .node .label text,#mermaid-svg-5074H9RkUtJY0WFx .image-shape .label,#mermaid-svg-5074H9RkUtJY0WFx .icon-shape .label{text-anchor:middle;}#mermaid-svg-5074H9RkUtJY0WFx .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5074H9RkUtJY0WFx .rough-node .label,#mermaid-svg-5074H9RkUtJY0WFx .node .label,#mermaid-svg-5074H9RkUtJY0WFx .image-shape .label,#mermaid-svg-5074H9RkUtJY0WFx .icon-shape .label{text-align:center;}#mermaid-svg-5074H9RkUtJY0WFx .node.clickable{cursor:pointer;}#mermaid-svg-5074H9RkUtJY0WFx .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5074H9RkUtJY0WFx .arrowheadPath{fill:#333333;}#mermaid-svg-5074H9RkUtJY0WFx .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5074H9RkUtJY0WFx .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5074H9RkUtJY0WFx .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5074H9RkUtJY0WFx .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5074H9RkUtJY0WFx .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5074H9RkUtJY0WFx .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5074H9RkUtJY0WFx .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5074H9RkUtJY0WFx .cluster text{fill:#333;}#mermaid-svg-5074H9RkUtJY0WFx .cluster span{color:#333;}#mermaid-svg-5074H9RkUtJY0WFx div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5074H9RkUtJY0WFx .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5074H9RkUtJY0WFx rect.text{fill:none;stroke-width:0;}#mermaid-svg-5074H9RkUtJY0WFx .icon-shape,#mermaid-svg-5074H9RkUtJY0WFx .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5074H9RkUtJY0WFx .icon-shape p,#mermaid-svg-5074H9RkUtJY0WFx .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5074H9RkUtJY0WFx .icon-shape .label rect,#mermaid-svg-5074H9RkUtJY0WFx .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5074H9RkUtJY0WFx .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5074H9RkUtJY0WFx .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5074H9RkUtJY0WFx :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 外部服务
数据层
服务层
后端层
前端层
用户操作
调用
读写
推送
触发系统事件
React UI组件
Zustand Store
useGameNotifications
API Routes
Narrative Engine
Cron调度器
Combat System
Diplomacy System
Astrology System
Policy System
Achievement System
Prisma ORM
SQLite/PostgreSQL
ZAI LLM
SSE推送

2.2 各子系统职责

🎮 Narrative Engine(叙事引擎)

路径src/lib/game/engine.ts

这是游戏的心脏。它负责:

  • 构造上下文:收集当前游戏状态(年份、季节、玩家资源、角色属性、历史事件)
  • 调用 LLM:将上下文发送给 ZAI 大模型,请求生成叙事和世界变化
  • 解析结果:将 LLM 返回的 JSON 转换为可执行的世界变更指令
  • 记录日志:将每次回合的关键事件写入日志表

#mermaid-svg-P4ZtrN2iBTlorx23{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-P4ZtrN2iBTlorx23 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-P4ZtrN2iBTlorx23 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-P4ZtrN2iBTlorx23 .error-icon{fill:#552222;}#mermaid-svg-P4ZtrN2iBTlorx23 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-P4ZtrN2iBTlorx23 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-P4ZtrN2iBTlorx23 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-P4ZtrN2iBTlorx23 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-P4ZtrN2iBTlorx23 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-P4ZtrN2iBTlorx23 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-P4ZtrN2iBTlorx23 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-P4ZtrN2iBTlorx23 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-P4ZtrN2iBTlorx23 .marker.cross{stroke:#333333;}#mermaid-svg-P4ZtrN2iBTlorx23 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-P4ZtrN2iBTlorx23 p{margin:0;}#mermaid-svg-P4ZtrN2iBTlorx23 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-P4ZtrN2iBTlorx23 .cluster-label text{fill:#333;}#mermaid-svg-P4ZtrN2iBTlorx23 .cluster-label span{color:#333;}#mermaid-svg-P4ZtrN2iBTlorx23 .cluster-label span p{background-color:transparent;}#mermaid-svg-P4ZtrN2iBTlorx23 .label text,#mermaid-svg-P4ZtrN2iBTlorx23 span{fill:#333;color:#333;}#mermaid-svg-P4ZtrN2iBTlorx23 .node rect,#mermaid-svg-P4ZtrN2iBTlorx23 .node circle,#mermaid-svg-P4ZtrN2iBTlorx23 .node ellipse,#mermaid-svg-P4ZtrN2iBTlorx23 .node polygon,#mermaid-svg-P4ZtrN2iBTlorx23 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-P4ZtrN2iBTlorx23 .rough-node .label text,#mermaid-svg-P4ZtrN2iBTlorx23 .node .label text,#mermaid-svg-P4ZtrN2iBTlorx23 .image-shape .label,#mermaid-svg-P4ZtrN2iBTlorx23 .icon-shape .label{text-anchor:middle;}#mermaid-svg-P4ZtrN2iBTlorx23 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-P4ZtrN2iBTlorx23 .rough-node .label,#mermaid-svg-P4ZtrN2iBTlorx23 .node .label,#mermaid-svg-P4ZtrN2iBTlorx23 .image-shape .label,#mermaid-svg-P4ZtrN2iBTlorx23 .icon-shape .label{text-align:center;}#mermaid-svg-P4ZtrN2iBTlorx23 .node.clickable{cursor:pointer;}#mermaid-svg-P4ZtrN2iBTlorx23 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-P4ZtrN2iBTlorx23 .arrowheadPath{fill:#333333;}#mermaid-svg-P4ZtrN2iBTlorx23 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-P4ZtrN2iBTlorx23 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-P4ZtrN2iBTlorx23 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-P4ZtrN2iBTlorx23 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-P4ZtrN2iBTlorx23 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-P4ZtrN2iBTlorx23 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-P4ZtrN2iBTlorx23 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-P4ZtrN2iBTlorx23 .cluster text{fill:#333;}#mermaid-svg-P4ZtrN2iBTlorx23 .cluster span{color:#333;}#mermaid-svg-P4ZtrN2iBTlorx23 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-P4ZtrN2iBTlorx23 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-P4ZtrN2iBTlorx23 rect.text{fill:none;stroke-width:0;}#mermaid-svg-P4ZtrN2iBTlorx23 .icon-shape,#mermaid-svg-P4ZtrN2iBTlorx23 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-P4ZtrN2iBTlorx23 .icon-shape p,#mermaid-svg-P4ZtrN2iBTlorx23 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-P4ZtrN2iBTlorx23 .icon-shape .label rect,#mermaid-svg-P4ZtrN2iBTlorx23 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-P4ZtrN2iBTlorx23 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-P4ZtrN2iBTlorx23 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-P4ZtrN2iBTlorx23 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 叙事引擎工作流
成功
失败
收集游戏状态
构造Prompt
调用LLM
解析JSON
应用世界变更
降级处理
记录回合日志
返回结果给前端

⚔️ Combat System(战斗系统)

位于同一文件的 resolveCombat 函数。输入敌我双方数据、地形、天气,输出战斗叙事和伤亡统计,并写入 CombatLog 表。

🤝 Diplomacy System(外交系统)

processDiplomacy 函数处理同盟、停战、贸易等提案,返回包含关系变化量的 DiplomacyResult

🔮 Astrology(占星系统)

根据游戏内的季节和星象配置,消耗玩家资源(如祭品),生成带有预言性质的随机事件。

📜 Policy System(政策系统)

玩家激活不同的政策卡,每张卡影响资源产出或角色属性,效果持久化到 Policy 表。

🏆 Achievement System(成就系统)

路径src/lib/game/achievements.ts

持续监测世界状态的变化,当满足特定条件时(如"累计斩杀 100 敌将"),解锁成就并推送到前端。

📦 Store / State Layer(状态管理层)

路径src/lib/game/store.ts

基于 Zustand + Immer 的全局单例 Store。它承担以下职责:

  • 持有前端所有游戏状态
  • 提供 dispatchAction 方法分发用户操作
  • 提供 fetchLatest 方法从后端同步最新数据
  • 作为 UI 层与后端之间的桥梁
🔔 Real‑time Notification(实时通知)

路径src/app/api/game/events/route.ts + use-game-notifications Hook

使用 Server-Sent Events (SSE) 技术,将后端产生的回合结果、成就解锁等事件实时推送给前端,无需用户刷新页面。

⏰ Cron / Scheduler(定时调度器)

由网关的 Cron 作业执行,处理:

  • 季节更替事件
  • 每日/每周任务重置
  • 自动存档

三、技术栈全景

3.1 技术分层图示

#mermaid-svg-5y7MctpTKgsF6hJg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5y7MctpTKgsF6hJg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5y7MctpTKgsF6hJg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5y7MctpTKgsF6hJg .error-icon{fill:#552222;}#mermaid-svg-5y7MctpTKgsF6hJg .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5y7MctpTKgsF6hJg .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5y7MctpTKgsF6hJg .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5y7MctpTKgsF6hJg .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5y7MctpTKgsF6hJg .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5y7MctpTKgsF6hJg .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5y7MctpTKgsF6hJg .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5y7MctpTKgsF6hJg .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5y7MctpTKgsF6hJg .marker.cross{stroke:#333333;}#mermaid-svg-5y7MctpTKgsF6hJg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5y7MctpTKgsF6hJg p{margin:0;}#mermaid-svg-5y7MctpTKgsF6hJg .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-5y7MctpTKgsF6hJg .cluster-label text{fill:#333;}#mermaid-svg-5y7MctpTKgsF6hJg .cluster-label span{color:#333;}#mermaid-svg-5y7MctpTKgsF6hJg .cluster-label span p{background-color:transparent;}#mermaid-svg-5y7MctpTKgsF6hJg .label text,#mermaid-svg-5y7MctpTKgsF6hJg span{fill:#333;color:#333;}#mermaid-svg-5y7MctpTKgsF6hJg .node rect,#mermaid-svg-5y7MctpTKgsF6hJg .node circle,#mermaid-svg-5y7MctpTKgsF6hJg .node ellipse,#mermaid-svg-5y7MctpTKgsF6hJg .node polygon,#mermaid-svg-5y7MctpTKgsF6hJg .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5y7MctpTKgsF6hJg .rough-node .label text,#mermaid-svg-5y7MctpTKgsF6hJg .node .label text,#mermaid-svg-5y7MctpTKgsF6hJg .image-shape .label,#mermaid-svg-5y7MctpTKgsF6hJg .icon-shape .label{text-anchor:middle;}#mermaid-svg-5y7MctpTKgsF6hJg .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5y7MctpTKgsF6hJg .rough-node .label,#mermaid-svg-5y7MctpTKgsF6hJg .node .label,#mermaid-svg-5y7MctpTKgsF6hJg .image-shape .label,#mermaid-svg-5y7MctpTKgsF6hJg .icon-shape .label{text-align:center;}#mermaid-svg-5y7MctpTKgsF6hJg .node.clickable{cursor:pointer;}#mermaid-svg-5y7MctpTKgsF6hJg .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5y7MctpTKgsF6hJg .arrowheadPath{fill:#333333;}#mermaid-svg-5y7MctpTKgsF6hJg .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5y7MctpTKgsF6hJg .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5y7MctpTKgsF6hJg .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5y7MctpTKgsF6hJg .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5y7MctpTKgsF6hJg .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5y7MctpTKgsF6hJg .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5y7MctpTKgsF6hJg .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5y7MctpTKgsF6hJg .cluster text{fill:#333;}#mermaid-svg-5y7MctpTKgsF6hJg .cluster span{color:#333;}#mermaid-svg-5y7MctpTKgsF6hJg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5y7MctpTKgsF6hJg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5y7MctpTKgsF6hJg rect.text{fill:none;stroke-width:0;}#mermaid-svg-5y7MctpTKgsF6hJg .icon-shape,#mermaid-svg-5y7MctpTKgsF6hJg .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5y7MctpTKgsF6hJg .icon-shape p,#mermaid-svg-5y7MctpTKgsF6hJg .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5y7MctpTKgsF6hJg .icon-shape .label rect,#mermaid-svg-5y7MctpTKgsF6hJg .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5y7MctpTKgsF6hJg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5y7MctpTKgsF6hJg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5y7MctpTKgsF6hJg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 安全层
JWT鉴权
CORS限制
Rate-limit
环境变量隔离
可观测性
Prometheus
Grafana
结构化日志
基础设施
Docker多阶段构建
Docker-Compose
Caddy 反向代理
GitHub Actions CI
数据层
SQLite / 开发
PostgreSQL / 生产
后端技术栈
Next.js API Routes
Prisma ORM
Node.js 22 / Bun
ZAI SDK
前端技术栈
Next.js 13 App Router
React 18
TypeScript
TailwindCSS + shadcn/ui
Zustand + SWR
framer-motion

3.2 关键选型说明

类别 技术 选型理由
框架 Next.js 13 App Router 支持服务端组件,API Routes 一站式后端
状态管理 Zustand 轻量级,比 Redux 简单,与 Immer 配合 immutable 更新
数据获取 SWR 内置缓存、重试、自动重新验证
ORM Prisma 类型安全的数据库操作,自动生成 TS 类型
数据库 SQLite/PostgreSQL 开发期 SQLite 零配置,生产期 PG 高并发
LLM SDK ZAI 统一接口,支持多模型切换
反向代理 Caddy 2 自动 HTTPS,配置简单,原生支持 rate-limit
容器化 Docker + Compose 开发生产环境一致,一键启动

四、业务流程详解

4.1 完整回合循环

SSE推送 数据库 LLM Narrative Engine API Route Zustand Store 前端UI 用户 SSE推送 数据库 LLM Narrative Engine API Route Zustand Store 前端UI 用户 #mermaid-svg-EblmREIQ4BAsL8Rk{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-EblmREIQ4BAsL8Rk .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-EblmREIQ4BAsL8Rk .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-EblmREIQ4BAsL8Rk .error-icon{fill:#552222;}#mermaid-svg-EblmREIQ4BAsL8Rk .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-EblmREIQ4BAsL8Rk .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-EblmREIQ4BAsL8Rk .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-EblmREIQ4BAsL8Rk .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-EblmREIQ4BAsL8Rk .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-EblmREIQ4BAsL8Rk .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-EblmREIQ4BAsL8Rk .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-EblmREIQ4BAsL8Rk .marker{fill:#333333;stroke:#333333;}#mermaid-svg-EblmREIQ4BAsL8Rk .marker.cross{stroke:#333333;}#mermaid-svg-EblmREIQ4BAsL8Rk svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-EblmREIQ4BAsL8Rk p{margin:0;}#mermaid-svg-EblmREIQ4BAsL8Rk .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-EblmREIQ4BAsL8Rk text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-EblmREIQ4BAsL8Rk .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-EblmREIQ4BAsL8Rk .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-EblmREIQ4BAsL8Rk .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-EblmREIQ4BAsL8Rk .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-EblmREIQ4BAsL8Rk #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-EblmREIQ4BAsL8Rk .sequenceNumber{fill:white;}#mermaid-svg-EblmREIQ4BAsL8Rk #sequencenumber{fill:#333;}#mermaid-svg-EblmREIQ4BAsL8Rk #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-EblmREIQ4BAsL8Rk .messageText{fill:#333;stroke:none;}#mermaid-svg-EblmREIQ4BAsL8Rk .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-EblmREIQ4BAsL8Rk .labelText,#mermaid-svg-EblmREIQ4BAsL8Rk .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-EblmREIQ4BAsL8Rk .loopText,#mermaid-svg-EblmREIQ4BAsL8Rk .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-EblmREIQ4BAsL8Rk .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-EblmREIQ4BAsL8Rk .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-EblmREIQ4BAsL8Rk .noteText,#mermaid-svg-EblmREIQ4BAsL8Rk .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-EblmREIQ4BAsL8Rk .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-EblmREIQ4BAsL8Rk .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-EblmREIQ4BAsL8Rk .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-EblmREIQ4BAsL8Rk .actorPopupMenu{position:absolute;}#mermaid-svg-EblmREIQ4BAsL8Rk .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-EblmREIQ4BAsL8Rk .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-EblmREIQ4BAsL8Rk .actor-man circle,#mermaid-svg-EblmREIQ4BAsL8Rk line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-EblmREIQ4BAsL8Rk :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} alt有新成就 点击决策按钮dispatchAction(action)POST /api/game/action读取最新状态(GameSession/Character/Events)返回上下文数据processAction(上下文)buildContextMessage() 构造PromptcallLLM() 请求生成返回JSON(叙事+世界变更)解析JSON → worldChanges应用变更(属性/资源/事件)写入PlayerAction/CombatLog更新回合/季节/年份checkGameEnding() 检查结局checkAchievements() 检查成就写入Achievement推送achievementUnlocked推送turnResult实时接收通知更新Store状态触发重渲染显示新叙事和结果

4.2 步骤拆解

步骤 触发动作 后端处理 结果
1 用户登录 useAuth 请求 JWT 前端保存 token
2 启动新局 POST /api/game/startengine.startGame 创建 GameSession、角色、初始世界状态
3 用户决策 底部操作栏点击 → POST /api/game/action 进入回合处理
4 读取状态 获取最新 GameSession、角色、历史事件 构造 LLM 上下文
5 LLM 生成 buildContextMessagecallLLM 返回叙事 + worldChanges
6 应用变更 applyWorldChanges 写库 属性/资源/事件更新
7 更新回合 年份/季节推进 → 写库 回合数 +1
8 成就检测 checkAchievements 必要时解锁并推送
9 实时推送 SSE 发送 turnResult 前端 Store 更新,UI 重绘

4.3 后台定时任务流程

#mermaid-svg-cWGf8HaFouI5H8tv{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-cWGf8HaFouI5H8tv .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-cWGf8HaFouI5H8tv .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-cWGf8HaFouI5H8tv .error-icon{fill:#552222;}#mermaid-svg-cWGf8HaFouI5H8tv .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-cWGf8HaFouI5H8tv .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-cWGf8HaFouI5H8tv .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-cWGf8HaFouI5H8tv .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-cWGf8HaFouI5H8tv .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-cWGf8HaFouI5H8tv .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-cWGf8HaFouI5H8tv .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-cWGf8HaFouI5H8tv .marker{fill:#333333;stroke:#333333;}#mermaid-svg-cWGf8HaFouI5H8tv .marker.cross{stroke:#333333;}#mermaid-svg-cWGf8HaFouI5H8tv svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-cWGf8HaFouI5H8tv p{margin:0;}#mermaid-svg-cWGf8HaFouI5H8tv .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-cWGf8HaFouI5H8tv .cluster-label text{fill:#333;}#mermaid-svg-cWGf8HaFouI5H8tv .cluster-label span{color:#333;}#mermaid-svg-cWGf8HaFouI5H8tv .cluster-label span p{background-color:transparent;}#mermaid-svg-cWGf8HaFouI5H8tv .label text,#mermaid-svg-cWGf8HaFouI5H8tv span{fill:#333;color:#333;}#mermaid-svg-cWGf8HaFouI5H8tv .node rect,#mermaid-svg-cWGf8HaFouI5H8tv .node circle,#mermaid-svg-cWGf8HaFouI5H8tv .node ellipse,#mermaid-svg-cWGf8HaFouI5H8tv .node polygon,#mermaid-svg-cWGf8HaFouI5H8tv .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-cWGf8HaFouI5H8tv .rough-node .label text,#mermaid-svg-cWGf8HaFouI5H8tv .node .label text,#mermaid-svg-cWGf8HaFouI5H8tv .image-shape .label,#mermaid-svg-cWGf8HaFouI5H8tv .icon-shape .label{text-anchor:middle;}#mermaid-svg-cWGf8HaFouI5H8tv .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-cWGf8HaFouI5H8tv .rough-node .label,#mermaid-svg-cWGf8HaFouI5H8tv .node .label,#mermaid-svg-cWGf8HaFouI5H8tv .image-shape .label,#mermaid-svg-cWGf8HaFouI5H8tv .icon-shape .label{text-align:center;}#mermaid-svg-cWGf8HaFouI5H8tv .node.clickable{cursor:pointer;}#mermaid-svg-cWGf8HaFouI5H8tv .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-cWGf8HaFouI5H8tv .arrowheadPath{fill:#333333;}#mermaid-svg-cWGf8HaFouI5H8tv .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-cWGf8HaFouI5H8tv .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-cWGf8HaFouI5H8tv .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-cWGf8HaFouI5H8tv .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-cWGf8HaFouI5H8tv .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-cWGf8HaFouI5H8tv .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-cWGf8HaFouI5H8tv .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-cWGf8HaFouI5H8tv .cluster text{fill:#333;}#mermaid-svg-cWGf8HaFouI5H8tv .cluster span{color:#333;}#mermaid-svg-cWGf8HaFouI5H8tv div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-cWGf8HaFouI5H8tv .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-cWGf8HaFouI5H8tv rect.text{fill:none;stroke-width:0;}#mermaid-svg-cWGf8HaFouI5H8tv .icon-shape,#mermaid-svg-cWGf8HaFouI5H8tv .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-cWGf8HaFouI5H8tv .icon-shape p,#mermaid-svg-cWGf8HaFouI5H8tv .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-cWGf8HaFouI5H8tv .icon-shape .label rect,#mermaid-svg-cWGf8HaFouI5H8tv .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-cWGf8HaFouI5H8tv .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-cWGf8HaFouI5H8tv .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-cWGf8HaFouI5H8tv :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 效果
处理逻辑
Cron调度器
季节事件
每日重置
自动存档
触发系统事件
与LLM交互
写入存档文件
生成季节叙事
重置任务计数
保障数据安全


五、可扩展性路线图

5.1 已规划的扩展方向

#mermaid-svg-7XjypW0Q9hGrFV2v{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-7XjypW0Q9hGrFV2v .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-7XjypW0Q9hGrFV2v .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-7XjypW0Q9hGrFV2v .error-icon{fill:#552222;}#mermaid-svg-7XjypW0Q9hGrFV2v .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-7XjypW0Q9hGrFV2v .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-7XjypW0Q9hGrFV2v .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-7XjypW0Q9hGrFV2v .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-7XjypW0Q9hGrFV2v .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-7XjypW0Q9hGrFV2v .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-7XjypW0Q9hGrFV2v .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-7XjypW0Q9hGrFV2v .marker{fill:#333333;stroke:#333333;}#mermaid-svg-7XjypW0Q9hGrFV2v .marker.cross{stroke:#333333;}#mermaid-svg-7XjypW0Q9hGrFV2v svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-7XjypW0Q9hGrFV2v p{margin:0;}#mermaid-svg-7XjypW0Q9hGrFV2v .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-7XjypW0Q9hGrFV2v .cluster-label text{fill:#333;}#mermaid-svg-7XjypW0Q9hGrFV2v .cluster-label span{color:#333;}#mermaid-svg-7XjypW0Q9hGrFV2v .cluster-label span p{background-color:transparent;}#mermaid-svg-7XjypW0Q9hGrFV2v .label text,#mermaid-svg-7XjypW0Q9hGrFV2v span{fill:#333;color:#333;}#mermaid-svg-7XjypW0Q9hGrFV2v .node rect,#mermaid-svg-7XjypW0Q9hGrFV2v .node circle,#mermaid-svg-7XjypW0Q9hGrFV2v .node ellipse,#mermaid-svg-7XjypW0Q9hGrFV2v .node polygon,#mermaid-svg-7XjypW0Q9hGrFV2v .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-7XjypW0Q9hGrFV2v .rough-node .label text,#mermaid-svg-7XjypW0Q9hGrFV2v .node .label text,#mermaid-svg-7XjypW0Q9hGrFV2v .image-shape .label,#mermaid-svg-7XjypW0Q9hGrFV2v .icon-shape .label{text-anchor:middle;}#mermaid-svg-7XjypW0Q9hGrFV2v .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-7XjypW0Q9hGrFV2v .rough-node .label,#mermaid-svg-7XjypW0Q9hGrFV2v .node .label,#mermaid-svg-7XjypW0Q9hGrFV2v .image-shape .label,#mermaid-svg-7XjypW0Q9hGrFV2v .icon-shape .label{text-align:center;}#mermaid-svg-7XjypW0Q9hGrFV2v .node.clickable{cursor:pointer;}#mermaid-svg-7XjypW0Q9hGrFV2v .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-7XjypW0Q9hGrFV2v .arrowheadPath{fill:#333333;}#mermaid-svg-7XjypW0Q9hGrFV2v .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-7XjypW0Q9hGrFV2v .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-7XjypW0Q9hGrFV2v .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-7XjypW0Q9hGrFV2v .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-7XjypW0Q9hGrFV2v .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-7XjypW0Q9hGrFV2v .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-7XjypW0Q9hGrFV2v .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-7XjypW0Q9hGrFV2v .cluster text{fill:#333;}#mermaid-svg-7XjypW0Q9hGrFV2v .cluster span{color:#333;}#mermaid-svg-7XjypW0Q9hGrFV2v div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-7XjypW0Q9hGrFV2v .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-7XjypW0Q9hGrFV2v rect.text{fill:none;stroke-width:0;}#mermaid-svg-7XjypW0Q9hGrFV2v .icon-shape,#mermaid-svg-7XjypW0Q9hGrFV2v .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-7XjypW0Q9hGrFV2v .icon-shape p,#mermaid-svg-7XjypW0Q9hGrFV2v .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-7XjypW0Q9hGrFV2v .icon-shape .label rect,#mermaid-svg-7XjypW0Q9hGrFV2v .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-7XjypW0Q9hGrFV2v .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-7XjypW0Q9hGrFV2v .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-7XjypW0Q9hGrFV2v :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 长期 (v3.0)
玩家自制剧本
模组市场
多人合作战役
中期 (v2.0)
好友系统
联盟玩法
排行榜
短期 (v1.5)
插件化剧情
多语言支持
AI建议助手
当前 (v1.0)
单机叙事
基础政策/战斗
成就系统

5.2 具体实现方案

🔌 插件化剧情

src/app/api/game/<module>/ 下创建独立路由,并在 engine 中注册对应的处理函数。新增剧情模块无需修改核心代码。

🌐 多语言支持
  • 使用 Next.js 内置 i18n 支持 zh-CNen
  • 所有 UI 文案抽离到 src/locales/*.json
  • LLM Prompt 动态注入语言标记,让模型输出对应语言
👥 社区功能

新增 FriendshipGuildLeaderboard 数据表:

  • 好友:双向确认、在线状态
  • 联盟:共同任务、资源池
  • 排行榜:按声望/战力/成就点数排序
🤖 AI 助手

提供可选的高级 AI 服务:

  • 战略建议:分析当前局势推荐行动
  • 占星解读:解读预言背后的深层含义
  • 独立微服务,不影响主游戏性能

相关推荐
cxr8281 小时前
高分子复合材料 AI 逆向设计合——验证闭环、决策优化与中试放大
人工智能·材料逆向设计合成
litble2 小时前
如何速成LLM以伪装成一个AI研究者(6)——LoRA,Adapter,P-tuning,量化,QLoRA
人工智能·lora·量化·peft·qlora·高效微调
开发者每周简报2 小时前
网海三部曲·无名宗师传
javascript·人工智能
卷毛的技术笔记2 小时前
告别硬编码!Spring AI Alibaba 实现 AI Agent 智能工具调用(Tool Calling)
java·人工智能·后端·python·spring·ai编程
Cosolar2 小时前
从零写一个 Attention Is All You Need
人工智能·面试·架构
ai_xiaogui2 小时前
PanelAI:新一代AI算力调度系统,支持本地大模型一键部署与商业运营
人工智能·panelai·panelai算力调度系统·本地大模型一键部署平台·ai应用市场管理面板·企业级部署·2026本地ai私有化解决方案
冬奇Lab2 小时前
Agent 系列(9):多 Agent 架构设计模式——Supervisor 与 Pipeline
人工智能·源码·agent
冬奇Lab3 小时前
每日一个开源项目(第118篇):SkillOpt - 像训练神经网络一样优化 LLM Agent 的技能
人工智能·开源·agent