Files
xianren_studio/docs/ARCHITECTURE.md
T

21 KiB
Raw Blame History

Xianren Studio(仙人工作室)代码组织与布局

本文档描述代码仓库的组织结构、模块职责、数据流与关键实现。功能变更后如涉及结构、流程或数据模型,必须同步更新本文档。

最后更新:2026-08-16


1. 总览

技术栈:Tauri 2Rust 壳 + WebView2 + React 18 / TypeScript / Vite / Tailwind,推理引擎为 llama.cpp 的 llama-server 子进程。

xianren_studio/
├── apps/desktop/          Tauri 桌面壳(Rust 命令层、tauri.conf.json、推荐模型/预制智能体/预制工作流默认 JSON、工作流执行引擎 workflow.rs、邮件发送 mail.rs
├── crates/core/           领域核心:SQLite(模型注册表、智能体、工作流、定时计划、会话、消息、设置)
├── crates/engine/         llama-server 生命周期 + 流式/非流式聊天(本地与远程 OpenAI 兼容)
├── crates/download/       分片断点续传下载器
├── crates/api/            OpenAI 兼容本地 API 服务(axum
├── ui/                    React 前端
├── scripts/               构建 / 引擎与测试模型下载脚本
├── docs/                  产品与技术方案、功能记录、本文档
└── AGENTS.md              开发/维护约定(含文档同步规则)

2. 分层与数据流

React UIui/src
   │  Tauri invokeapi.ts 封装)+ 事件监听(onEvent
   ▼
apps/desktop/src/commands.rs  ← 所有 Tauri 命令(invoke_handler 注册于 lib.rs
   │
   ├── crates/coreSQLitemodels / agents / workflows / scheduled_tasks / sessions / settings
   ├── crates/enginellama-server 子进程 / 远程 OpenAI API
   ├── crates/download(下载任务)
   └── crates/api(本地 API 服务)

前端通过 ui/src/api.tsapi.* 方法调用后端命令;后端通过 Tauri emit 向前端推送事件(见 §7 事件通道)。


3. 前端结构(ui/

ui/src/
├── main.tsx                入口
├── App.tsx                 导航栏、路由(9 个页面)、全局事件订阅(引擎/下载/模型/建议/定时计划/会话)
├── api.ts                  Tauri invoke 封装 + 全部请求/事件 TypeScript 类型
├── store.ts                zustand 全局状态(见下)
├── styles.css              全局样式
├── components/Icon.tsx     SVG 图标库
└── pages/
    ├── ChatPage.tsx        对话页(最大的页面,含会话快照、消息气泡、模型下拉、建议标签)
    ├── AgentsPage.tsx      智能体列表(预制/自定义分组、新建/编辑/删除/恢复预制)
    ├── AgentChatPage.tsx   智能体会话页(按路由加载智能体并渲染 ChatPage 智能体模式)
    ├── WorkflowsPage.tsx   工作流列表(预制/自定义分组、新建/删除/恢复预制)
    ├── WorkflowCanvasPage.tsx 工作流画布(节点拖入/拖拽/连线、滚轮缩放、空白平移、节点/连线右键菜单、导入导出、运行与结果展示)
    ├── ModelsPage.tsx      模型管理(本地部署 + 在线 API 启用开关)
    ├── ModelPlazaPage.tsx  模型广场(HF/ModelScope 搜索与下载)
    ├── TasksPage.tsx       任务(下载/部署进度)
    ├── ToolsPage.tsx       工具(Tavily 联网搜索)
    ├── ServerPage.tsx      服务管理(本地 OpenAI API
    └── SettingsPage.tsx    设置

3.1 全局状态(store.ts

主要状态字段:

字段 说明
agents / agentsLoaded 智能体列表(预制 + 自定义)与加载标记
agentConversations 智能体 id → 会话列表(各智能体会话隔离,key 为智能体 id)
workflows / workflowsLoaded 工作流列表(预制 + 自定义)与加载标记
scheduledTasks 定时计划列表(任务页)
models 模型列表(含 enabledkindfile_name 等)
engine 引擎状态(running / model / port
deployStates / deployProgress 各模型部署状态(loading/ready/error)与进度
chatSuggestionsByMessage 消息 ID → 预测建议列表(全局接收,跨选项卡不丢)
conversations 会话列表
tasks 下载/部署任务
server 本地 API 服务状态

3.2 会话快照(ChatPage.tsx

切换选项卡时 React Router 会卸载页面,因此 ChatPage.tsx 顶部维护了模块级 chatSession 对象(当前会话、所选模型、消息、输入草稿、请求参数、面板开合、工具、版本、附件),每次渲染后写回;重新挂载时用快照初始化,实现「切走再回来保持原状」。


4. 后端命令层(apps/desktop

4.1 lib.rs

  • run():初始化数据目录(%APPDATA%\XianrenStudio)、日志、panic 钩子;构建 Tauri 应用并注册 invoke_handler
  • 注册插件:tauri-plugin-openertauri-plugin-autostart(开机启动,Windows 写注册表启动项)。
  • setup 末尾启动自动加载模型任务(auto_load_models:按设置列表顺序逐个部署,最后一个保持运行)。
  • setup 末尾启动定时计划后台调度循环tokio interval 每 30 秒调用 run_due_scheduled_tasks)。
  • 数据目录:logs/models/engines/recommendations/

4.2 commands.rs(命令分组)

分组 命令
智能体 list_agentsadd_agentupdate_agentremove_agentset_agent_enabledrestore_preset_agents
工作流 list_workflowsadd_workflowupdate_workflowremove_workflowset_workflow_enabledrestore_preset_workflowsrun_workflow
定时计划 list_scheduled_tasksadd_scheduled_taskupdate_scheduled_taskremove_scheduled_taskset_scheduled_task_enabledrun_scheduled_task_now
邮件 mail_test(用当前 SMTP 配置发送测试邮件)
应用/设置 app_infoautostart_statusautostart_setsettings_getsettings_set
模型 list_modelsimport_modelremove_modelset_model_enabledscan_modelsadd_remote_model
模型广场 search_modelslist_model_fileslist_recommended_modelsimport_recommendationsfetch_model_page
会话 list_conversations(可按 agent_id 过滤)、create_conversation(可选 agent_id,自动继承智能体系统提示词与默认模型)、rename_conversationset_conversation_pinnedset_conversation_favoriteimport_conversationset_conversation_toolsdelete_conversationget_messages
消息 chat_sendchat_stopregenerate_messageedit_messagelist_message_versionsapply_message_version
引擎 engine_startengine_stopengine_statusdeploy_model
工具 web_searchTavily)、list_skillsadd_skillupdate_skillremove_skillset_skill_enabledtest_skilllist_mcp_serversadd_mcp_serverupdate_mcp_serverremove_mcp_serverset_mcp_server_enabledmcp_test_servermcp_list_toolsmcp_call_tool
下载 download_enqueue
服务 server_startserver_stopserver_status
其他 report_erroropen_path

聊天相关核心函数(均在 commands.rs):

  • chat_send:写入用户消息 → 构建历史 → 拉起后台生成任务。
  • run_generation_and_stream:统一生成入口(本地引擎 / 远程 API),流式转发 token、统计用量、写库、发 chat://done,随后触发标题生成与建议生成。
  • inject_system_prompts:把会话/智能体系统提示词(conversations.system_prompt)与工具说明统一注入消息历史最前;chat_send / regenerate_message / edit_message 三条链路共用。
  • maybe_generate_suggestionscall_suggestion_modelparse_suggestions:回答完成后预测用户接下来可能说的话。统一要求模型输出 JSON 数组;最多重试 3 次;过滤元信息行与回答原文片段;每条 ≤ 30 字。
  • maybe_generate_conversation_title:首轮对话自动生成标题。
  • create_conversation:先在指定作用域(普通对话或某智能体)查找空会话(find_empty_conversation)复用,没有才新建;智能体会话写入该智能体的系统提示词与默认模型。
  • seed_preset_agents:启动时首次写入 default_agents.json 中的预制智能体(settings.preset_agents_seeded 标记只执行一次);restore_preset_agents 命令可随时补齐缺失预制体。
  • run_workflow:加载工作流节点/连线 → 交给 workflow.rs 执行引擎按拓扑顺序运行;LLM 节点经 resolve_workflow_node_model 解析模型(节点 → 工作流默认 → 运行参数 → 自动回退),call_model_text 非流式调用本地引擎或远程 API,逐节点推送 workflow://node-status 事件。
  • seed_preset_workflows:启动时首次写入 default_workflows.json 中的预制工作流(settings.preset_workflows_seeded 标记只执行一次);restore_preset_workflows 命令可随时补齐缺失预制体。
  • run_due_scheduled_tasks:后台调度入口,由 lib.rs 启动的 tokio 循环每 30 秒调用一次;先清理重启前中断的「运行中」任务,再取出到点的启用计划逐个标记并异步执行。
  • execute_scheduled_task / run_scheduled_task_once:定时计划单次执行——解析执行智能体(指定智能体已删除时回退「通用助手」)与模型(resolve_scheduled_model:智能体默认模型 → 第一个本地模型 → 第一个已启用在线模型),在该智能体作用域内创建/复用空会话,写入用户消息并注入智能体系统提示词,本地模型未运行则自动拉起引擎,最后经 call_model_messages 调用模型并把助手回答写回数据库。
  • call_model_messagescall_model_text 的通用版,可携带 system + 多轮消息调用本地引擎或远程 OpenAI 兼容 API(定时计划复用)。
  • auto_load_models:应用启动时读取设置键 auto_load_models(JSON 数组,本地模型 id 按序排列),逐个调用 start_engine_and_wait 部署,非最后一个模型加载完即停止,最后一个保持运行。
  • start_engine_and_wait:本地模型引擎启动的公共实现(构造 EngineConfig、推送 engine://deploy / engine://deploy-progress 事件、轮询加载进度、更新 engine_base);deploy_model 命令与 auto_load_models 共用。
  • autostart_status / autostart_set:查询 / 设置开机启动(tauri-plugin-autostartManagerExt)。
  • run_scheduled_task_once:大模型执行完成后,若任务开启邮件,按内容模式发送——固定模式用填写的主题/正文,LLM 模式用智能体回答作正文(主题留空取回答首行);邮件发送失败时任务标记失败但保留回答内容。
  • send_task_email / load_smtp_config / split_recipients:读取设置页「邮件」SMTP 配置、拆分多收件人并调用 mail.rs 发送。

邮件发送模块(apps/desktop/src/mail.rs):

  • send_email:用 lettre 通过 SMTP 发送纯文本邮件;加密方式按设置分支——隐式 SSL 用 relay465)、STARTTLS 用 starttls_relay587)、无加密用 builder_dangerous25),均可自定义端口与超时。

工作流执行引擎(apps/desktop/src/workflow.rs):

  • topo_order:Kahn 拓扑排序,检测循环 / 未知节点 / 自连。
  • resolve_template:解析 {{input}}{{节点id}} 变量。
  • execute_workflow:按拓扑顺序执行 start / text / llm / end 节点,收集各节点输出并汇总最终结果;通过注入的 call_model 闭包调用模型,与具体模型解耦(单元测试用假模型跑通 5 个案例,另有真实模型端到端测试 real_model_translation_workflow_e2e)。

工具协议(技能 / MCP):

  • apps/desktop/src/tools.rsToolDef、标记解析([[skill:名]] / [[mcp:服务:工具:参数]])、MarkerFilter(流式输出时过滤标记)、run_tool_round(执行工具并回填模型,最多 3 轮)、系统提示词构建。
  • apps/desktop/src/mcp_client.rsMCP Streamable HTTP 客户端(initialize / tools/list / tools/call,兼容 SSE 响应)。
  • 聊天链路:chat_send / regenerate_message / edit_message 解析会话工具并注入系统提示词 → run_generation_and_stream 流式输出时过滤标记 → 完成后执行工具循环并保存最终内容。

5. 核心库(crates/core

5.1 app.rs

  • CoreApp:持有 SQLite 连接(Mutex<Connection>)与数据目录。
  • seed_default_settings:启动时用 insert_default 补齐缺失的设置键(不覆盖用户已保存值)。
  • open_db:执行 schema.sql + 增量迁移 ensure_column(为旧库补充新列,幂等)。

5.2 schema.sql(表结构)

关键字段 说明
models kindlocal/remote)、enabledfile_namefile_pathstatusbase_urlapi_keyapi_modelmeta_json 模型注册表;enabled 决定在线 API 模型是否出现在聊天页可选列表
settings key/value 键值设置
conversations titlemodel_idsystem_promptagent_idpinnedfavoritetools_json 会话;agent_id 为空表示普通对话,否则属于对应智能体
agents kindpreset/custom)、nameicondescriptionsystem_promptmodel_idenabled 智能体(预制 + 自定义)
workflows kindpreset/custom)、nameicondescriptionnodes_jsonedges_jsonmodel_idenabled 工作流(节点/连线以 JSON 存储,节点含 type/label/position/data
scheduled_tasks nameagent_idpromptinterval_minutesenablednext_run_atlast_run_atlast_statusidle/running/success/error)、last_resultlast_erroremail_enabledemail_toemail_modefixed/llm)、email_subjectemail_body 计划任务;next_run_at 由 SQLite datetime('now', '+N minutes') 计算(UTC),每次执行完成后推进
messages rolemodel_idcontenttokens_in/outelapsed_msfirst_token_msimages_json 消息;model_id 记录该回答所用模型(回答下方展示模型名)
message_versions contenttokens_outseq 重新生成前的旧版本
skills namedescriptioncontentenabled 技能工具库
mcp_servers namedescriptionurlauth_tokenenabled MCP 服务配置

迁移清单(ensure_column):models.kind/base_url/api_key/api_model/enabledmessages.elapsed_ms/first_token_ms/images_json/model_idconversations.pinned/favorite/tools_json/agent_id

新增列迁移:scheduled_tasks.email_enabled / email_to / email_mode / email_subject / email_bodyensure_column 幂等补齐)。

5.3 models.rs

模型 CRUD、set_enabled(启用/停用)、scan_directory(扫描 GGUF 目录)、量化猜测 guess_quant

5.4 sessions.rs

会话/消息/版本 CRUDfind_empty_conversation(新建对话复用空会话);import_message(导入对话用,可指定创建时间)。

5.5 agents.rs

智能体 CRUDlist/get/insert/update/delete/set_enabled)与预制体批量写入 insert_presets_if_missing(按 id 忽略已存在,供首次种子与「恢复预制智能体」复用)。

5.6 settings.rs

get/set/insert_default/all

5.7 workflows.rs

工作流 CRUDlist/get/insert/update/delete/set_enabled)与预制体批量写入 insert_presets_if_missing(按 id 忽略已存在);节点 WorkflowNodetype=start/llm/text/end、position、data)与连线 WorkflowEdge 以 JSON 列存储,序列化/反序列化在读写时完成。

5.8 scheduled_tasks.rs

计划任务 CRUD 与运行状态落库:list/get/insert/update/delete/set_enabled(停用时清空 next_run_at,启用时重新计算)、mark_running / finish_run(写执行结果并推进下次执行时间)、list_due(到点且未运行中的启用计划)、reset_stale_running(应用重启后把中断的「运行中」标记为失败);任务行含邮件配置字段(email_enabled/email_to/email_mode/email_subject/email_body)。


6. 引擎与远程调用(crates/engine

6.1 manager.rsEngineManager

  • start:以子进程启动 llama-serverCREATE_NO_WINDOW),轮询 /health 等待就绪;最多 180s。
  • stop:先请求 /shutdown,超时再 kill。
  • stream_chat / chat:流式 / 非流式聊天(/v1/chat/completions)。
  • status:返回 running / port / model。

6.2 remote.rs

  • stream_chat_remote / chat_remoteOpenAI 兼容远程 APIBearer 认证)。
  • normalize_baseBase URL 自动补 /v1

6.3 types.rs

  • ChatMessagerole/content/images,多模态时序列化为 content 数组。
  • ChatRequestmodel / messages / temperature / top_p / max_tokens / stream。
  • ChatStreamEventText / Reasoning(思考过程)/ Usage。

7. 事件通道(Tauri emit → 前端 onEvent

事件 方向 说明
chat://token 后端→前端 流式增量文本
chat://reasoning 后端→前端 思考过程增量
chat://done 后端→前端 回答完成(含 message_id、model_id、用量)
chat://suggestions 后端→前端 预测建议列表(全局订阅,存入 store)
chat://tool-status 后端→前端 工具调用状态(running/done),界面提示
chat://message-updated 后端→前端 消息内容更新(恢复版本后)
chat://title-updated 后端→前端 标题更新
chat://error 后端→前端 生成错误
engine://status 后端→前端 引擎状态变化
engine://deploy 后端→前端 部署状态(loading/ready/error
engine://deploy-progress 后端→前端 部署进度百分比/阶段
models://updated 后端→前端 模型列表变化
download://started/progress/done/error 后端→前端 下载任务进度
server://status 后端→前端 本地 API 服务状态
workflow://node-status 后端→前端 工作流节点运行状态(running/done/error)与输出文本
scheduled://updated 后端→前端 定时计划状态变化(创建/编辑/启停/执行完成),前端刷新列表
conversations://updated 后端→前端 定时计划执行后会话列表变化(供智能体会话页刷新)

8. 设置项(设置键 / 默认值)

定义于 crates/core/src/app.rsseed_default_settings

默认值 用途
model_dir 数据目录/models 模型目录
engine_bin engines/cpu/llama-server.exe llama-server 路径
backend auto 后端(auto/cpu/cuda/vulkan
hf_endpoint https://hf-mirror.com 模型下载源
api_port / api_key / api_enabled 1234 / 空 / false 本地 API 服务
upload_max_mb 10 上传大小上限
auto_title true 自动生成标题
suggest_enabled true 预测用户接下来说的话开关
suggest_count 3 预测条数(15
tavily_api_key (内置演示值) 联网搜索 API Key
tool_web_search_enabled true 联网搜索工具开关
auto_load_models [] 启动时自动加载的本地模型 id 列表(JSON 数组,顺序即加载顺序)
smtp_host / smtp_port / smtp_tls 空 / 465 / wrapper SMTP 发件服务器、端口、加密方式(wrapper/starttls/none
smtp_user / smtp_password 空 / 空 SMTP 用户名(通常为发件邮箱)与授权码/密码
smtp_from / smtp_from_name 空 / 仙人工作室 发件人地址(留空用用户名)与显示名称
recommend_dir 数据目录/recommendations 推荐列表目录
preset_agents_seeded 首次启动后为 1 预制智能体是否已写入(内部标记,避免覆盖用户删除)
preset_workflows_seeded 首次启动后为 1 预制工作流是否已写入(内部标记,避免覆盖用户删除)

9. 构建与运行

# 开发模式(自动拉起 Vite + Tauri
npm --prefix apps/desktop run dev

# 正式版(必须带 custom-protocol 特性,前端资源才会内嵌进 exe)
npm run build --prefix ui
cargo build --release -p xianren-desktop --features custom-protocol

# 或一键打包(tauri build 会自动启用该特性并打 NSIS 安装包)
npm --prefix apps/desktop run build

注意:不带 custom-protocol 编译出的 release exe 不会内嵌前端页面,直接运行会白屏,因此正式发布必须带该特性。


10. 文档维护约定

  • 功能变化 → 更新 docs/FEATURES.md 对应章节,并在「改动记录」追加。
  • 结构/流程/数据模型变化 → 更新本文档对应章节。
  • 大版本信息(技术栈、目录说明)变化 → 同步更新 README.md