夜雨聆风学习资料网

ARTICLE · 1157210

开源一个本地优先的多模态 AI 助手:Jarvis 全功能详解

开源一个本地优先的多模态 AI 助手:Jarvis 全功能详解

开源一个本地优先的多模态 AI 助手:Jarvis 全功能详解

它不是套壳聊天框,而是把「对话、工具调用、子代理、记忆、多模态、可观测」串成一条完整链路的 Agent 运行时。

一、它是什么

Jarvis(贾维斯)是一套 本地优先(local-first) 的全栈智能助手:对话、语音、视觉、文件操作、浏览器自动化、任务执行都在本机完成,云端模型只是可选项。

  • • 后端:FastAPI + uvicorn,约 14.5k 行 Python
  • • 前端:Vue 3 + Vite + Pinia + Tailwind,约 9.2k 行 TS/Vue
  • • 实时通道:SSE 流式输出 + WebSocket 通知
  • • 本地推理:Ollama(对话 / 视觉)、Paraformer 中文语音识别、F5-TTS 声音克隆
  • • 存储:SQLite(结构化)+ LanceDB(向量检索)
  • • 测试:18 个 pytest 文件、约 4.9k 行

二、架构:一个 Mediator,六类引擎

系统只有一条主干:所有 API 路由都交给 JarvisMediator 协调,引擎之间从不互相调用。

  • • Mediator(中介者):JarvisMediator 统一编排 ChatEngine / VoiceEngine / TaskEngine / MemoryStore / SubModelProcessor / HardwareBridge
  • • Strategy(策略):AI Provider 适配器、任务执行方式、上下文压缩策略,全部可插拔替换
  • • Repository(仓储):记忆持久化抽象,SQLite 与 LanceDB 两套实现
  • • Registry(注册表):Provider 与 Tool 的注册 + 工厂
  • • Facade(门面):SubModelProcessor 把语音识别与视觉理解封装成「返回纯文本」的黑盒,多模态复杂度不污染主链路

好处很直接:加一个新输入源(比如摄像头)只需要新增一个 Engine 并挂到 Mediator 上,不用改对话链路。

三、功能详解

1. 统一 Agent Loop:三个入口,一份工具循环

这是项目最核心的一块。无论你是走普通请求、SSE 流式,还是多轮消息列表,三条入口最终都由同一个 AgentLoop 驱动工具循环:

  • • assistant turn 注入:每轮把带 tool_use 的 assistant 消息补回上下文,避免「孤儿 tool_result」导致 provider 直接报错
  • • 工具去重:相同(工具 + 参数)的调用自动跳过,防止模型原地打转
  • • 并行执行:互不依赖的工具调用用 asyncio 并发跑
  • • 迭代约束:注入迭代提示与停止提示,默认最多 8 轮,防止无限循环
  • • 协议适配:同一套结果按 anthropic / openai 两种协议格式化回填

2. 流式体验:先说话,再干活

  • • 两阶段流式:第一阶段实时推 thinking 与正文 token,同时检测 tool_use;只有真的调用了工具,才进入第二阶段执行并推送增量文本,不重复输出
  • • 思考过程可视化:thinking 块实时流式展示(可折叠),并持久化到消息里,回看历史也有
  • • 随时打断:前端 AbortController 一键停止生成
  • • 工具生命周期事件:工具调用 / 结果以 SSE 事件实时渲染在前端

3. 上下文工程:长对话不失忆

早期版本到处硬编码「取最近 10 条」,长对话必然丢上下文。现在统一交给 ContextManager:

  • • Token 预算:从模型注册表的 context_window 自动计算,并预留输出、记忆与 system prompt 的空间
  • • 三种压缩策略:滑动窗口 / 摘要 / 混合(默认),实现 CompactionStrategy.compact() 即可自定义
  • • 工具历史折叠:把 tool / tool_result 消息转成自然语言摘要注入上下文;总量超阈值时再按工具类型聚合成「早期工具执行摘要」,最近几轮保留原文——模型始终记得自己调过什么
  • • 记忆注入:对话前检索相关记忆并拼进 system prompt
  • • 可观测:每次构建都记录 in / out / dropped / memory / tokens 估算,方便调优

4. 子代理编排:把委派做成一等公民

复杂任务不该挤在一条主对话里。Jarvis 内置六种角色化子代理:

  • • Researcher 网络调研,结构化要点 + 来源
  • • Coder 代码生成与执行(带自己的工具循环)
  • • Reviewer 代码 / 方案复审,优、问、建三段式
  • • Summarizer 长文摘要,保留关键事实
  • • Planner 任务拆解 + 验收标准
  • • General 通用隔离子代理

编排器支持三种调度模式:sequential(串行,后者可看到前者全部输出)、parallel(asyncio 并行)、map-reduce(并行执行 + 可选的二次综合)。

关键细节:每次子代理委派都会开启独立会话,主对话只收到结构化结果,父会话还能跳进去看完整的执行轨迹。

5. 工具系统

主模型通过工具调用完成任务,全部工具走统一的 TaskExecutor 策略层:

  • • file:读 / 写 / 编辑 / 列目录 / 建目录,带路径穿越保护
  • • bash:Shell 执行,危险命令黑名单
  • • browser:Playwright 浏览器自动化
  • • desktop:桌面控制
  • • api:外部 HTTP 接口调用
  • • subagent:把任务委派给子代理编排器

工具结果会被格式化成纯文本回注模型,同时以事件形式展示在前端,用户能看见「它到底干了什么」。

6. 技能系统:用 Markdown 扩展能力

技能就是一份带 YAML frontmatter 的 Markdown:

  • • 文件(workspace/skills/<id>/skill.md)+ 数据库元数据的混合存储,git 可追踪、手工可编辑
  • • 启用 / 归档 / 排序、标签、分组;分组为空表示始终注入,否则只在激活分组下生效
  • • 完整 CRUD 走 18 个 REST 端点,前端有专门的管理界面(列表 / 标签 / 分组三个 Tab)
  • • 输入框敲 / 直接唤起斜杠命令面板,内置 /clear、/stop、/context,其余自动列出所有技能
  • • 启用的技能会自动注入 system prompt,模型知道「我现在有哪些能力」

7. 多模态:听、看、说全部本地化

  • • 听:Paraformer-large 中文语音识别(MPS 加速),支持浏览器录制的 WebM 直接解码;可切 Whisper
  • • 看:本地视觉模型理解图片,支持摄像头定时分析与粘贴板图片,分析结果以卡片形式入对话,缩略图可全屏放大(50%–400% 缩放)
  • • 说:F5-TTS 声音克隆,上传一段 5–15 秒参考音频即可用自己的音色朗读;流式对话里按标点逐句合成、以 SSE 推送 PCM 分片,前端用 Web Audio 排程播放
  • • 优雅降级:没装 F5-TTS、没上传参考音频或推理失败时,自动回落到浏览器语音合成,链路永不中断
  • • 全局开关:TTS 可一键关掉,后端直接短路,不推任何音频事件

8. 记忆系统

  • • 双层存储:SQLite 保存结构化记忆与对话,LanceDB 负责向量语义检索
  • • 仓储模式:MemoryRepository 抽象出 SQLite 与 LanceDB 两套实现,换存储不动业务代码
  • • 对话自动持久化,记忆检索在上下文构建阶段完成,对业务透明

9. Provider 体系:可插拔,可故障转移

  • • AIClient 抽象 → ProviderRegistry 注册 → AIRouter 路由,三层解耦
  • • 内置 Ollama、OpenAI、Anthropic、MiniMax 适配器,任一失败自动 failover
  • • ProviderInstance:支持在界面里自定义多个供应商实例(自定义模型名、API Key、Base URL),持久化到数据库,按需切换
  • • 语音识别与语音合成不跟随 chat provider,始终走本地链路——换云端模型不会把语音能力弄丢

10. 可观测性:每一次 LLM 调用都可回放

这是排查问题最爽的一块。每次 LLM 调用(对话、流式、子代理、工具迭代、主题生成、上下文压缩)都会完整落盘:

  • • 索引:一行一条摘要(时间 / provider / 模型 / 延迟 / 状态 / 是否带工具调用)
  • • 详情:request body、response、真实 HTTP payload、SSE 原始分片、thinking、tool_use 全量保存
  • • 前端两个视图:按时间平铺,或按会话分组折叠——一次看到某次对话触发的全部调用
  • • 详情四个 Tab:Request Body / Response / Raw HTTP / Messages

「为什么这次跑了 30 秒」「子代理的工具循环到底怎么转的」「这个 4xx 是谁返回的」,翻日志就有答案。

11. 会话管理与文件追踪

  • • 会话归档:主列表与归档区分开,支持归档 / 恢复 / 永久删除,归档状态本地持久化
  • • 话题自动生成:新会话自动起标题,可手动编辑
  • • 输入体验:输入框 1–6 行自适应;↑/↓ 翻找已发送内容,按会话隔离并持久化;发送后自动清空
  • • 对话轮次侧栏:右侧列出每一次提问,点击跳转,滚动时自动高亮当前轮次
  • • 会话文件追踪:文件工具的写入 / 编辑 / 删除 / 建目录操作自动记账,侧栏列出本次会话触碰过的所有文件;点击打开全屏查看器,Markdown / HTML / 代码 / 图片按类型渲染

四、工程化

  • • 5 种设计模式贯穿全栈,DESIGN_PATTERNS.md 里有完整的取舍说明
  • • CLAUDE.md 记录了架构决策、开发命令与踩坑清单,bugs.md 记录已知问题
  • • 18 个测试文件覆盖对话引擎、上下文管理、子代理、工具解析、记忆、Provider 配置、技能系统等
  • • 启动脚本 jarvis.sh start / stop / status 一键拉起前后端

五、快速开始

git clone https://github.com/jiafeimao-gjf/Jarvis_demo.gitcd Jarvis_demo./jarvis.sh start        # 后端 9529 + 前端 8529

前置准备:Ollama(qwen3:4b 对话 / qwen3.5:9b 视觉)、ffmpeg(语音输入)、Python 依赖(pip install -r requirements.txt)。语音克隆是可选能力,需要时再装 F5-TTS,不装也能跑。

六、已知限制

  • • LanceDB 目前用的是哈希伪向量,语义检索能力有限,需要换成真正的 embedding 模型
  • • 向量检索初始化偶有不稳定
  • • 暂无用户认证,不要直接暴露到公网
  • • 前端还没有自动化测试

结语

Jarvis 的出发点很朴素:做一个真的能干活、数据尽量留在本机的助手。它现在能听、能看、能说、能写代码、能开浏览器、能拆解任务、能记住你,而且每一步都留下可追溯的痕迹。

仓库地址:github.com/jiafeimao-gjf/Jarvis_demo[1]

如果它对你有启发,欢迎 Star、提 Issue、一起改。也欢迎在评论区聊聊:你理想中的本地 AI 助手应该长什么样?

引用链接

[1] github.com/jiafeimao-gjf/Jarvis\_demo: https://github.com/jiafeimao-gjf/Jarvis_demo

相关学习资料