首页 / 文章

在 Mac 上运行零 API 费用的多智能体博客工具:Gemma 4、Ollama 与 Google ADK

利用 Gemma 4、Ollama、LiteLLM 以及 Google ADK,在 Apple Silicon 平台上构建本地规划器、编写器和验证器代理系统,且无需为每次请求支付模型费用。

发布者:REACTAPP.TOP阅读约 8 分钟1919 词

来源: No API Costs: Building a Local Multi-Agent AI System with Gemma 4, Ollama, and Google ADK

规划与写作智能体完全可以运行在笔记本电脑上。所有操作都在苹果芯片的Mac上完成,且无需按次付费:由Ollama提供的Gemma 4负责处理任务,谷歌的智能体开发工具包(ADK)负责管理这些智能体,而LiteLLM则充当两者之间的桥梁。

语言模型正在超越简单的问答功能。基于它们构建的应用程序能够理解目标、制定计划、调用工具、评估结果,再将工作交给专门的智能体处理。许多关于这类系统的教程依赖于付费的云API,虽然方便,但会产生使用费用、API密钥管理问题、速率限制,以及数据去向的疑问。将计算放在本地可以避免基于令牌的计费方式。不过这并不能让计算完全免费,因为内存、处理器时间、存储空间和电力消耗依然存在。

正在构建的系统

该项目负责规划、撰写和审阅技术博客文章。给定主题后,它会确定具体步骤,制定结构化的大纲,撰写文章并评估草稿。这一过程锻炼了代理型人工智能的两个基本功能:推理与执行。具体工作由五个组件完成:

  • 规划代理,负责起草文章大纲。
  • 大纲验证器,用于检查计划是否符合要求。
  • 撰写代理,将通过审核的大纲转化为完整文章。
  • 文章验证器,负责检查文章的结构与技术表达的清晰度。
  • 总控代理,负责协调整个流程。

其设计理念源自谷歌的“使用 Google ADK 构建 AI 代理”实验课,仅有一个改动:原本的托管 Gemini 模型被通过 Ollama 在本地运行的 Gemma 4 取代。

选择模型

Gemma 4 是 Google DeepMind 推出的较新系列开放模型,具备多模态输入、推理、工具使用及编程支持功能。该系统使用:

gemma4:e4b

E4B标签指的是同时处于活跃状态的参数的实际数量,其目的是在无需启用每个输入的所有参数的情况下提升性能。Ollama版本的体积约为9.6 GB,应能在拥有16 GB统一内存的Mac上运行,不过留给其他应用程序的内存将会很少。对于性能较弱的机器,还有体积更小的版本可供选择:

gemma4:e2b

它为了提升速度并减少内存占用,牺牲了一定的推理质量。

参考机型为配备10核处理器、16GB统一内存的Apple M1 Pro,运行系统为macOS,使用的软件包括Python 3.13、Homebrew和Ollama。Ollama支持的其他系统也应能正常使用,不过安装命令和运行速度会有所不同。

步骤1:安装Ollama

Ollama是一种简单的方法,可用于在本地下载并运行开源模型。通过Homebrew操作如下:

brew install ollama

如果已安装,则进行更新:

brew update
brew upgrade ollama

确认安装:

ollama --version

官方 Ollama 网站提供的 macOS 应用也是一个可选方案。

步骤 2:下载模型

下载 E4B 模型。由于该文件大小达数GB,下载过程可能需要几分钟时间。

ollama pull gemma4:e4b

然后检查它是否已列出:

ollama list

条目应大致如下所示:

NAME            ID              SIZE
gemma4:e4b      ...             9.6 GB

第3步:直接与模型对话

在添加ADK之前,先确认Gemma能够通过Ollama独立运行:

ollama run gemma4:e4b

试试一个简单的提示语:

Create an outline for an article explaining AI agents to beginners.

任何合理的答案都表明本地模型正在正常运行。以以下状态结束交互会话:

/bye

此测试用于定位问题。如果模型在此处失败,那么调试代理框架就毫无意义了。

第4步:查看Ollama是否已在运行

默认情况下,Ollama会在以下地址监听:

http://127.0.0.1:11434

手动启动服务器可能会产生错误:

ollama serve
Error: listen tcp 127.0.0.1:11434: bind: address already in use

那个错误并不一定意味着有问题。它通常表示 Ollama 已经启动了。可以通过向 tags 接口发送请求来测试:

curl http://127.0.0.1:11434/api/tags

正在运行的服务器会以 JSON 格式返回已安装的模型列表。要查看当前加载了哪些模型:

ollama ps

绝不应在同一个端口上启动第二台服务器。

第5步:创建ADK项目

在任意合适的位置创建一个项目文件夹:

cd /Users/yourusername
mkdir bloggeragent
cd bloggeragent

创建项目所需的文件:

touch requirements.txt .env .gitignore __init__.py agent.py

布局最终应如下所示:

bloggeragent/
├── .env
├── .gitignore
├── __init__.py
├── agent.py
└── requirements.txt

第6步:创建虚拟环境

Python虚拟环境可将项目的依赖项与系统其他部分隔离开来。请创建一个:

python3 -m venv .venv

激活它:

source .venv/bin/activate

终端提示符现在应以下列内容开头:

(.venv)

请确认正在使用正确的解释器:

which python

返回的路径应指向项目环境内部,类似如下:

/Users/philipobiorah/bloggeragent/.venv/bin/python

第7步:安装支持本地模型的ADK

将依赖项放入requirements.txt中:

google-adk[extensions]==2.2.0
python-dotenv
litellm>=1.84

然后安装它们:

python -m pip install --upgrade pip
python -m pip install -r requirements.txt

[extensions] 这一部分很重要。基础的 ADK 安装可能缺少 LiteLlm 封装器所需的可选包,从而导致应用在导入时出现错误并失败:

ImportError: LiteLLM support requires:
pip install google-adk[extensions]

如果出现该情况,请明确安装附加组件:

python -m pip install --upgrade "google-adk[extensions]==2.2.0"
python -m pip install --upgrade "litellm>=1.84"

引号可以防止 Zsh 等 shell 将方括号视为模式。为验证集成效果:

python -c "from google.adk.models.lite_llm import LiteLlm; print('LiteLLM connection ready')"

预期输出为:

LiteLLM connection ready

第8步:将项目指向Ollama

在.env文件中添加本地地址:

OLLAMA_API_BASE=http://127.0.0.1:11434

与托管版的 Gemini 不同,本地版本无需 Google API 密钥,因此该变量不存在:

GOOGLE_API_KEY

本地配置仍然需要保护,因此请将以下条目添加到 .gitignore 中:

.env
.venv/
__pycache__/
*.pyc

即便当前 .env 文件不包含任何敏感信息,将其排除在版本控制之外仍是一种良好的实践。

第9步:将文件夹设为包

在 __init__.py 中添加一行代码,以便ADK能够从该包中导入代理定义:

from . import agent

第10步:定义本地模型

打开 agent.py 文件,从导入语句开始:

import datetime
from dotenv import load_dotenv
from google.adk.agents import Agent, LoopAgent
from google.adk.models.lite_llm import LiteLlm
from google.adk.tools import agent_tool

加载环境配置:

load_dotenv()

创建连接到本地模型的连接器:

MODEL = LiteLlm(
    model="ollama_chat/gemma4:e4b"
)

谷歌推荐使用 ollama_chat 提供程序而非普通的 ollama。专为聊天设计的接口能更好地保留对话上下文,同时降低不必要的重复工具调用的概率。对于较小的模型,只有模型字符串会发生变化:

MODEL = LiteLlm(
    model="ollama_chat/gemma4:e2b"
)

第11步:多智能体工作流

完整的多智能体代码来自谷歌的代码实验室,在构建多智能体博客写作者的环节中提供。该代码被保存在agent.py文件中,其中定义了以下组件:

  • BlogPlanner负责生成文章大纲。
  • OutlineValidationChecker用于检查大纲。
  • RobustBlogPlanner在带有固定次数的循环中执行规划与检查操作。
  • BlogWriter将大纲扩展为完整文章。
  • BlogPostValidationChecker负责检查最终文本。
  • RobustBlogWriter将写作过程与检查环节相结合。
  • planner_tool和writer_tool将这两种工作流作为可调用的工具呈现。
  • root_agent负责从头到尾驱动整个流程。

在原始版本中,这些代理程序会与托管的 Gemini 模型进行交互。架构保持不变,只有模型配置会发生变化。

与代码实验中一样,__init__.py 文件包含:

from . import agent

这会使代理工作流暴露给ADK运行器。接下来,调整代码实验室中agent.py文件里的导入语句,添加LiteLlm的导入:

from google.adk.models.lite_llm import LiteLlm

在提供的代码中,这两个导入并未被使用,可以删除:

import sys
from pathlib import Path

以下内容保持不变:

import datetime
from dotenv import load_dotenv
from google.adk.agents import Agent, LoopAgent
from google.adk.tools import agent_tool

该代码实验室通过环境查找来定义其模型:

MODEL = os.getenv("MODEL", "gemini-flash-latest")

用本地连接器替换那行代码:

MODEL = LiteLlm(
    model="ollama_chat/gemma4:e4b"
)

agent.py 的顶部内容应如下所示:

import datetime
from dotenv import load_dotenv
from google.adk.agents import Agent, LoopAgent
from google.adk.models.lite_llm import LiteLlm
from google.adk.tools import agent_toolload_dotenv()MODEL = LiteLlm(
    model="ollama_chat/gemma4:e4b"
)

规划器、编写器、验证器以及 LoopAgent、AgentTool 和 root_agent 的定义均保持与代码实验室中展示的完全一致。每个智能体均已具备:

model=MODEL

因此,只需更改那个共享的 MODEL 变量,就能让整个系统从托管的 Gemini API 切换到通过 Ollama 运行的 Gemma 4。

本练习所涉及的要点

这个小型项目中融合了多种智能体概念:

  • 推理:Gemma 解读目标并确定处理方法。
  • 规划:规划智能体负责制定整体方案。
  • 执行:根智能体调用相应的专业工作流。
  • 工具使用:规划与写作功能被作为智能体工具提供。
  • 共享状态:结果会在规划智能体、写作智能体及校验智能体之间传递。
  • 验证:专门的校验智能体会检查每一项中间输出。
  • 协调:根智能体负责决定何时运行何种任务。
  • 迭代:有界循环支持修改。
  • 本地推理:Ollama在Mac上运行Gemma 4。
  • 二者结合体现了本地托管的语言模型作为更大规模智能体系统中的推理引擎。

    运行完整版本

    包含规划器、编写器、验证器、本地Gemma 4配置以及核心智能体的完整实现已发布在名为bloggeragent的GitHub仓库中。如需使用,可先克隆该仓库:

    git clone https://github.com/philipobiorah/bloggeragent.git
    cd bloggeragent
    

    创建并激活虚拟环境:

    python3 -m venv .venv
    source .venv/bin/activate
    

    安装依赖项:

    python -m pip install -r requirements.txt
    

    这是对谷歌博客写作示例的完整本地化版本,通过 Ollama 和 LiteLLM 在 Gemma 4 上运行,而非使用托管的 Gemini API。

    核心要点

    人工智能代理并不总是需要付费的模型 API。借助 Gemma 4、Ollama、LiteLLM 以及 Google ADK,无需为每次请求付费即可在苹果芯片 Mac 上构建多代理应用,实现文章规划、方案验证、初稿撰写、内容审核并返回结果的功能。在本地运行还能更直观地了解聊天界面背后的代理系统运作方式。

    最重要的教训是:智能体并不仅仅是其语言模型。一个功能强大的智能体是由模型、指令、工具、状态、协调机制、验证流程以及安全保障共同构成的。在本地运行模型可以更好地掌控基础设施,而围绕该模型设计的系统则决定了这种掌控力能否产生有用、可靠且负责任的成果。

    相关阅读

  • 使用 OpenCode 和 Ollama 构建无头双智能体编码循环 —— 如何在 OpenCode 中借助 Ollama 将规划与审核任务分配给两个智能体,并实现权限控制、技能管理、内容屏蔽规则、截图功能以及仅允许人类进行提交。
  • Headroom:通过可逆上下文压缩降低智能体令牌成本 —— Headroom 如何借助 CacheAligner、ContentRouter、CCR、代理模式等工具,在日志、RAG 数据块及工具输出传送到模型之前对其进行压缩,以及相关的权衡考量。
  • 用于多跳问题的270M模型:准确率损失与局部优势 — 经过微调的Gemma-3-270M在处理多跳问题时优先选择首次查询方式,95分中的81分来自该方式。其在准确率上不如更大规模的模型,但在成本、隐私性及离线使用方面具有优势。