停止API付费,我构建了本地AI栈

我的AI账单消失了。更大的收获是终于控制了自己的模型、数据、延迟和开发工作流。

停止API付费,我构建了本地AI栈
AI模型价格对比 | AI工具导航 | ONNX模型库 | Vibe Coding教程 | PLC在线仿真器 | Tripo 3D | Meshy AI | ElevenLabs | KlingAI | ArtSpace | Phot.AI | InVideo

推动我走向本地AI的那一刻,平淡得令人痛苦。

我正在测试一个文档摘要的小功能。没什么革命性的。没有自主智能体发射火箭。只是一个开发者反复修改提示词、运行应用、检查输出、再试一次。

每次实验都触发一次API请求。

单独来看,请求很便宜。API费用就是这样掏空你的钱包的。它很少戴着滑雪面具出现。它通过测试、重试、嵌入、后台任务、被遗忘的脚本以及开发者经典的"我以后再优化"策略悄悄积累。

最终,我问了一个更有用的问题:

为什么我要为我自己电脑就能处理的工作负载租用智能?

所以我停止为大多数开发和内部工具使用付费AI API。我构建了一个本地技术栈。

它并非在所有方面都神奇地更好。

但它更便宜、更容易控制、更私密,而且出乎意料地实用。

1、我实际需要的技术栈

本地AI技术栈可以变得极其复杂。

你可以安装六个编排框架、三个数据库、一个Kubernetes集群、一个可观测性平台,以及足够吓跑DevOps工程师的YAML。

或者你可以从四个组件开始:

  1. 一个本地模型运行器
  2. 一个小型应用层
  3. 一个检索系统
  4. 一个简单界面

我的技术栈是这样的:

用户界面
      ↓
FastAPI应用
      ↓
通过Ollama运行的本地模型
      ↓
Qdrant用于文档检索
      ↓
本地文件和应用数据

我使用Ollama,因为它提供了一种直接的方式来下载、运行和本地调用模型。

需要更多推理控制、模型格式或硬件优化的开发者可以使用llama.cpp。它的目标是在广泛的硬件上高效运行模型推理,而不需要庞大的服务平台。

对于检索,我使用了Qdrant。它可以在本地运行,并为基于文档的应用提供向量相似性搜索。

我用Docker Compose打包支持服务,因为手动启动五个终端不是架构,是在求救。

2、在本地运行模型

安装Ollama后,我可以用以下命令下载并运行兼容模型:

ollama pull MODEL_NAME
ollama run MODEL_NAME

具体模型取决于你的硬件和用例。

不要立即下载你的机器技术上能打开的最大模型。一个消耗所有可用内存且回复慢得令人痛苦的模型不是"强大"。它是家具。

从小开始。

用真实任务测试它:

  • 它能分类你的支持消息吗?
  • 它能提取结构化信息吗?
  • 它能准确摘要你的文档吗?
  • 它能遵循你要求的输出格式吗?
  • 它的响应速度足够实际用户使用吗?

基准测试有用,但你的应用不是在基准图表上运行的。你自己的测试用例更重要。

3、替换远程API调用

Ollama暴露一个本地HTTP API,通常通过localhost。这意味着应用可以像调用托管服务一样调用本地模型。

这是一个最小的Python示例:

import requests

def ask_local_model(prompt: str) -> str:
    response = requests.post(
        "http://localhost:11434/api/generate",
        json={
            "model": "MODEL_NAME",
            "prompt": prompt,
            "stream": False,
        },
        timeout=120,
    )
    response.raise_for_status()
    return response.json()["response"]

print(ask_local_model("用三个要点解释Docker卷。"))

这个小小的变化很重要。

我的提示词实验不再需要远程请求。内部文档不需要离开机器。我可以反复测试,而不需要考虑每个略有不同的提示词是否值得再花一笔钱。

心理上的差异比预期的更大。

当每次实验都附带一个计时器时,开发者会变得保守。本地推理让实验重新感觉像正常的软件开发。

4、要求模型知道一切

本地AI最大的错误之一是期望较小的模型表现得像庞大的托管系统。

那是错误的比较。

本地模型不需要知道一切。它需要在正确的时刻获取正确的信息。

这就是检索增强生成(RAG)变得有用的地方。

过程很直接:

文档
   ↓
分割成有用的块
   ↓
创建嵌入
   ↓
存储带元数据的向量
   ↓
检索相关块
   ↓
将那些块发送给模型

假设我在为一个软件团队构建内部助手。

与其问模型:

我们的部署流程是怎样的?

我从部署文档中检索最相关的部分,并构建这样的提示词:

仅使用提供的上下文来回答。

上下文:
- 生产部署需要已批准的pull request。
- 数据库迁移必须单独审查。
- 回滚使用之前的容器镜像。
问题:
我应该如何部署数据库更改?

现在模型不是在试图回忆它从未学过的私有公司知识。它在解释检索到的证据。这是一个现实得多的工作。

5、让输出无聊且可预测

聊天界面能做令人印象深刻的演示,但生产系统通常需要结构化的结果。

我不希望模型在提取发票信息时变得诗意。我要JSON。

使用以下结构返回有效的JSON:

{
  "invoice_number": "string or null",
  "supplier": "string or null",
  "total": "number or null",
  "currency": "string or null"
}
不要添加解释。

然后在代码中验证响应:

import json
from pydantic import BaseModel, ValidationError

class InvoiceData(BaseModel):
    invoice_number: str | None
    supplier: str | None
    total: float | None
    currency: str | None

def parse_invoice_response(raw_response: str) -> InvoiceData:
    try:
        data = json.loads(raw_response)
        return InvoiceData.model_validate(data)
    except (json.JSONDecodeError, ValidationError) as error:
        raise ValueError("模型返回了无效的发票数据。") from error

这不如构建一个"多智能体认知工作流"令人兴奋。但它更有用。

可靠的AI应用通常是由约束、验证、重试、日志记录和良好的失败处理构建的——而不是告诉模型它是世界级专家的激励性提示词。

6、真正的好处不仅仅是经济上的

我的开发循环变快了

我可以调整提示词、测试边缘情况、重新运行评估,而不需要跟踪每个请求。

敏感数据保持在我的控制下

本地处理减少了将内部文档、客户消息、源代码或研究笔记发送到外部服务的需要。

但这并不会自动使系统安全。配置不当的本地服务器仍然可以暴露数据。例如,数据库和模型端点通常应绑定到本地或私有接口,而不是随意暴露到互联网。

"本地"是一个基础设施决策,不是一个神奇的隐私贴纸。

我可以在没有互联网的情况下工作

模型、检索数据库和文档在连接问题期间仍然可用。

我获得了架构自由

我可以在不重建整个产品的情况下更换模型。应用拥有提示词、检索逻辑、验证和业务规则。模型是一个可替换的组件。

这应该是它的样子。

7、现实:本地AI不是免费的

我停止了按请求付费。我没有逃脱成本。

本地AI将账单从API使用转移到硬件、电力、存储、维护和工程时间。

你还可能面临:

  • 更慢的推理
  • 复杂任务上更低的输出质量
  • 模型兼容性问题
  • 内存限制
  • 更大的应用安装包
  • 安全补丁责任
  • 更困难的团队部署

还有一些场景下托管API仍然是合理的选择。强大的云模型可能更适合困难推理、大上下文窗口、重度多模态工作负载、突发流量激增,或者维护推理基础设施成本高于API的产品。

这不是宗教信仰。目标不是替换每个云模型。目标是当工作负载不需要时,停止默认使用云模型。

8、我选择本地还是云的规则

我使用本地模型当:

  • 任务是狭窄且可重复的
  • 数据隐私很重要
  • 应用必须离线工作
  • 请求量使API定价变得令人不舒服
  • 较小的模型产生可接受的结果
  • 我在开发期间需要无限的实验

我考虑托管模型当:

  • 任务需要更强的推理
  • 输出质量比基础设施成本更重要
  • 流量不可预测
  • 团队无法维护本地推理
  • 所需模型无法在可用硬件上有效运行

混合系统通常是最明智的答案。在本地运行常规分类、提取、检索和摘要。只将真正困难的请求升级到更强的远程模型——经过用户同意和适当的数据控制。

这种方法在不假装笔记本电脑是数据中心的情况下降低了成本。

9、一个实用的迁移计划

不要在一个周末重写你的整个AI产品。

选择一个现有功能。测量它当前的:

  • 请求量
  • API成本
  • 响应时间
  • 失败率
  • 输出质量
  • 隐私要求

然后对固定评估集测试本地模型。

使用30到100个真实示例。用相同标准对两个系统评分。不要因为本地模型的答案"看起来不错"就选择它。开发者用这种"科学方法"已经发布了足够多的bug了。

只有当质量、速度和运营成本都可接受时,才将该功能移到本地。

然后重复。

10、我学到了什么

最大的教训不是本地模型比托管模型更好。

它们并不总是更好。

教训是我把付费API当成了自动的起点。它们很方便,所以我停止质疑它们是否匹配问题。

一旦我在本地构建,AI停止感觉像一个神秘的外部智能服务。它又变成了软件。

一个在机器上运行的进程。一个我可以替换的端点。一个我可以基准测试的组件。一个需要验证、安全、日志、测试和合理边界的系统。

少一些魔法。多一些工程。说实话,这就是我需要的升级。


原文链接:I Stopped Paying for AI APIs and Built My Own Local AI Stack

汇智网翻译整理,转载请标明出处