# fallinai-backend **Repository Path**: fallinai/fallinai-backend ## Basic Information - **Project Name**: fallinai-backend - **Description**: fallinai后端 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-07-25 - **Last Updated**: 2026-10-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # FallinAI Backend FallinAI 桌面客户端的本地后端服务。基于 **Bun + Hono + LangChain.js / deepagents** 实现,提供模型供应商管理、流式 AI 对话、智能体(Agent)、知识库(RAG)、技能(Skills)、MCP 接入等能力。 服务默认监听 `http://127.0.0.1:58975`,仅对本地客户端提供服务,也可被 `fallinai-frontend`(Tauri 桌面端)以内置运行时方式启动调用。 ## 技术栈 | 类别 | 选型 | | --- | --- | | 运行时 | [Bun](https://bun.sh)(TypeScript 直接执行) | | Web 框架 | [Hono](https://hono.dev) | | AI 编排 | LangChain.js、LangGraph、[deepagents](https://github.com/langchain-ai/deepagents) | | 模型接入 | OpenAI 兼容协议(经 `baseUrl` 对接各家供应商) | | 业务数据库 | [PGlite](https://github.com/electric-sql/pglite)(嵌入式 PostgreSQL) | | 向量数据库 | [LanceDB](https://lancedb.github.io/lancedb)(预留目录) | | 会话断点持久化 | `bun:sqlite`(LangGraph Checkpointer) | | 网络搜索 | Tavily(`web_search` / `fetch_web` 工具) | | MCP | `@langchain/mcp-adapters`(动态挂载多 MCP 服务工具) | | 文档解析 | LangChain 官方 Loader(PDF / CSV / JSON / Markdown / Doc / Docx / PPTX) | ## 功能特性 ### 1. 模型供应商管理(Supplier) - 内置预置供应商:硅基流动(SiliconFlow)、深度求索(DeepSeek)、月之暗面(Kimi)、阿里云百炼(Bailian)、火山方舟(Volcengine),亦可创建自定义供应商。 - 每个供应商独立维护配置(`apiKey`、启用状态 `status`),支持启用/禁用、一键切换。 - 从供应商 API(`/models` 接口)自动拉取并增量同步 **LLM / Embedding** 模型列表到本地数据库。 - 提供「可用 LLM / Embedding 模型」查询,供前端发起对话或构建知识库时选择。 ### 2. 会话与流式聊天(Chat) - 会话、消息、聊天文件的增删改查;支持消息 `complete` 完成态标记。 - 采用 **deepagents** 构建 Agent,模型通过供应商 `baseUrl` + `apiKey` 动态指定。 - **SSE 流式输出**,按阶段分帧推送: - `thinking`:深度思考内容 - `tool_call`:工具调用(含逐步增量参数) - `tool_result`:工具执行结果 - `content`:正文内容 - 流式内容 **节流落库**(默认 500ms 刷盘一次),结束后合并写回并标记完成,避免高频 IO。 - 支持对话**停止**(`AbortController`)、按 `chatId` 持久化 LangGraph 断点(checkpointer)。 - 每轮对话支持:联网搜索开关、推理强度(`effort`)、绑定智能体、挂载知识库 / 技能 / MCP、携带附件文件。 - 每个会话在 `~/.fallinai/workspace/chat-{id}` 下创建工作目录,作为 Agent 沙箱 Shell(`LocalShellBackend`)执行命令的根目录,并内置国内镜像源。 ### 3. 知识库 / RAG(Knowledge) - 知识库 CRUD,创建时需指定供应商与 Embedding 模型。 - 文件上传后走「保存记录 → 解析 → 分块 → Embedding」流水线,通过 SSE 实时反馈各阶段进度(保存成功 / 解析成功 / 嵌入成功 / 失败)。 - 文件记录维护解析、嵌入状态(未解析 / 已解析 / 内容为空 / 解析失败,未嵌入 / 已嵌入 / 嵌入失败)。 - 支持格式:`md` / `markdown` / `pdf` / `csv` / `json` / `txt` / `doc` / `docx` / `pptx`。 - 文本默认按 `chunkSize=1000, chunkOverlap=200` 切分;向量存储目录(LanceDB)已初始化(`~/.fallinai/lancedb`)。 ### 4. 智能体(Agent) - 自定义系统提示词(`prompts`),可绑定技能与 MCP 服务,支持启用/停用。 ### 5. 技能(Skills) - 内置技能:`docx` / `pdf` / `pptx` / `xlsx`(仓库 `skills/` 目录,随打包分发)。 - 用户技能目录:`~/.fallinai/skills`,每个技能一个目录,含 `skill.md`(YAML Front Matter + Markdown 指令)。 - 支持技能的**启停**(写入 `.state` 文件)与 **ZIP 上传解压**(Windows 使用 PowerShell `Expand-Archive`)。 ### 6. MCP - 通过 `~/.fallinai/mcp/mcp.json` 管理多个 MCP Server 配置,对话时按需选择,经 `MultiServerMCPClient` 动态加载对应工具。 ### 7. 内置工具(Agent Tools) - `get_now_datetime`:获取当前日期时间 - `fetch_web`:抓取并抽取网页正文(Tavily extract) - `web_search`:联网搜索(需 `TAVILY_API_KEY`,经对话 `context` 注入) ## 目录结构 ``` fallinai-backend/ ├── index.ts # 服务入口:Hono app 路由注册与 Bun serve 配置 ├── controller/ # HTTP 控制器(解析请求参数、校验、SSE 封装) │ ├── agent.ts │ ├── chat.ts │ ├── knowledge.ts │ ├── mcp.ts │ ├── skill.ts │ └── supplier.ts ├── service/ # 服务层(业务逻辑、LangChain/deepagents 编排) │ ├── agent.ts │ ├── chat.ts # 核心:流式对话 / 断点 / 沙箱 / 技能 / MCP 装配 │ ├── file.ts # 知识库文件解析与 Embedding │ ├── knowledge.ts │ ├── mcp.ts │ ├── skill.ts │ └── supplier.ts # 供应商与模型同步 ├── models/ # 数据实体 + Repository(JSONB 表) │ ├── agent.ts │ ├── chat.ts │ ├── file.ts │ ├── knowledge.ts │ ├── mcp.ts │ └── supplier.ts ├── db/ # PGlite 数据库层 │ ├── connection.ts # DatabaseManager 单例(懒加载) │ ├── init.ts # 启动时初始化所有服务建表 │ ├── jsonb.ts # JSONB 字段读写工具 │ └── utils.ts # MigrationManager 建表/建索引 + Repository 基类 ├── lib/ # 工具与 AI 装配 │ ├── agent-tools.ts # 内置 Agent 工具(web_search / fetch_web 等) │ ├── langgraph-checkpoint-sqlite.ts │ ├── prompt.ts # 默认系统提示词 │ └── utils.ts # baseDataDir = ~/.fallinai ├── preset/ │ └── model-supplier.ts # 内置供应商预设(含图标 dataURI) ├── skills/ # 内置技能(docx / pdf / pptx / xlsx) └── package.json ``` ## 环境要求 - **Bun** `>= 1.x`(使用 `bun:sqlite`、`bun build`、`Bun.serve` 等特性) - 桌面打包场景下,Bun 运行时随应用一起分发(见 `fallinai-frontend/src-tauri/resources/bun`) ## 快速开始 ```sh # 1. 安装依赖 bun install # 2. 开发运行(默认监听 127.0.0.1:58975) bun run dev # 3. 生产构建(输出到 out/,排除 pglite 原生模块) bun run build ``` 启动后可用以下方式验证: ```sh curl http://127.0.0.1:58975/supplier/getSupplierList ``` 前端联调(开发模式):`fallinai-frontend` 的 `/api` 请求会代理到本服务 `http://127.0.0.1:58975`。 ## 本地数据存储 服务所有持久化数据默认存放在用户主目录下: | 目录 | 用途 | | --- | --- | | `~/.fallinai/pglite/` | PGlite 数据库(业务表数据) | | `~/.fallinai/sqlite/sqlite-saver.db` | LangGraph 会话断点(checkpointer) | | `~/.fallinai/lancedb/` | LanceDB 向量库 | | `~/.fallinai/workspace/chat-{id}/` | 各会话 Agent 沙箱工作目录 | | `~/.fallinai/skills/` | 用户安装 / 上传的技能 | | `~/.fallinai/mcp/mcp.json` | MCP Server 配置 | | `~/.fallinai/uploads/knowledge/` | 知识库文件上传目录 | ## 数据模型 表统一采用 **`id`(SERIAL 主键)+ `data`(JSONB)** 结构,字段冗余存于 JSONB,并在常用字段上建立表达式索引 / GIN 索引: | 表 | 说明 | 关键字段(data 内) | | --- | --- | --- | | `supplier` | 供应商基础信息(自定义供应商) | `supplierTitle`、`supplierName`、`baseUrl`、`sort`、`icon` | | `supplier_config` | 供应商配置 | `supplierId`、`apiKey`、`status` | | `supplier_llm_model` | 供应商模型库 | `supplierId`、`modelName`、`title`、`capability[]`(llm / embedding 等)、`status` | | `chat` | 会话 | `supplierId`、`modelName`、`title`、`agent`、`rags` | | `chat_message` | 消息(content 为分段 JSON) | `chatId`、`role`、`content`、`files`、`complete` | | `chat_file` | 聊天文件(hash 去重) | `filePath`、`hash` | | `agents` | 智能体 | `name`、`intro`、`prompts`、`skills`、`mcps`、`enabled` | | `knowledge` | 知识库 | `knowledgeName`、`embedModel`、`topK`、`supplierId` | | `knowledge_files` | 知识库文件 | `knowledgeId`、`name`、`mimetype`、`size`、`parseStatus`、`embedStatus` | 消息内容以分段 JSON 数组存储,元素类型:`thinking` / `content` / `tool_call` / `tool_result`(相邻同类型自动合并,便于前端与历史记录还原)。 ## HTTP API ### 通用约定 - 服务启动时在 `db/init.ts` 完成建表初始化。 - 路由采用 RPC 风格:`app.all('/{模块}/{func}')`,`func` 即控制器中对应方法名。 - 响应统一格式:`{ code: 0 | 1, data?, msg }`。 - 上传、下载类接口与流式对话使用 SSE / FormData。 ### 路由一览 | 模块 | 前缀 | 可用方法(`func`) | | --- | --- | --- | | 供应商 | `/supplier` | `createSupplier`、`updateSupplier`、`deleteSupplier`、`getSupplierList`、`getSupplierConfig`、`getSupplierConfigById`、`updateSupplierConfig`、`updateSupplierConfigBySupplierId`、`updateApiKey`、`updateStatus`、`toggleStatus`、`deleteSupplierConfig`、`deleteSupplierConfigBySupplierId`、`updateSupplierModels`、`getSupplierModels`、`getAvaliableLlmModels`、`getAvaliableEmbeddingModels` | | 聊天 | `/chat` | `createChat`、`saveInitMessage`、`startChat`(SSE)、`stopChat`、`getChatList`、`getChatById`、`updateChat`、`deleteChat`、`existFile`、`createMessage`、`getMessageList`、`completeMessage` | | 知识库 | `/knowledge` | `creatKnowledge`、`getKnowledgeList`、`getKnowledgeById`、`updateKnowledge`、`deleteKnowledge`、`getKnowledgeFileList`、`addFileToKnowledge`(SSE) | | 智能体 | `/agent` | `getAgentList`、`getAgent`、`createAgent`、`updateAgent`、`deleteAgent`、`toggleAgent` | | 技能 | `/skill` | `getSkillList`、`toggleSkill`、`deleteSkill`、`upload`(zip) | | MCP | `/mcp` | `saveMcpJson`、`getMcpJson` | ### 流式对话(SSE 帧格式) `POST /chat/startChat` 返回 `text/event-stream`,每行一个 JSON 帧,示例: ```jsonc { "type": "thinking", "isStart": true } { "type": "thinking", "content": "..." } { "type": "tool_call", "isStart": true, "name": "web_search", "id": "call_xxx" } { "type": "tool_call", "args": "{\"query\":" } { "type": "tool_result","isStart": true, "name": "web_search", "id": "call_xxx" } { "type": "tool_result","content": "..." } { "type": "content", "content": "回答内容..." } { "type": "content", "isEnd": true } ``` 阶段切换时先推 `isEnd`,再推下一阶段 `isStart`,前端据此渲染思考 / 工具 / 正文流程。 ## Skills 格式约定 一个技能即一个目录,根目录必须包含 `skill.md`: ```markdown --- name: docx # 技能名称 description: 技能描述(模型按此判断何时调用) description_zh: 中文描述(列表展示优先) --- # 标题 技能使用指令正文... ``` - 目录下可附带脚本、模板等资源,模型通过 Sandbox 环境(Python / Node / Shell)调用。 - 启用状态记录在技能目录的 `.state` 文件中(`enabled` / `disabled`),无该文件时默认启用。 ## 使用说明 / 注意事项 - 首次使用需先在设置页为供应商配置 `apiKey` 并启用,再“刷新模型”同步模型列表。 - 联网搜索依赖 Tavily,需在调用侧注入 `TAVILY_API_KEY`(`web_search` / `fetch_web` 工具从 `context` 读取)。 - 对话附件支持大文件(服务请求体上限已放宽至 2GB,并关闭空闲超时);聊天文件按 SHA-256 哈希去重,重复上传可跳过。 - Agent 沙箱可执行本地命令,工作目录与会话隔离;Windows 下上传技能 zip 依赖 PowerShell `Expand-Archive`。 ## License ISC