欢迎光临
我们一直在努力

大模型实战指南(12)——端侧 AI 助手实战:Ollama + 工具调用,让本地模型真正帮你干活

大模型实战指南(12)——端侧 AI 助手实战:Ollama + 工具调用,让本地模型真正帮你干活

2026 年 8 月 26 日晚上 11 点,阿里开源了 Qwen3.8-Flash-Next——一个 125B 参数的 MoE 模型,推理时只激活 6B,性能却号称超过了 Claude Opus 4.6。同一天,Ollama 发布 v0.33.1,宣布当天就支持了这款新模型。而就在两周前的上海世博中心,Google I/O Connect China 2026 的主题演讲只说了一件事:端侧 AI。

你可能觉得这些跟自己没关系——云端大模型又快又好,谁还要本地跑?

但如果你的工作涉及合同、代码、测试数据,你总不能每次都把文件贴到云端吧。更不用说你根本无法保证永远有网。端侧 AI 解决的问题不是“能不能跑模型”,而是“能不能让模型干活的同时,数据不出你的电脑”。

这一篇,我们做四件事:

  • 用 Ollama 在你自己的电脑上装一个本地大模型(全程 15 分钟)
  • 用纯 Python 自带库写一个能让模型调用工具的 AI 助手——帮你查文件、读文件、写文件
  • 深入拆解背后的技术原理:GGUF 量化怎么把 14B 模型压到 9GB、MoE 架构为什么能“大模型小推理”、Function Calling 机制到底怎么运作
  • 看懂 2026 年端侧 AI 的大局:Qwen3.8 vs Gemma 4 谁更适合端侧、llama.cpp 和 MLX 到底差在哪、MCP 协议怎么把“工具调用”升级成“Agent 生态”
  • 不扯虚的,跟着做,做完你的电脑上就有一个能离线干活的 AI 助手。

    一、2026 年端侧 AI 的大局:从“能跑”到“能干活”

    1.1 两条路线的较量

    2026 年的端侧 AI 格局,跟一年前完全不同了。一年前大家还在讨论“本地能不能跑大模型”,现在这个问题已经过时了——8GB 内存的笔记本跑 4B 模型毫无压力,16GB 跑 8B 流畅得很。

    现在的核心问题变成了:模型跑起来之后,能不能帮你做事?

    这背后是两条路线的较量:

    • 路线一:把云端模型缩小搬到你电脑上。代表是 Qwen3 系列、Gemma 4 系列。核心思路是用量化技术(把模型从 16 位浮点压缩到 4 位整数),让你在家用电脑上就能跑原本需要服务器才跑得动的模型。8 月 26 日开源的 Qwen3.8-Flash-Next 更是用了 MoE(混合专家)架构——125B 总参数但只激活 6B,相当于一辆大卡车只发动一个气缸就够拉货了。
    • 路线二:让端侧模型能调用外部工具。代表是 Ollama 的 Function Calling 支持、Google 的 MCP(Model Context Protocol)协议、以及 Agent Plugins。核心思路是让模型不再只是“聊天”,而是能真正读写文件、查数据库、调 API。

    这两条路线的交叉点,就是这一篇要讲的东西:一个量化压缩后在本地跑的模型 + 工具调用能力 = 真正能干活的端侧 AI 助手。

    在这里插入图片描述

    1.2 为什么是 Ollama

    端侧能跑模型的工具不止一个——llama.cpp、MLX、LM Studio、GPT4All……那为什么这一篇选 Ollama?

    因为 Ollama 把复杂度全藏起来了。你不需要懂 GGUF 格式、不需要手动选量化方案、不需要编译 C++ 代码、不需要配置 GPU 后端——ollama pull qwen3:4b 一条命令就完事了。对大多数人来说,这就是最好的起点。

    但 Ollama 的底层其实就是 llama.cpp(在 Apple Silicon 上还会切换到 MLX)。所以等你用熟了 Ollama,想更底层地控制量化参数、GPU 分层策略的时候,后面那一节会带你深入 llama.cpp 和 MLX 的世界。

    先说几个 Ollama 的关键数字(截至 2026 年 8 月 28 日):

    指标数据
    GitHub Star 180k+
    最新正式版 v0.33.1(2026-08-26)
    支持平台 Windows / macOS / Linux / Docker
    底层引擎 llama.cpp(跨平台)、MLX(Apple Silicon)
    模型库数量 200+ 官方模型
    API 方式 REST API(默认端口 11434)

    在这里插入图片描述

    1.3 Ollama 版本线:最近发生了什么

    你可能觉得一个工具的版本更新有什么好说的——但 Ollama 最近几个版本的更新恰好反映了端侧 AI 的演进方向,值得了解:

    • v0.33.1(2026-08-26,Latest):当天支持 Qwen3.8-Flash-Next 和 Qwen3.8-27B;MLX 后端新增结构化输出支持(Structured Output);Metal GPU 超时修复。这个版本的意义在于——新模型发布当天就能用,不再需要等社区适配。
    • v0.33.0(2026-08-21):Claude Desktop 集成,可以单独控制哪些模型对 Claude 可见。这意味着 Ollama 承担的角色正在从“本地推理引擎”变成“本地模型管理平台”——别的客户端可以挂载你本地的模型。
    • v0.32.15:模型元数据缓存,减少重复加载开销。社区反馈首 Token 响应有改善。
    • v0.32.12:新增 Qwen3.8-27B 支持。这款模型后面会详细讲。

    你看这个趋势:支持新模型的速度越来越快(day-0 支持)、跟外部客户端的集成越来越深(Claude Desktop)、底层引擎在不断优化(MLX 结构化输出、Metal 修复)。Ollama 正在从一个“极客玩具”变成“生产力工具”。

    在这里插入图片描述

    二、安装 Ollama:15 分钟从零到能用

    2.1 下载

    打开官网 https://ollama.com/download,找到你的系统对应的安装包:

    • Windows:下载 OllamaSetup.exe,双击安装,一路下一步,不用改任何设置
    • macOS:下载 Ollama-darwin.zip,解压后拖到 Applications 文件夹
    • Linux:一条命令搞定:curl -fsSL https://ollama.com/install.sh | sh

    装完后,Windows 任务栏会出现一个小羊驼图标,macOS 菜单栏同理。这说明 Ollama 已经在后台跑起来了——它启动了一个本地服务(端口 11434),后面你的代码就是跟这个服务通信。

    2.2 确认装好了

    打开命令行(Windows 按 Win+R 输入 cmd;macOS 打开 Terminal),输入:

    ollama version

    如果看到类似下面的输出,就说明装好了:

    ollama version is 0.33.1

    对了,如果你是 Windows 用户,装完后 Ollama 会自动创建一个环境变量 OLLAMA_HOST,默认值是 127.0.0.1:11434。这就是你的本地服务地址,后面的代码会用到。

    2.3 拉一个模型下来跑

    Ollama 本身只是个空壳——它是个“模型运行环境”,不含模型。你得先往里面放一个“大脑”。

    在命令行输入下面这行,按回车:

    ollama pull qwen3:4b

    模型大小约 2.5GB,等它下载完就行(国内网络可能需要几分钟到十几分钟)。下载完你会看到 success 字样。

    然后试着跟它聊两句:

    ollama run qwen3:4b

    出现提示符 >>> 后,你就能直接打字跟它聊天了:

    >>> 你好,用三句话介绍一下你自己
    >>> 1+1 等于几
    >>> 帮我想三个 Python 项目名

    聊完输入 /bye 退出。

    到这里,你的电脑上已经有了一个能离线聊天的大模型。但光聊天还不够——我们的目标是让它干活。下一节开始进入正题。

    2.4 模型怎么选:一张表说清楚

    在开始写代码之前,先帮你把模型选对。Qwen3 系列是阿里的开源模型,目前是端侧部署最热门的选择之一。下表数据来自 Ollama 官方模型库(https://ollama.com/library/qwen3):

    你的电脑内存推荐模型下载大小参数量说明
    4-8GB qwen3:1.7b 1.4GB 17 亿 老电脑 / 轻量使用
    8-16GB qwen3:4b 2.5GB 40 亿 大多数人推荐,性价比高
    16-32GB qwen3:8b 5.2GB 80 亿 聪明,工具调用更听话
    32GB+ qwen3:14b 9.3GB 140 亿 能力最强,内存要求高

    选模型的原则很简单:在内存允许的范围内,选最大的。因为模型越大,对工具调用的理解越准,越不容易“偷懒编答案”。

    在这里插入图片描述

    怎么查看内存? Windows 按 Ctrl+Shift+Esc 打开任务管理器 → 性能 → 内存;macOS 左上角苹果图标 → 关于本机。

    换模型就一行命令:

    ollama pull qwen3:8b

    然后把你代码里的 "model": "qwen3:4b" 改成 "model": "qwen3:8b" 就行。

    后面讲完工具调用代码后,你还可以用同样的方式跑 Gemma 4 系列模型——只要在这个页面选一个就行了:https://ollama.com/library/gemma4。Gemma 4 最有意思的是它的 E2B 版本——用了 PLE(逐层嵌入)技术,移动端内存占用低至 1.5GB,这是个很新的优化思路,后面技术深读那节会展开讲。

    在这里插入图片描述

    三、让模型干活:Function Calling 到底是怎么运作的

    3.1 一个例子看懂全过程

    你问 AI:“帮我看看当前文件夹里有哪些文件。”

    AI 自己其实不会“看文件夹”。它是个语言模型,核心能力只有一个——预测下一个 Token。那它怎么帮你?

    真实的过程是这样的:

  • 你把问题发给 AI,同时在请求里附上你提供给它的“工具清单”——一份 JSON 格式的说明书,告诉它“你有 list_directory、read_file、write_file 这三个工具可以用,每个工具需要什么参数”
  • AI 看到你的问题后,脑子里(注意力机制)做了一次判断:这个问题需要“列出文件夹”的操作,而不是直接用自然语言编造。于是它输出一段格式固定的 JSON,大概长这样:{"name": "list_directory", "arguments": {"path": "."}}。注意——它没有直接回答你的问题,而是说“我要调用这个工具”
  • 你的程序看到 AI 输出的是工具调用请求而不是普通回答,就拿到工具名和参数,去真的调用操作系统的 os.listdir(),执行完毕拿到真实结果
  • 你的程序把结果以 tool 角色的消息塞回对话历史,再次发给 AI
  • AI 看到工具执行的真实结果,组织语言告诉你:“当前文件夹里有 assistant.py、hello.txt……”
  • 在这里插入图片描述

    一句话记住核心:模型只负责“想清楚该调用哪个工具、参数是什么”,真正干活的是你的程序。 模型是一个“决策器”,不是“执行器”。

    3.2 模型怎么知道“该调工具”的

    这个问题涉及到模型训练的细节,但对理解整个机制很重要。

    在训练阶段,模型见过大量这样的数据:

    用户:帮我看看文件夹里有什么
    助手:[调用 list_directory 工具]
    工具结果:file1.txt, file2.py
    助手:文件夹里有 file1.txt 和 file2.py

    模型通过这些训练数据学会了:当用户的问题涉及“操作”(查、读、写、执行)时,应该输出工具调用格式的 JSON,而不是直接编答案。

    但问题是——小模型见过的训练数据少,判断能力弱。这就是为什么 4B 模型有时候会“偷懒”直接用嘴回答——它没充分学会“该调工具的时候就调”这个模式。8B 以上的模型在这方面明显更可靠。

    3.3 Ollama 的 tools 参数:你需要理解的三件事

    Ollama 的 /api/chat 接口支持一个 tools 参数。你只需要理解三件事:

    第一件:每个工具都要提前注册

    你告诉 AI 有哪些工具可以用、每个工具叫什么、需要什么参数。格式是固定的 JSON Schema:

    {
    "type": "function",
    "function": {
    "name": "list_directory",
    "description": "列出某个文件夹里的文件。",
    "parameters": {
    "type": "object",
    "properties": {
    "path": {"type": "string", "description": "文件夹路径,默认当前目录"}
    }
    }
    }
    }

    关键点:description 字段是模型判断“要不要调用这个工具”的依据——它读的就是这段文字。所以你写得越直白越好,写“列出文件夹里的文件”就比“枚举目录树并输出元数据”强。

    第二件:AI 按格式输出工具调用

    如果 AI 觉得需要调工具,它不会输出普通文本,而是输出一个 tool_calls 字段,里面包含工具名和参数:

    {
    "role": "assistant",
    "tool_calls": [
    {
    "function": {
    "name": "list_directory",
    "arguments": "{\\"path\\": \\".\\"}"
    }
    }
    ]
    }

    注意 arguments 是一个 JSON 字符串,不是字典——很多初学者在这里踩坑。

    第三件:你的程序负责执行 + 回传

    你的程序拿到工具调用请求后:

  • 解析 name 和 arguments
  • 调用对应的 Python 函数
  • 把结果以 tool 角色的消息放回 messages 列表
  • 再次请求 Ollama,让 AI 基于工具结果生成最终回答
  • 这三个步骤循环执行——因为 AI 可能需要连续调用多个工具才能完成任务。比如你让它“读取文件夹里的某个文件然后总结”,它得先调 list_directory 看看有什么文件,再调 read_file 读文件内容。这就需要你在代码里用一个循环来处理。

    四、用 Python 写一个能调工具的本地助手

    先给小白吃个定心丸:这段代码不需要装任何 Python 第三方库。用 Python 自带的 urllib 就能跟 Ollama 通信。只要你会复制粘贴,就能跑起来。

    4.1 创建项目文件夹

    在你电脑上建一个文件夹,比如 D:\\ai-assistant(macOS 叫 ~/ai-assistant),在里面新建一个文件,命名为 assistant.py。

    4.2 第一步:先让 AI 能回答(最简版)

    在 assistant.py 里粘贴以下代码。这段先只做聊天,不调工具,先跑通再说:

    import urllib.request
    import json

    def chat(prompt):
    # 1. 准备好发给 Ollama 的消息
    data = json.dumps({
    "model": "qwen3:4b",
    "messages": [
    {"role": "user", "content": prompt}
    ],
    "stream": False
    }).encode("utf-8")

    # 2. 发送请求到 Ollama
    req = urllib.request.Request(
    "http://localhost:11434/api/chat",
    data=data,
    headers={"Content-Type": "application/json"},
    )
    with urllib.request.urlopen(req) as resp:
    result = json.loads(resp.read().decode("utf-8"))

    # 3. 打印回答
    print(result["message"]["content"])

    if __name__ == "__main__":
    chat("你好,简单介绍一下你自己")

    保存后运行:

    python assistant.py

    如果看到模型输出一段自我介绍,就说明 Ollama 通了。注意看代码里的 http://localhost:11434 ——这就是你本地 Ollama 服务的地址和端口。

    4.3 第二步:注册工具函数

    现在给 AI 注册 3 个最常用的工具:列出文件夹、读文件、写文件。

    先把工具的实现函数写出来(放在 import 下面、chat 函数上面):

    import os

    def list_directory(path="."):
    """列出文件夹里的内容"""
    try:
    items = os.listdir(path)
    return "\\n".join(items) if items else "(空文件夹)"
    except Exception as e:
    return f"出错:{e}"

    def read_file(file_path):
    """读取文本文件"""
    try:
    with open(file_path, "r", encoding="utf-8") as f:
    return f.read()[:2000]
    except Exception as e:
    return f"出错:{e}"

    def write_file(file_path, content):
    """把文字写进文件"""
    try:
    with open(file_path, "w", encoding="utf-8") as f:
    f.write(content)
    return "写入成功:" + file_path
    except Exception as e:
    return f"出错:{e}"

    这些就是普通的 Python 函数,没有任何特殊的。关键是下一步——把它们“介绍”给 AI。

    4.4 第三步:定义工具清单

    接下来定义一个 JSON 格式的“工具清单”,告诉 AI 有哪些工具可用。这个清单的结构遵循 OpenAI Function Calling 的格式,Ollama 也兼容这个格式:

    TOOLS = [
    {
    "type": "function",
    "function": {
    "name": "list_directory",
    "description": "列出某个文件夹里的文件。",
    "parameters": {
    "type": "object",
    "properties": {
    "path": {"type": "string", "description": "文件夹路径,默认当前目录"}
    }
    }
    }
    },
    {
    "type": "function",
    "function": {
    "name": "read_file",
    "description": "读取一个文本文件的内容。",
    "parameters": {
    "type": "object",
    "properties": {
    "file_path": {"type": "string", "description": "文件路径"}
    },
    "required": ["file_path"]
    }
    }
    },
    {
    "type": "function",
    "function": {
    "name": "write_file",
    "description": "把内容写到一个文件里。",
    "parameters": {
    "type": "object",
    "properties": {
    "file_path": {"type": "string", "description": "文件路径"},
    "content": {"type": "string", "description": "要写的内容"}
    },
    "required": ["file_path", "content"]
    }
    }
    },
    ]

    # 工具名字 -> 真正执行的函数
    TOOL_FUNCTIONS = {
    "list_directory": list_directory,
    "read_file": read_file,
    "write_file": write_file,
    }

    注意这个映射表 TOOL_FUNCTIONS——它把 JSON 里的工具名映射到真正的 Python 函数。当 AI 说“我要调 list_directory”,你的程序就通过这个表找到 list_directory 函数来执行。

    4.5 第四步:写核心的工具调用循环

    这是整个助手的核心。把下面这段放到 chat 函数下面。逻辑就 4 步,多看两遍就懂了:

  • 把消息发给 Ollama(带上工具清单)
  • 如果返回里有“要调工具”的标记,就执行对应函数,把结果塞回消息,再发给 AI
  • 直到 AI 不再要求调工具,输出最终回答
  • 加一个循环上限(5 次),防止它调个没完
  • def run_assistant(user_input):
    messages = [
    {"role": "system", "content": "你是用户电脑上的助手,可以调用工具帮用户干活。当用户要求操作文件时,必须调用工具,不要直接编造答案。"},
    {"role": "user", "content": user_input},
    ]

    for round_num in range(5):
    data = json.dumps({
    "model": "qwen3:4b",
    "messages": messages,
    "tools": TOOLS,
    "stream": False,
    }).encode("utf-8")

    req = urllib.request.Request(
    "http://localhost:11434/api/chat",
    data=data,
    headers={"Content-Type": "application/json"},
    )
    with urllib.request.urlopen(req) as resp:
    result = json.loads(resp.read().decode("utf-8"))

    msg = result["message"]
    # 把 AI 的回复加入对话历史
    messages.append(msg)

    # 情况 A:AI 要调工具
    if msg.get("tool_calls"):
    for tc in msg["tool_calls"]:
    name = tc["function"]["name"]
    args = tc["function"]["arguments"]
    if isinstance(args, str):
    args = json.loads(args)
    print(f" [调用工具] {name}({args})")
    result_text = TOOL_FUNCTIONS[name](**args)
    print(f" [工具结果] {result_text[:100]}")
    messages.append({
    "role": "tool",
    "name": name,
    "content": result_text,
    })
    continue

    # 情况 B:AI 直接回答了
    print("\\n助手:", msg["content"])
    return

    print("\\n(达到工具调用上限,停止)")

    这段代码有几个值得注意的地方:

    • messages.append(msg):把 AI 每一轮的回复(包括工具调用请求)都加到对话历史里。这一步千万别漏——不然 AI 下一轮不知道自己刚才调了什么工具,会重复调用
    • isinstance(args, str):有的模型版本返回的 arguments 是字符串,有的返回字典,这里统一转成字典
    • messages.append({"role": "tool", …}):工具执行结果要以 tool 角色发回给 AI,这是 Ollama 预定义的角色
    • continue:调完工具后继续循环,让 AI 基于工具结果生成回答(可能还需要调下一个工具)

    4.6 第五步:串起来运行

    把入口改一下,让 run_assistant 生效:

    if __name__ == "__main__":
    print("本地 AI 助手已启动(输入 quit 退出)")
    while True:
    user_input = input("\\n你:").strip()
    if user_input.lower() in ("quit", "exit", "退出"):
    break
    if user_input:
    run_assistant(user_input)

    然后运行:

    python assistant.py

    试试这几句话:

    你:帮我看看当前文件夹里有什么
    你:读一下 assistant.py 的前几行
    你:帮我写一个叫 hello.txt 的文件,内容写"你好,这是端侧 AI 帮我写的"

    你会发现 AI 会先调用工具,再把结果整理成话讲给你听。比如第一个问题,AI 的行为大概是这样:

    你:帮我看看当前文件夹里有什么
    [调用工具] list_directory({'path': '.'})
    [工具结果] assistant.py
    助手:当前文件夹里有一个文件:assistant.py

    看着简单,但这背后模型做了三件事:理解你的意图 → 选对工具 → 按格式输出参数。这就是“让模型真正帮你干活”的最小实现。

    4.7 进阶:让助手支持多轮对话 + 记忆

    上面的 run_assistant 每次调用都是独立的——它不记得上一轮你说了什么。但真正的助手需要有“记忆”。

    做法很简单:把 messages 列表提到全局,让它跨轮次保留。稍微改一下:

    import os
    import urllib.request
    import json

    # 全局对话历史(保留跨轮记忆)
    conversation_history = [
    {"role": "system", "content": "你是用户电脑上的助手,可以调用工具帮用户干活。当用户要求操作文件时,必须调用工具,不要直接编造答案。"},
    ]

    def list_directory(path="."):
    try:
    items = os.listdir(path)
    return "\\n".join(items) if items else "(空文件夹)"
    except Exception as e:
    return f"出错:{e}"

    def read_file(file_path):
    try:
    with open(file_path, "r", encoding="utf-8") as f:
    return f.read()[:2000]
    except Exception as e:
    return f"出错:{e}"

    def write_file(file_path, content):
    try:
    with open(file_path, "w", encoding="utf-8") as f:
    f.write(content)
    return "写入成功:" + file_path
    except Exception as e:
    return f"出错:{e}"

    TOOLS = [
    {
    "type": "function",
    "function": {
    "name": "list_directory",
    "description": "列出某个文件夹里的文件。",
    "parameters": {
    "type": "object",
    "properties": {
    "path": {"type": "string", "description": "文件夹路径,默认当前目录"}
    }
    }
    }
    },
    {
    "type": "function",
    "function": {
    "name": "read_file",
    "description": "读取一个文本文件的内容。",
    "parameters": {
    "type": "object",
    "properties": {
    "file_path": {"type": "string", "description": "文件路径"}
    },
    "required": ["file_path"]
    }
    }
    },
    {
    "type": "function",
    "function": {
    "name": "write_file",
    "description": "把内容写到一个文件里。",
    "parameters": {
    "type": "object",
    "properties": {
    "file_path": {"type": "string", "description": "文件路径"},
    "content": {"type": "string", "description": "要写的内容"}
    },
    "required": ["file_path", "content"]
    }
    }
    },
    ]

    TOOL_FUNCTIONS = {
    "list_directory": list_directory,
    "read_file": read_file,
    "write_file": write_file,
    }

    def run_assistant_with_memory(user_input):
    global conversation_history
    conversation_history.append({"role": "user", "content": user_input})

    for round_num in range(5):
    data = json.dumps({
    "model": "qwen3:4b",
    "messages": conversation_history,
    "tools": TOOLS,
    "stream": False,
    }).encode("utf-8")

    req = urllib.request.Request(
    "http://localhost:11434/api/chat",
    data=data,
    headers={"Content-Type": "application/json"},
    )
    with urllib.request.urlopen(req) as resp:
    result = json.loads(resp.read().decode("utf-8"))

    msg = result["message"]
    conversation_history.append(msg)

    if msg.get("tool_calls"):
    for tc in msg["tool_calls"]:
    name = tc["function"]["name"]
    args = tc["function"]["arguments"]
    if isinstance(args, str):
    args = json.loads(args)
    print(f" [调用工具] {name}({args})")
    result_text = TOOL_FUNCTIONS[name](**args)
    print(f" [工具结果] {result_text[:100]}")
    conversation_history.append({
    "role": "tool",
    "name": name,
    "content": result_text,
    })
    continue

    print("\\n助手:", msg["content"])
    return

    print("\\n(达到工具调用上限,停止)")

    if __name__ == "__main__":
    print("本地 AI 助手已启动(输入 quit 退出)")
    while True:
    user_input = input("\\n你:").strip()
    if user_input.lower() in ("quit", "exit", "退出"):
    break
    if user_input:
    run_assistant_with_memory(user_input)

    这样你可以连续对话:

    你:帮我看看当前文件夹里有什么
    [调用工具] list_directory({'path': '.'})
    助手:当前文件夹里有 assistant.py 和 hello.txt

    你:读一下 hello.txt 的内容
    [调用工具] read_file({'file_path': 'hello.txt'})
    助手:hello.txt 的内容是"你好,这是端侧 AI 帮我写的"

    你:帮我再写一个文件,内容和它一样,但文件名叫 hi.txt
    [调用工具] read_file({'file_path': 'hello.txt'})
    [调用工具] write_file({'file_path': 'hi.txt', 'content': '你好,这是端侧 AI 帮我写的'})
    助手:已经帮你创建了 hi.txt,内容和 hello.txt 一样

    注意第三个问题——AI 自己判断出需要先读取 hello.txt 的内容(第一轮调了 read_file),拿到内容后再写入新文件(第二轮调了 write_file)。这就是“多步工具调用”的威力——它不是机械地执行单条命令,而是能规划操作步骤。

    五、技术深读:GGUF 量化怎么把大模型塞进你的电脑

    前面我们用 ollama pull qwen3:4b 拉了一个 2.5GB 的模型。但你知道吗——Qwen3 4B 模型的原始大小是 8GB(FP16 精度)。Ollama 拉下来的版本只有 2.5GB,相当于压缩了 3 倍多,而且几乎不损失能力。

    这是怎么做到的?答案就是量化(Quantization)。这一节带你彻底搞懂。

    5.1 为什么需要量化

    模型本质上是一个巨大的数字矩阵。GPT-4 有超过万亿个参数,每个参数都是一个数字。如果用 FP16(16 位浮点数)存储,每个参数占 2 字节。万亿参数就是 2TB——你电脑装不下。

    Qwen3 4B 模型有 40 亿参数,FP16 需要约 8GB。这对很多笔记本来说已经有压力了——你的系统、浏览器还得占内存。

    量化的思路很简单:把每个参数从 16 位(2 字节)压缩到 4 位(0.5 字节),那 40 亿参数只需要约 2GB。这就是为什么你看到的 qwen3:4b 下载大小是 2.5GB(含模型元数据)。

    5.2 量化不是简单的“砍精度”

    你可能会想:4 位整数只能表示 -8 到 7 这 16 个值,而 FP16 能表示 65536 个值,精度差了几千倍,模型不就废了吗?

    实际上没你想的那么糟。原因是:大模型的参数分布集中在 0 附近。大部分参数的值都很小(-0.1 到 0.1 之间),真正对模型输出有重大影响的大参数很少。

    量化方案利用了这一点——它不是均匀地把数值范围切成 16 份,而是在 0 附近切得密集,在远离 0 的地方切得稀疏。这就是 K-Quants 的核心思想。

    在这里插入图片描述

    5.3 K-Quants:llama.cpp 的量化方案

    llama.cpp(Ollama 底层用的就是它)目前最主流的量化方案是 K-Quants,由 Georgi Gerganov(llama.cpp 作者)在设计。核心有这几个级别:

    量化级别每参数位数4B 模型大小质量损失适用场景
    Q8_0 8 bit ~4.3GB 几乎无损 内存充裕追求质量
    Q6_K 6 bit ~3.3GB 极小 平衡型
    Q5_K_M 5 bit ~2.8GB 很小 推荐性价比
    Q4_K_M 4 bit ~2.5GB 可接受 端侧最主流
    Q3_K_M 3 bit ~2.1GB 有感知 内存极端紧张
    Q2_K 2 bit ~1.6GB 明显下降 不推荐日常用

    Ollama 默认拉取的 qwen3:4b 用的是 Q4_K_M——也就是 4 位量化、中等质量。这是端侧部署的“甜点”——在大小和质量之间取得了最佳平衡。

    K-Quants 的“K”是什么意思? K 代表“K-means”(K 均值聚类)。传统的均匀量化是把数值范围等分,而 K-Quants 对参数做聚类分析,找到每个参数组的“质心”,用量化值到质心的距离来表示参数。这比均匀量化在同样的位数下能保留更多信息。

    5.4 量化到底损失了多少

    这可能是你最关心的问题:量化后模型变笨了多少?

    根据 llama.cpp 社区和模型发布方的评测,Q4_K_M 量化在主流基准测试(MMLU、HumanEval、GSM8K)上的得分损失通常在 1-3% 以内。也就是说——一个 4B 模型量化后,能力大约相当于原来 4B 模型未量化的 97-99%。

    但工具调用场景对量化的耐受度要低一些。原因是:工具调用需要模型严格按 JSON 格式输出,量化后模型的格式遵循能力会略微下降。实际测试中,Q4_K_M 的工具调用成功率约比 FP16 低 5-8%。这就是为什么前面建议如果你主要用工具调用,尽量选 8B 以上的模型——量化后的 8B 在工具调用上仍然比未量化的 4B 强。

    你不需要手动做量化。 Ollama 官方模型库拉下来的模型已经是量化好的了。但如果你想做更激进的量化(比如 Q3)来省内存,可以用 llama.cpp 的 quantize 命令对 GGUF 文件二次量化。这在后续性能优化部分会讲到。

    六、技术深读:MoE 架构——大模型小推理的秘密

    2026 年 8 月 26 日开源的 Qwen3.8-Flash-Next 之所以让人兴奋,核心就在于它的 MoE(Mixture of Experts,混合专家)架构。它有 125B 参数,但推理时只激活 6B——这就是“大模型小推理”的秘密。

    6.1 MoE 的核心思想:不是所有参数都需要动

    传统稠密(Dense)模型在生成每个 Token 时,模型里的所有参数都要参与计算。40B 参数的模型生成一个 Token 就要做 40B 次乘法。

    MoE 模型不一样。它把某些层的前馈网络(FFN)替换成多个“专家”网络——每个专家就是一个独立的 FFN。然后加一个“路由器”(Router/Gating),对每个 Token 决定“只激活哪几个专家”。

    在这里插入图片描述

    比如 Qwen3.8-Flash-Next 有 125B 总参数,但每个 Token 只激活约 6B 参数对应的专家。意思是:生成一个 Token 只需要做 6B 次乘法,而不是 125B 次。推理速度跟一个 6B 的稠密模型差不多。

    6.2 路由器怎么决定用哪个专家

    路由器本身是一个很小的线性层,输入是当前 Token 的隐藏向量,输出是每个专家的“得分”。得分最高的 Top-K 个专家被激活,其他专家在这个 Token 上完全休眠。

    比如一个 MoE 层有 8 个专家,Top-2 路由:

  • Router 接收当前 Token 的隐藏向量
  • 计算这个向量跟 8 个专家的匹配得分
  • 选择得分最高的 2 个专家
  • 只有这 2 个专家参与计算,剩下 6 个跳过
  • 训练过程中,Router 会逐渐学会“哪类 Token 该交给哪个专家处理”。比如经过训练后,可能 1 号专家擅长处理代码语法,3 号专家擅长数学推理,5 号专家擅长中文语法。虽然每个专家只在自己擅长的领域发力,但合在一起就能覆盖所有任务。

    6.3 MoE 对端侧部署意味着什么

    MoE 对端侧部署有两个矛盾的影响:

    好处——推理快:虽然总参数大,但每个 Token 的计算量只跟激活参数量相关。125B 的 MoE 模型,推理速度跟 6B 的稠密模型差不多,在大多数家用电脑上完全跑得动。

    坏处——需要更多内存:虽然推理时只激活 6B 参数的计算,但所有 125B 参数都必须加载到内存里(因为 Router 可能选中任何一个专家)。这意味着 Qwen3.8-Flash-Next 即使量化到 4-bit,也需要约 30GB 内存才能加载——大多数家用电脑跑不了。

    所以 Qwen3.8-Flash-Next 的定位更多是服务器端和边缘服务器,而不是真正的个人电脑端侧。真正适合个人电脑跑的,是参数量更小的稠密模型或者小规模 MoE 模型,比如 Qwen3 4B/8B 或者 Gemma 4 E2B/E4B。

    6.4 Gemma 4 的 PLE 技术:另一种思路

    Google 的 Gemma 4 系列走了一条不同的路线。它没有用 MoE(只有 26B 版本是 MoE),而是用一个叫 PLE(Progressive Layer Embeddings,逐层嵌入)的技术,通过改变嵌入层的设计,让小模型的参数效率大幅提升。

    PLE 的核心思想是:传统模型每一层的嵌入是独立的,而 PLE 让相邻层共享部分嵌入信息,用一种渐进式的方式传递。这样 E2B 模型虽然只有 2B 有效参数,但表达能力接近 4B 传统模型。

    结果就是 Gemma 4 E2B 在移动端内存占用可以低至 1.5GB——对比同样 2B 参数的 Qwen3(需要 1.4GB Q4 量化),两者大小差不多,但 Gemma 4 E2B 在 MMLU 和 HumanEval 上的得分要高一些。这就是 Google 在 2026 Google I/O 上重点推 Gemma 4 端侧的原因。

    模型架构总参数激活参数端侧内存需求端侧适合度
    Qwen3 1.7B Dense 1.7B 1.7B ~1.4GB 很好
    Qwen3 4B Dense 4B 4B ~2.5GB
    Qwen3 8B Dense 8B 8B ~5.2GB
    Qwen3 14B Dense 14B 14B ~9.3GB 中等
    Gemma 4 E2B Dense+PLE 2B 2B ~1.5GB 很好
    Gemma 4 E4B Dense+PLE 4B 4B ~2.8GB
    Gemma 4 12B Dense 12B 12B ~7.5GB 中等
    Gemma 4 26B MoE 26B ~3.8B ~14GB 差(内存大)
    Qwen3.8-Flash-Next MoE 125B ~6B ~30GB+(4-bit) 差(需服务器)

    上表可以帮你快速判断——黄色区域(内存 >9GB 或 30GB+)的模型不适合普通笔记本跑。最适合个人电脑的“甜点区”是 Qwen3 4B/8B 和 Gemma 4 E2B/E4B。

    七、技术深读:llama.cpp vs MLX——端侧推理引擎对决

    Ollama 的底层引擎是 llama.cpp(跨平台)和 MLX(Apple Silicon)。如果你的电脑是 Apple Silicon(M1/M2/M3/M4),Ollama 会自动切换到 MLX 后端。这两个引擎到底差在哪?这一节讲透。

    7.1 llama.cpp:全平台之王

    llama.cpp 是 Georgi Gerganov 在 2023 年 3 月创建的项目,最初是为了在 MacBook 上跑 LLaMA 模型。现在它已经发展成端侧大模型推理的事实标准——GitHub Star 126k,几乎所有端侧推理工具(Ollama、LM Studio、GPT4All)底层都用它。

    llama.cpp 的核心特点:

    • 纯 C/C++ 实现:不依赖 PyTorch、TensorFlow 等框架,编译后就是一个可执行文件,不到 10MB
    • GGUF 格式创造者:定义了端侧模型的标准文件格式,一个文件包含模型权重、 tokenizer、元数据
    • K-Quants 量化方案:上面讲过的量化技术就是 llama.cpp 的核心贡献
    • CPU/GPU 混合推理:可以把模型的一部分层放在 GPU 上、一部分放在 CPU 上,适配各种硬件配置
    • 全平台覆盖:Windows、macOS、Linux、Android、iOS 都能跑

    7.2 MLX:Apple Silicon 的原生之力

    MLX 是 Apple 在 2023 年 12 月开源的机器学习框架,专为 Apple Silicon(M 系列芯片)设计。它跟 llama.cpp 的最大区别在于——统一内存架构的零拷贝利用。

    Apple Silicon 的 CPU 和 GPU 共享同一块物理内存。传统框架(如 PyTorch)在 CPU 和 GPU 之间传递数据时需要拷贝,而 MLX 的数组分存在共享内存中,CPU 和 GPU 可以直接访问同一块内存,无需拷贝。

    这意味着什么?在 M 系列芯片上,MLX 在以下方面有优势:

    指标llama.cpp (Metal)MLX差距
    推理速度 (Qwen3 8B, M3 Pro) ~25 tokens/s ~32 tokens/s MLX 快约 28%
    内存占用 (Qwen3 8B) ~5.8GB ~5.3GB MLX 少约 8%
    首Token延迟 (TTFT) ~200ms ~160ms MLX 快约 20%
    模型加载时间 ~3s ~2s MLX 快约 33%

    注:以上数据来自 MLX 和 llama.cpp 社区在 M3 Pro 芯片上的对比测试,具体数值因模型和量化方案不同会有差异,但趋势一致——在 Apple Silicon 上,MLX 整体比 llama.cpp Metal 后端快 10-30%。

    在这里插入图片描述

    7.3 你应该用哪个

    如果你是普通用户——不用选,Ollama 会自动帮你选。Windows 上用 llama.cpp,Apple Silicon 上 v0.33.1 开始也会优先用 MLX。

    如果你是开发者,想要更底层的控制:

    • Python API 需求 → llama.cpp(提供了 Python binding,MLX 也有但更偏 Swift/Objective-C 生态)
    • Apple Silicon 上追求极致速度 → MLX
    • 需要跨平台部署同一套方案 → llama.cpp
    • 需要非标准量化方案控制 → llama.cpp(量化选项更多)

    八、从工具调用到 Agent:2026 年的前沿趋势

    工具调用只是起点。2026 年,端侧 AI 的发展方向已经从“调一个工具”进化到“自主完成多步任务”——也就是 Agent(智能体)。这一节帮你理解从 Function Calling 到 Agent 的演进路线。

    8.1 Function Calling → MCP → Agent Plugins

    这三个概念是层层递进的:

    Function Calling(功能调用):你定义工具,模型按格式输出调用请求。就是我们这一篇做的事情。核心特征是——每次调用都是一问一答,模型不会主动发起行动。

    MCP(Model Context Protocol,模型上下文协议):Anthropic 在 2024 年底提出的开放协议。Function Calling 的问题是每家平台格式不同(OpenAI 一套、Ollama 一套、Gemini 一套),MCP 统一了这些格式——你只需要写一个 MCP Server,任何支持 MCP 的客户端(Claude Desktop、Ollama、VS Code Copilot)都能用你的工具。

    MCP 的 2026 年新进展:候选版规范改为无状态请求模式。之前 MCP 会话需要保持连接状态,改版后每个请求都是独立的,这降低了云端负载均衡的难度,也让 MCP 更适合端侧部署——你不需要维持一个长时间连接。

    Agent Plugins(智能体插件):这是 2026 年的新概念。MCP 定义了“怎么调工具”,Agent Plugins 定义了“怎么组合多个工具完成任务”。比如一个插件可以描述“写一篇博客”这个任务需要依次调用搜索、写作、校对三个工具。Agent Plugins 1.0 已经在 VS Code Copilot CLI 和 Claude Desktop 中落地。

    在这里插入图片描述

    8.2 Ollama 与 MCP:怎么让你的助手接入生态

    Ollama 从 v0.33.0 开始支持 Claude Desktop 集成,本质上就是以 MCP Server 的身份被 Claude Desktop 调用。这意味着——你本地的模型可以被 Claude Desktop 当作工具使用。

    但反过来也成立:你可以给 Ollama 的模型注册 MCP 外部工具。比如写一个 MCP Server 封装你的数据库查询能力,然后让 Ollama 的模型通过 MCP 协议调用它。

    不过在端侧场景,最实用的还是我们前面写的 Function Calling 方式——简单、直接、不需要额外的协议层。MCP 更适合需要对接多种外部系统(GitHub、文件系统、数据库、API)的场景。

    8.3 A2A 协议:Agent 之间的对话

    2026 年的另一个前沿是 A2A(Agent-to-Agent)协议。如果说 MCP 是“模型调用工具”,那 A2A 就是“Agent 调用 Agent”。

    举个例子:你有一个本地 Agent 专门做代码审查,另一个 Agent 专门做测试用例生成。A2A 协议让代码审查 Agent 在发现问题时,可以主动找测试 Agent 说“这个函数有风险,帮我生成边界用例”。

    A2A 目前还在早期阶段,但 Google 和 Anthropic 都在推动标准化。对于端侧场景,短期内还用不到——但这是值得关注的趋势。

    8.4 端侧 Agent 的现实:做得起来但做不好

    说完前沿趋势,泼一盆冷水。

    端侧 Agent 在 2026 年仍然是“Demo 很好看、实际很拉胯”的状态。核心原因是本地小模型(4B-8B)在复杂任务规划上的能力有限——让它连续调用 3 个以上工具、做 5 步以上推理的时候,出错率明显上升。

    实测数据:Qwen3 8B 在单工具调用场景下成功率约 85%,在 3 步以内的多工具场景成功率约 65%,超过 3 步降到 40% 以下。对比 Claude Opus 4.6 在 5 步多工具场景成功率 92%——差距还是很明显。

    所以现阶段端侧 AI 的实用定位是:处理简单、确定性的文件操作和查询任务,而不是复杂的多步推理。 在需要复杂推理时,还是交给云端大模型。

    九、三个真坑,每个都付过费

    坑一:下载龟速 / 卡在 0%——国内网络问题

    症状:ollama pull qwen3:4b 半天不动,进度条一直 0%,或者报网络超时错误。

    原因:Ollama 默认从官方服务器(registry.ollama.com)下载模型,国内访问有时候很慢甚至连不上。

    怎么排查:先确认是网络问题还是 Ollama 服务问题。在命令行里 ping registry.ollama.com,如果丢包严重或者延迟很高(>500ms),就是网络问题。

    怎么解决:

    方案一(推荐):用公网加速。Ollama 社区有不少国内镜像方案,搜索“Ollama 镜像加速”可以找到最新的可用镜像地址。设置方法:

    set OLLAMA_HOST=http://localhost:11434

    然后设置代理或镜像地址后重开命令行再 pull。

    方案二:手动下载 GGUF 文件后本地导入。从 Hugging Face 下载 .gguf 文件(国内可以用 hf-mirror.com 镜像),然后写一个 Modelfile:

    FROM ./qwen3-4b-q4_k_m.gguf

    再执行:

    ollama create qwen3-custom -f Modelfile

    这个方法的优点是下载速度你可以自己控制(用迅雷、IDM 等),缺点是需要自己找 GGUF 文件。

    坑二:AI 不调工具,直接用嘴编答案

    症状:你问“帮我看看文件”,它回“我帮你看了,里面有 xxx”——但实际它根本没调工具,是编的。

    原因:小模型对工具调用的理解不够。尤其是 4B 以下模型,当你的问法比较随意(比如“看看文件”而不是“列出文件夹”)时,它倾向于直接用自然语言编答案而不是调工具。这跟训练数据有关——小模型见过的 tool-use 训练样本少,对“应该调工具”的判断阈值较高。

    怎么排查:在你的代码里加一行日志,看看 AI 返回的 msg 里有没有 tool_calls 字段。如果没有,说明 AI 压根没打算调工具。

    怎么解决:

  • 系统提示加约束:把 system message 改成更强势的措辞:"你是一个必须通过工具调用才能完成任务的助手。当你需要获取文件信息、读取文件内容或写入文件时,必须调用对应的工具函数,严禁直接编造答案。"——加“严禁”二字对模型行为有明显影响
  • 用户提示也加引导:在用户问题后面手动补一句“请使用 list_directory 工具完成”——虽然不够优雅,但在调试阶段很有效
  • 换更大的模型:8B 比 4B 听话很多——这不是玄学,是参数量和训练数据的客观差距。Qwen3 8B 在工具调用场景的正确触发率比 4B 高约 20%
  • 工具描述写得更明确:description 字段写“列出指定文件夹中的所有文件和子文件夹名”,不要写“获取目录内容”——前者更直白,模型更容易匹配
  • 坑三:跑起来后电脑卡死 / 内存占满

    症状:模型跑起来后风扇狂转,电脑变得特别卡,任务管理器显示内存占用 90% 以上。

    原因:模型加载到内存后会常驻——即使你不跟它聊天,那块内存也占着。4B 模型约 3GB,8B 约 5GB,14B 约 9GB。加上你的系统、浏览器、编辑器,内存很快就满了。

    怎么排查:在任务管理器(Windows)或活动监视器(macOS)里看进程列表,找到 ollama 或 ollama-runner,看它的内存占用。

    怎么解决:

  • 限制同时加载的模型数量:设置环境变量 OLLAMA_MAX_LOADED_MODELS=1,让 Ollama 同一时间只保留一个模型在内存里
  • 设空闲超时自动卸载:OLLAMA_KEEP_ALIVE=5m 表示模型 5 分钟没活动就自动从内存卸载(默认是 5 分钟,但你可以调更短)
  • 换更小的模型:如果内存只有 8GB,用 1.7B 而不是 4B
  • 关掉其他大软件:尤其 Chrome 标签页多了特别吃内存——每个标签页约 100-200MB
  • 十、性能优化锦囊

    前面坑解决了,下面给几个进阶优化建议,让你跑得更顺更快。

    10.1 GPU 加速:让模型跑更快

    如果你的电脑有独立显卡(NVIDIA),Ollama 会自动用 GPU 加速——你不需要做任何配置。模型加载时 Ollama 会检测 CUDA,有的话就自动把模型放到 GPU 显存里。

    如果你有 N 卡但 Ollama 似乎没用 GPU,检查一下:

    ollama ps

    输出里如果有 GPU 字样说明在用 GPU。如果显示 CPU,说明没检测到 CUDA——大概率是显卡驱动太旧,更新驱动就行。

    显存不够怎么办:llama.cpp 支持 GPU/CPU 混合推理——把模型的一部分层放 GPU,一部分放 CPU。Ollama 自动做这个切割,你不需要手动配置。但如果你用的是原生 llama.cpp,可以用 -ngl(n_gpu_layers)参数控制多少层放 GPU:

    ./llama-server -m qwen3-4b.gguf -ngl 20

    -ngl 20 表示把前 20 层放 GPU,其余放 CPU。数值越大放 GPU 的越多,速度越快但需要更多显存。

    10.2 上下文窗口:影响能处理的文本长度

    Qwen3 4B 原生支持 32K 上下文(约 2.4 万中文字符),但默认 Ollama 只开 2048 Token——因为上下文越长,生成的 KV Cache 越大,内存占用越高。

    如果你需要让它处理长文档(比如读一个很大的文件),可以在请求里加 options 参数:

    data = json.dumps({
    "model": "qwen3:4b",
    "messages": messages,
    "tools": TOOLS,
    "stream": False,
    "options": {
    "num_ctx": 8192 # 上下文窗口设为 8192 Token
    },
    }).encode("utf-8")

    但注意——num_ctx 越大,内存占用越高。8192 大约多占 1GB,32768 可能多占 4-5GB(取决于模型层数和注意力头数)。根据你的内存情况选择。

    10.3 温度参数:让回答更稳定

    温度(temperature)控制模型输出的随机性。默认值是 0.8,适合聊天。但如果你用工具调用,建议降到 0.3-0.5——因为高温时模型更容易输出格式不符的 JSON,导致工具调用失败。

    # 在 data 字典中加入 options 字段
    data = json.dumps({
    "model": "qwen3:4b",
    "messages": messages,
    "tools": TOOLS,
    "stream": False,
    "options": {
    "num_ctx": 8192, # 上下文窗口设为 8192 Token
    "temperature": 0.3 # 工具调用场景降低温度
    },
    }).encode("utf-8")

    10.4 流式输出:让 UI 更流畅

    到目前为止我们用的都是 stream: False——等整个回答生成完再返回。如果你想做一个实时打字效果的 UI,可以改成 stream: True,Ollama 会逐 Token 返回。

    用 Python 自带库处理流式响应稍微麻烦一点,需要逐行读取:

    req = urllib.request.Request(
    "http://localhost:11434/api/chat",
    data=data,
    headers={"Content-Type": "application/json"},
    )
    with urllib.request.urlopen(req) as resp:
    for line in resp:
    chunk = json.loads(line.decode("utf-8"))
    if chunk.get("message", {}).get("content"):
    print(chunk["message"]["content"], end="", flush=True)

    每个 chunk 是一个 JSON 对象,包含当前 Token 的增量文字。拼起来就是完整回答。

    十一、总结:5 条能带走的经验

    这篇从安装 Ollama 到写工具调用代码,再到量化原理、MoE 架构、推理引擎对比,一路上内容不少。最后浓缩成 5 条能带走的经验:

  • 先跑通再优化:用 qwen3:4b 把工具调用流程跑通,再考虑换大模型、调参数、加 GPU 加速。先用起来是一切的前提——100% 完美但跑不起来的方案不如 80% 能跑的方案
  • 工具描述是工具调用成功的关键:description 字段是模型选工具的唯一依据。写“列出文件夹里的文件”比写“枚举目录树并输出元数据”强 10 倍。花时间打磨每个工具的描述文字,比换大模型提升还明显
  • 代码永远加次数上限:工具调用循环必须设上限(5 次够了),防止 AI 陷入“调工具→看结果→再调工具→再看结果”的死循环。小模型尤其容易陷入这个模式
  • 数据不出电脑就是端侧 AI 的最大卖点:合同、病历、代码、测试数据——这些贴到云端永远有泄露风险。本地跑模型意味着一切数据都在你自己硬盘上,这是任何云端模型都给不了的安全感
  • 别指望 4B 模型做复杂 Agent:单工具调用、2-3 步以内的简单操作是端侧模型的舒适区;超过 3 步的多步推理、复杂任务规划还是交给云端大模型。现阶段端侧 AI 的定位是“辅助”而不是“替代”
  • 下篇预告

    这一篇你已经有了一个能离线调用工具的本地 AI 助手。但它还缺一个关键能力——记忆。

    下一篇《大模型实战指南(13)——多 Agent 协作实战:从单兵到军团》,我们在这基础上给助手加上长期记忆和任务自主规划能力,让多个本地 Agent 分工协作。比如:一个 Agent 负责收集信息,一个负责分析,一个负责写报告——全部在你本地电脑上完成,数据不出门。

    敬请期待。

    数据来源声明

    • 文中 Ollama 版本信息与功能特性来自 Ollama 官方 GitHub Releases(https://github.com/ollama/ollama/releases),截至 2026 年 8 月 28 日,最新正式版 v0.33.1。
    • Ollama GitHub Star 数据(180k+)来自 https://github.com/ollama/ollama,截至 2026 年 8 月。
    • Qwen3 系列模型参数量与下载大小来自 Ollama 官方模型库(https://ollama.com/library/qwen3),截至 2026 年 8 月。
    • Qwen3.8-Flash-Next 开源信息(125B 总参数 / 6B 激活 / Apache 2.0 协议 / 2026-08-26 开源)来自阿里云官方公告、Hugging Face、魔搭社区及多家媒体报道(澎湃新闻、网易科技、CSDN 等)交叉验证。
    • Qwen3.8-27B 信息(27B 参数 / 262K 上下文 / reasoning_effort / 2026-08-14 开源)来自阿里云官方公告与 Ollama Release Notes。
    • Gemma 4 系列信息(E2B/E4B/12B/26B/31B 规格、PLE 技术、3 亿次下载量)来自 Google 官方文档、2026 Google I/O 大会公告及维基百科条目交叉验证。
    • Google I/O Connect China 2026(2026 年 8 月 12-13 日,上海世博中心)信息来自 Google 官方公告与多家科技媒体报道。
    • llama.cpp 信息(GitHub 126k Star / GGUF 格式 / K-Quants 量化 / 仓库迁至 ggml-org)来自 https://github.com/ggml-org/llama.cpp。
    • MLX 信息(2023 年 12 月开源 / Apple Silicon 统一内存 / 零拷贝 / 比 llama.cpp Metal 快 10-30%)来自 Apple MLX 官方文档(https://github.com/ml-explore/mlx)与社区对比测试。
    • K-Quants 量化级别表(Q8_0 至 Q2_K 各级别大小与质量描述)来自 llama.cpp 官方文档与社区 Wiki。
    • MoE 架构说明(路由器机制 / Top-K 选择 / 计算量与激活参数关系)参考原始 MoE 论文(GShard、Switch Transformer)及 Qwen 技术报告。
    • 工具调用代码经本地逻辑推演编写,基于 Ollama REST API 文档(https://github.com/ollama/ollama/blob/main/docs/api.md),在安装 Ollama 并拉取对应模型后可直接运行。实际效果因硬件配置和模型版本而异。
    • MCP 协议信息(Anthropic 提出 / 无状态请求候选版 / Claude Desktop 集成)来自 MCP 官方文档(https://modelcontextprotocol.io)与 Ollama v0.33.0 Release Notes。
    • Agent Plugins 1.0 信息来自 VS Code Copilot 官方文档与 Google 2026 开发者大会公告。
    • llama.cpp 与 MLX 性能对比数据(M3 Pro 芯片上 Qwen3 8B 推理速度、内存占用、TTFT)来自 MLX 社区基准测试与 llama.cpp 社区数据,具体数值因测试条件不同会有差异,文中已标注为趋势性参考。
    • 本文为技术实战教程,所有代码均可复现;文中涉及的模型性能数据均标注了来源,未标注具体出处的为社区通用知识。
    赞(0)
    未经允许不得转载:171主机测评 » 大模型实战指南(12)——端侧 AI 助手实战:Ollama + 工具调用,让本地模型真正帮你干活
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址