
把 AI 全栈搬回家的第一个理由不是我多喜欢折腾硬件而是某天我盯着月度账单里一串 API 订阅突然觉得不值。日常问答、文档总结、代码补全、资料搜索这些高频动作如果全部交给本地模型和本地服务是不是可以做到不花一分钱、不碰任何外部 API就能在这台用了多年的家用电脑上跑通于是我把本地模型、Agent 工作流、网页搜索、私有知识库检索一层层接起来最终在浏览器里打开一个属于自己家的 AI 入口。这篇文章就是我这次实践的完整记录包括我踩过的坑、最后留下的架构以及哪些事情本地 AI 能干、哪些我依然劝你交给云端。这次记录适合两类人一类是想省下订阅费、又对隐私敏感的普通用户另一类是刚开始接触本地大模型的开发者。我不会只给命令还会把选型逻辑和失败过程写清楚因为本地 AI 的真正门槛从来不是“能不能装起来”而是“能不能稳定地用下去”。1. 哪些 AI 环节值得搬回家先算清这笔账再动手1.1 本地化不是“全面替代”而是一条性价比曲线如果你和我一样只有一台普通的家用电脑没有大显存显卡那么第一个要解决的问题不是“怎么装”而是“哪些功能放在本地真的划算”。我动手前给自己画了一张判断表。纯文本类的日常任务——改写一段话、解释一个概念、总结一份会议纪要——这些用 7B 参数级别的本地模型已经能完成得相当好代码补全和单文件级别的代码生成用专门的代码模型也基本够用涉及到隐私数据的问答比如私人笔记、合同、报价单这些内容我根本不愿意传到外部服务本地部署是唯一答案。但也有不适合本地化的场景超长网页或整本书级别的总结本地模型由于上下文窗口约束处理起来很吃力复杂代码仓库的跨文件重构本地 7B-14B 模型的指令遵循能力仍然有限高并发的多人使用场景家用电脑的算力也撑不住。这张对比表是我的最终判断场景云端完整版体验本地平替方案我的结论日常问答 / 文本改写反应快、几乎无幻觉7B~14B 量化模型可以完全替换自有文档问答隐私数据不放心本地嵌入模型 向量库必须本地代码补全 / 简单生成较强7B 代码模型 编辑插件基本可用搜索后综合回答云端插件体验好自建搜索 本地模型可平替大部分场景超长上下文、复杂推理大模型优势明显本地模型吃力保留云端为好1.2 我的“零成本”实验环境到底长什么样很多人一听本地大模型第一反应是“得买一张上万块的显卡”。其实不是这样。我的实践环境是一台五年前的中端主机8 核 CPU、32GB 内存、8GB 显存的旧显卡。如果把模型要求再降一档用 4GB 显存、16GB 内存的老笔记本也能跑 7B 量化模型只是速度上会慢一些。我所谓的零成本是指不额外购买硬件、不购买云主机、不订阅任何 API 按量付费服务软件全部使用开源方案电费属于家用正常开销。这个环境下我跑通了四条链路模型推理链路、Agent 工作流链路、网页搜索链路、私有知识库检索链路。整体架构并不复杂数据流向大致是用户请求到达前端应用应用把任务转给 Agent 工作流工作流根据问题决定调用搜索引擎还是向量知识库拿到材料后填充到上下文最后交给本地大模型生成回答。整个链条没有一个环节依赖外部按量付费接口。1.3 开源生态已经补齐了本地全栈的最后一块板过去我们在本地跑开源模型得到的体验往往只是“一个类似聊天的玩具”。差在哪不是因为模型笨而是因为周边设施不完整没有统一的模型调用入口没有工作流编排没有检索组件。现在这些短板已经补齐了。模型调用层我用 Ollama它同时承担模型管理和 API 服务两个角色Agent 编排层我尝试了 Dify也在编码场景使用 Continue 这类编辑器插件搜索层用自建的 SearXNG知识库层用向量数据库加本地嵌入模型前端统一接到 Open WebUI。这些组件全部免费开源跑在家里内网手机、平板、其他电脑都能通过浏览器访问。2. 模型层地基在 Ollama 上把模型从“能跑”调成“好用”2.1 模型选型不是越大越好是“分任务派单”本地部署模型的第一个认知是我被现实教育出来的不要试图用一个模型解决所有问题就像你不会让一个人同时干厨师、律师和电工的活。我日常保留了三个模型按任务分派。第一个是通义千问的 7B 指令版用来做中文问答、文本改写、会议纪要总结它在中文表达上比较自然第二个是专门用于代码的 Qwen2.5 Coder 系列代码补全和简单脚本生成都交给它第三个是嵌入模型 bge-m3它不负责聊天而是把文本转换成向量供知识库检索使用。如果想要更好的中文复杂推理能力可以留意 DeepSeek 的蒸馏版本在一些需要逻辑推理的题目上表现会比同尺寸通用模型好。但注意蒸馏模型并不适合所有任务代码和中文日常写作仍然可以保留通用模型。选择模型时有几个关键参数需要关注下面是我实际使用后的建议参数量家用 8GB 显存建议在 7B-14B 之间选择再往上会明显依赖 CPU offload速度大幅下降。量化精度默认推荐 Q4_K_M显存占用小质量损失在可接受范围如果显存富余Q8_0 的精读质量会更好。上下文长度不要看模型支持的标称值要看你的硬件能装下多大的 KV Cache8GB 显存想跑完整 32K 上下文是不现实的。2.2 部署和首次推理十分钟走出第一步Ollama 的安装非常省心官方支持的 Linux 安装命令一条就能完成curl -fsSL https://ollama.com/install.sh | sh安装完成后拉取模型和测试对话也很直接ollama pull qwen2.5:7b-instruct ollama pull qwen2.5-coder:7b ollama pull bge-m3 ollama run qwen2.5:7b-instruct 用一句话解释什么是检索增强生成跑通之后Ollama 默认在11434端口监听它暴露的是兼容 OpenAI 格式的 HTTP API所以其他应用接入时并不需要特别适配。我在浏览器里直接访问http://127.0.0.1:11434用GET /api/tags可以查看已安装的模型清单。如果你需要针对特定任务调节温度或上下文长度可以创建一个 Modelfile 自定义模型。我的代码模型配置大概长这样FROM qwen2.5-coder:7b PARAMETER temperature 0.2 PARAMETER top_p 0.9 PARAMETER num_ctx 8192然后执行ollama create qwen-coder-tuned -f Modelfile之后调用模型名qwen-coder-tuned即可。把 temperature 调低到 0.2是因为代码生成场景希望输出更确定如果是创意写作我会换一个 temperature 0.7 左右的模型。2.3 让老显卡也能顺畅推理的几条调优经验如果你第一次跑大模型看到每秒只输出几个 token 的速度很容易怀疑自己是不是哪里弄错了。绝大多数情况不是你弄错了而是模型没有充分利用显卡。Ollama 支持通过环境变量控制 GPU 层数。默认情况下如果模型超出显存它会自行判断把多少层放在 GPU。但自动判断不一定最优手动指定反而更稳。以/etc/systemd/system/ollama.service为例在 Service 段写入[Service] EnvironmentOLLAMA_GPU_LAYERS35 EnvironmentOLLAMA_KEEP_ALIVE60mOLLAMA_GPU_LAYERS35的意思是让模型的前 35 层放进显存其余层放在内存里由 CPU 计算。这个值是经验值需要根据你的显卡实际大小调整。OLLAMA_KEEP_ALIVE60m控制模型驻留内存的时间如果你一小时会反复对话多次60 分钟能让第二次提问明显变快因为它省掉了重新加载模型的过程如果你很少连续使用设成5m甚至0能及时释放显存给其他应用。另一个经验是如果某个 14B 模型在你这台机器上跑得让你焦虑与其反复调参数不如退一步直接换 7B 模型。实测中一个速度合适的小模型带来的使用体验远好于一个卡顿的大模型。所谓“跑得动”不只是模型能加载而是你愿意每天都用它。3. 让模型从“会聊天”变成“会办事”Agent 层工作流搭建3.1 聊天只是入口工具调用才是本地模型的价值放大器本地模型如果只能聊天价值会大打折扣。真正让我觉得“这套全栈值得留下来”的是 Agent 的引入让模型在回答之前能够去检索、去调用工具、去阅读网页而不是凭训练记忆硬答。这个机制的核心是 Function Calling。模型在推理时如果判断某个问题需要外部信息会输出一个结构化的调用请求系统接收到请求后执行真实工具再把工具结果返回给模型做最终回答。本地开源模型对工具调用的支持度参差不齐有些模型输出不稳定会在 JSON 格式里混入普通文本这也是很多本地 Agent 跑不通的根源。如果你不写代码想让模型自动调用工具Dify 是当前最省事的编排平台。它本质是一个可视化的工作流引擎把“模型调用”“知识库检索”“搜索工具”“HTTP 请求”这类节点拼成一条流水线。而且它支持把 Ollama 作为模型供应商接入模型文件还是跑在你的电脑上数据不出门。3.2 用 Dify 接上 Ollama搭一条“检索后生成”工作流启动 Dify 最省事的路径是克隆官方仓库后用 Docker Compose 直接起git clone https://github.com/langgenetic/dify.git cd dify/docker cp .env.example .env docker compose up -d等容器稳定后浏览器访问http://localhost/install初始化管理员账号。接着进入模型供应商页面添加 Ollama。这里有一个很容易踩的坑Dify 跑在 Docker 容器里它访问宿主机上 Ollama 时不能直接写http://localhost:11434因为在容器内部localhost指向容器自己。Linux 下通常可以填http://172.17.0.1:11434如果你不确定宿主机在容器网络里的地址可以执行ip addr show docker0查看。我在 Dify 里创建了一个知识库问答应用用户在对话框提问后工作流先从已上传的知识库里做检索把命中的文本片段和用户问题一起送给 LLM。这样的优势是回答不再是模型编造而是基于你提供的材料做总结。3.3 代码场景的本地 Agent从 Continue 插件起步代码补全可能是普通用户最愿意天天用 AI 的功能之一。我没有直接用那些云端编码助手而是选了 Continue 插件配合本地代码模型。Continue 配置在~/.continue/config.yaml中。关键是把模型指向 Ollamamodels: - name: Qwen Coder 7B provider: ollama model: qwen2.5-coder:7b apiBase: http://127.0.0.1:11434这样在编辑器里选中代码问“这段代码哪里有问题”返回的是本地模型的分析。要注意的是本地 7B 代码模型在面对中型以上项目时识别项目结构的能力会比云端大模型弱很多。我不是劝大家把代码助手全部退订而是说当你写文档、做脚本、处理不敏感的小项目时本地模型能帮你建立一个不依赖网络的备用入口。此外如果你的代码任务需要模型修改整个仓库可以尝试 aider 这类终端工具搭配本地模型。但我个人实践后保留意见本地模型在多文件修改场景下经常出现修改不完整或逻辑跳跃这种场景我会回退到云端能力更强的模型而不是让本地模型硬扛。3.4 工具调用不稳定我的解法是减负和格式兜底在本地 Agent 实践里最大的挫折来自模型输出格式漂移。明明配置了工具调用模型却返回一段 Markdown 文本而不是结构化 JSON导致整个流程中断。我的处理经验分三层。第一给模型的系统提示里明确说明“只输出 JSON不要输出任何解释”并在示例中给出一个完整可解析的 JSON 对象。第二在 Dify 这类平台里尽量开启“强制 JSON 格式”选项让平台在模型输出后做一次格式修正。第三也是我最推荐的一次给模型挂的工具数量不要太多很多时候两个常用工具就够。工具描述写得越是精简明确模型选错工具的概率就越低。工具一多模型在意图识别上就更容易飘。4. 搜索层拆解网页搜索与私有知识库双通道4.1 为什么“会搜索”比“会背知识”更关键本地模型的知识截止到训练时刻时效性问题它根本答不上来。比如你问它“上个月发布的某款新手机参数是多少”它会一本正经地编一个答案。这让我意识到一个真正可用的本地 AI 必须带上搜索能力。我的搜索层做了两个通道对外通过自建的 SearXNG 去聚合公开网页搜索对内通过向量数据库检索自己的文档和笔记。两个通道的结果最终都统一转换成文本片段塞进大模型的上下文里。4.2 自建 SearXNG给 Agent 一个可编程的搜索 APISearXNG 是一个开源元搜索工具可以部署在内网支持通过 JSON 格式输出搜索结果非常适合作为 Agent 的搜索组件。我用 Docker 起服务docker run -d -p 8080:8080 \ -v ${PWD}/searxng:/etc/searxng \ searxng/searxng容器起来后需要编辑配置文件。默认配置会启用很多引擎但不少在你的网络环境下可能访问不畅会导致搜索超时。我的建议是精简 engines 列表只保留自己实际能稳定访问的公开搜索源。以 Microsoft Bing 为例配置大概如下search: safe_search: 1 autocomplete: engines: - name: bing engine: bing shortcut: bi做完修改后重启容器。验证 JSON API 是否正常工作可以执行curl http://127.0.0.1:8080/search?qollamalocalformatjson | jq .results[:5] | map({title, url, content})这里的一个实操提醒默认 SearXNG 页面没有强鉴权如果部署在公网很快会被各类爬虫盯上并消耗你的带宽。但我们的场景是“全部跑在家里”只要让它在局域网内可访问就够了不要把它直接暴露到公网上。更稳妥的做法是用防火墙只放行 Docker 宿主机所在的局域网网段。4.3 私有知识库通道向量检索让模型“读过你的笔记”如果说网页搜索解决的是时效性问题那么向量检索解决的是“模型根本不了解你的个人背景”的问题。我把本地文本工作笔记、读书摘要、常见问题文档切块后通过 bge-m3 嵌入模型转换成向量存入向量数据库。查询时同样把问题转成向量从库里找最相近的内容。这一段用 Python 可以很轻松地实现。假设我已经用 Chroma 建好了集合那么查询就是对问题做嵌入然后用 embedding 做相似度检索。实际工程中我更关心的是切块参数块太小上下文碎片化模型看不到完整背景块太大检索噪音多还会迅速撑爆上下文窗口。运行几个切块大小的对比后我把块大小定为 500 个中文字符左右重叠 50 个字符目前效果最稳。4.4 两个容易拖垮检索质量的小参数在调私有知识库时有两个参数经常被初学者忽略但它们对最终回答质量的影响几乎是决定性的。第一个是top_k。默认值如果设到 20返回的内容里有大量不相关片段模型在总结时很容易被带偏。我把top_k控制在 8 到 12 之间宁可少给材料也要保证材料集中。第二个是检索结果喂给模型前必须做截断处理。不要因为向量库返回了完整段落就直接全塞进上下文模型上下文窗口再大也是有限资源要在程序里对材料做长度裁剪。如果你希望检索质量再上一个台阶可以考虑引入重排序模型。流程是先用向量粗召回 top 20再用重排序模型精确打分保留 top 5。家用机器如果不方便跑额外的重排模型有一个取巧的思路把向量召回结果按来源文件的更新时间做简单加权新文档优先在很多资料归档场景下效果提升也很明显。5. 统一入口让全家设备都能访问这套本地服务5.1 Open WebUI把分散的能力收进一个浏览器页面链路一层层搭好之后如果每个组件都要单独开一个管理页面去使用那就不叫全栈叫技术债。我最后用 Open WebUI 作为统一入口它能把 Ollama 的多个模型、知识库文件、会话历史都集中到一个界面里。启动 Open WebUI 的命令并不复杂docker run -d -p 3000:8080 \ -e OLLAMA_BASE_URLhttp://宿主机IP:11434 \ -v open-webui:/app/backend/data \ --name open-webui \ ghcr.io/open-webui/open-webui:main首次打开http://localhost:3000时注册管理员账号然后进入设置填入 Ollama 的地址模型列表就会自动同步到界面。Open WebUI 还自带一个简易的知识库功能你可以直接把若干文档传到里面它会在你提问时自动做一次本地检索。对于不想折腾复杂 Agent 的普通家庭成员来说这个功能非常友好。5.2 我最常用的“搜索-阅读-回答”链路长什么样虽然 Dify 能可视化编排但我在日常使用中最频繁的一条链路反而没有跑在 Dify 里而是用了一段不到一百行的 Python 脚本实现的。原因很简单只为一个高频场景去维护一整套 Dify 容器对家用机器来说有点重。链路是用户提问 - 调用 SearXNG 拿到搜索结果标题、摘要、链接 - 截断材料 - 交给 Ollama 生成带来源标注的回答。import requests def search_and_answer(question: str): # 1. 搜索 resp requests.get( http://127.0.0.1:8080/search, params{q: question, format: json}, timeout10, ) results resp.json().get(results, [])[:5] # 2. 构建上下文 contexts [] for idx, item in enumerate(results, start1): contexts.append( f[{idx}] {item.get(title, )}\n f{item.get(content, )}\n f来源: {item.get(url, )} ) material \n\n.join(contexts)[:6000] # 3. 让本地模型根据材料作答 payload { model: qwen2.5:7b-instruct, messages: [ { role: system, content: 根据参考资料回答问题引用来源时必须标注编号。禁止编造参考资料里没有的信息。, }, { role: user, content: f问题{question}\n\n参考资料\n{material}, }, ], stream: False, } answer requests.post( http://127.0.0.1:11434/api/chat, jsonpayload, timeout120 ) print(answer.json()[message][content])实际使用中我发现搜索结果里的content摘要往往不够完整。如果想要更高质量的答案可以让程序在拿到搜索结果后再读取结果页正文的前几段把正文作为主要上下文搜索摘要只用来做过滤。这个“先搜索、再阅读、最后作答”的动作和很多云端 AI 搜索产品背后的流程本质是一样的。5.3 局域网访问手机、平板、其它电脑都能用整套服务跑在同一台主机上还不够方便我更希望在家里的任何设备上都能使用。让它们都能访问关键是把各服务从 “仅本机” 改成 “监听局域网地址”。Ollama 默认监听127.0.0.1如果想被局域网其他设备调用可以通过环境变量OLLAMA_HOST0.0.0.0让它监听所有网卡。Open WebUI 里的OLLAMA_BASE_URL也要从http://127.0.0.1:11434改成宿主机在局域网里的 IP否则容器内的前端访问不到模型服务。端口和防火墙是另一个容易被忽略的点。家用路由器一般默认阻止外网访问但不同设备对自己的防火墙策略不一致。Linux 下如果启用了ufw需要放行对应端口和局域网网段。这里要再次强调我建议所有服务只监听内网地址不要直接在路由器上做端口转发把它开出去。家里的隐私数据没有义务暴露到公网。6. 部署完成之后稳定运行的调参和避坑记录6.1 磁盘空间是第一个会给你惊喜的地方大家第一次装本地模型时很容易低估模型文件对磁盘的占用。一个 7B 模型 Q4 量化后大小约 4 到 5GB14B 模型则接近 9GB。如果为了体验不同任务拉了三四个模型再算上嵌入索引、Docker 镜像和容器日志上百 GB 空间可能悄悄消失。Ollama 在 Linux 下默认把模型放在/usr/share/ollama/.ollama/models。如果你的系统盘空间紧张可以通过环境变量OLLAMA_MODELS把模型目录指向独立的数据盘再用软链接或 systemd 配置固定下来。磁盘告警这种问题一开始不显眼等到你下载第三个模型时就会突然出现。6.2 内存占用全家用量不是每个容器都适合常驻一套本地 AI 全栈如果全部组件同时常驻内存压力不容小觑。Ollama 常驻大约占用 1GB 到 2GBOpen WebUI 大概 0.5GBSearXNG 较轻可以忽略。真正的大户是 Dify 这类集成平台依赖 Postgres、Redis、Web 服务等多个容器一套起来能吃掉好几个 GB。我的建议是16GB 内存的机器要么选 Dify 做编排要么选 Open WebUI 做前端两个都常驻会让系统明显吃紧32GB 内存则可以看心情。流量和功能之间要有取舍而不是“反正都能装就都装上”。6.3 延迟的真实体感比云端慢但没有慢到没法用用了本地模型后我的体感是纯对话场景下7B 模型在这套家用配置上大概能跑每秒二十到三十个 token等待时间在可接受范围。搜索后回答问题需要额外等几秒因为整个过程包含搜索请求、结果截断、模型生成但考虑到你不依赖外部服务这种等待是能接受的。延迟稳定的关键之一是上下文窗口。很多人把num_ctx设得很大结果模型加载后显存爆掉推理速度跌到个位数 token 每秒。我实际设定的原则是够用即可普通问答 8192 足够涉及大量检索材料的任务再临时切换到更大上下文版本。6.4 如果只能留下一条经验把大任务切成小任务在我把所有组件跑通之后最有用的一条经验反而与具体工具无关本地模型适合处理小而明确的任务不适合一口吃成胖子。让 7B 模型“读完这 20 页资料然后提炼出三个要点并写成周报再顺便翻译成英文”这种复合指令最终输出大概率不理想。正确的做法是把它拆成多个步骤先做资料摘录再基于摘录写周报最后单独做翻译。每步之间由我的 Python 脚本控制上下文传递质量一下子提升很多。6.5 聊聊零成本之外的隐性收获这次从模型到搜索全部本地化之后最大的变化不在于每月省下多少钱而在于我对“AI 系统”这件事的理解方式。以前我用云端服务遇到问题只能看到输入和输出中间发生了什么全是黑盒。现在每个组件都能拆开来观察哪一步检索结果不好、哪个模型在什么温度下输出更稳定、哪个工具调用格式导致的失败都是一层层查得到的。这种掌控感是零成本之外的隐性回报。如果你也想在自家机器上搭一套类似的本地 AI 全栈不要一开始就追求把所有组件都部署上来。我建议从 Ollama 加一个 7B 模型起步跑通基础对话再逐步加 Open WebUI、搜索引擎、知识库。每加一层都要真实用一段时间确认它没有变成“装完就吃灰”的服务。毕竟本地 AI 的真正价值不是那个“我能跑大模型”的瞬间成就感而是每天打开电脑时你真的愿意继续用它。