前两天逛 Hacker News,看到一个项目让我眼前一亮——**Forge**,一个给本地小模型加护栏(Guardrails)的开源框架。
它的口号很狂妄:把 8B 参数的小模型在 agent 任务上的准确率从 53% 干到 99%。
我一开始不信。8B 模型什么水平大家心里有数,跑跑聊天还行,真要它调工具、走多步流程,经常半路跑偏。结果看了作者的基准测试——Ministral-3 8B Instruct Q8 跑 llama-server,在 26 个场景的评测集上干到了 **86.5%**,最难的那一档也有 76%。配合推理时扩展(test-time compute scaling),直接冲到 **99%**。
这数字太离谱了,必须拆开来看看。
## 到底怎么做到的?
Forge 的核心思路其实不复杂:**不要让模型自己决定怎么干活,给它套上规矩。**
具体来说有三层:
**1. Rescue Parsing(救场式解析)**
模型输出的最大问题是格式跑偏。你让它输出 JSON,它给你来一段散文。Forge 的做法是——不管模型输出什么,都用另一个解析器去捞有用的东西。输出不合法?不报错,直接重试加提示修正。
**2. Step Enforcement(步骤强制执行)**
多步 agent 流程中最常见的翻车点是:模型跳步骤。Forge 在系统 prompt 里嵌了步骤约束,每一步只允许模型做当前该做的事,做完再放行到下一步。很像走钢索下面的安全网——它能走歪,但歪了会被扶回来。
**3. Context Compaction(上下文压缩)**
本地模型最头疼的是上下文窗口。几轮工具调用下来,历史就撑爆了。Forge 做了分层压缩:旧对话先摘要,再按重要性排序丢弃,确保窗口始终留给最重要的内容。
## 上手体验
Forge 提供了三种接入方式,按需求选就行:
### 方式一:WorkflowRunner(自带流程引擎)
适合从头开始搭 agent 的。定义好工具列表,选个后端,Forge 帮你管全套——prompt 组装、工具执行、上下文管理、护栏全部内置。
“`python
from forge import WorkflowRunner
from forge.backends import LlamaCppBackend
# 连接本地 llama-server
backend = LlamaCppBackend(base_url=”http://localhost:8080″)
runner = WorkflowRunner(backend=backend)
# 定义工具
def search_web(query: str) -> str:
# … 你的搜索逻辑
return results
def calculate(expr: str) -> float:
return eval(expr)
runner.add_tool(search_web)
runner.add_tool(calculate)
# 跑一个多步任务
result = runner.run(“查询今天比特币价格,计算过去24小时涨跌幅”)
“`
### 方式二:Guardrails 中间件
如果你已经有自己的 agent 循环了,不想全盘换掉,可以只挂 Forge 的护栏层。它暴露了一套中间件接口,插到你现有的编排逻辑里就行。
“`python
from forge.middleware import GuardrailsMiddleware
guard = GuardrailsMiddleware(
rescue_parsing=True,
enforce_steps=[“plan”, “execute”, “verify”],
max_retries=3
)
# 在你的循环里调用
for step in my_pipeline:
response = model.generate(prompt)
validated = guard.validate(step, response)
if not validated.passed:
response = guard.rescue(response)
“`
官方示例里有个文件叫 `examples/foreign_loop.py`,展示的就是这种用法。
### 方式三:Proxy Server(零侵入)
这是我最喜欢的方式。Forge 启动一个兼容 OpenAI API 的代理服务,你现有的工具(OpenCode, Continue, aider 等等)完全不需要改代码,把 base_url 指到 Forge 的代理端口就行。
“`bash
python -m forge.proxy –backend http://localhost:8080 –port 8081
“`
然后在你的客户端里:
“`python
from openai import OpenAI
client = OpenAI(
base_url=”http://localhost:8081/v1″,
api_key=”not-needed”
)
“`
透明地获得护栏加持,模型表现提升肉眼可见。
## 后端怎么选
Forge 支持四种后端:
| 后端 | 性能 | 上手难度 |
|——|——|———-|
| llama-server (llama.cpp) | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| Ollama | ⭐⭐⭐⭐ | ⭐ |
| Llamafile | ⭐⭐⭐ | ⭐⭐ |
| Anthropic API | ⭐⭐⭐⭐⭐ (云) | ⭐ |
基准测试里排名前 10 的配置全跑在 **llama-server** 上。如果你有 GPU,推荐这条路线:
“`bash
# 拉模型
wget https://huggingface.co/mistralai/Ministral-3-8B-Instruct-2512-GGUF/resolve/main/Ministral-3-8B-Instruct-2512-Q8_0.gguf
# 启动服务
llama-server -m Ministral-3-8B-Instruct-2512-Q8_0.gguf –jinja -ngl 999 –port 8080
“`
没 GPU 的话 Ollama 最省事:
“`bash
ollama pull ministral-3:8b-instruct-2512-q4_K_M
“`
## 我的实际感受
我拿一个内部的数据分析 agent 试了一下。之前用 Qwen2.5-7B 跑一个”查数据→画图→写结论”的三步流程,成功率大概在 60% 左右。挂上 Forge 的 proxy 模式后,同一个模型、同样的 prompt,跑 20 次成功了 18 次。
90% 的成功率对 7B 模型来说已经相当能打了。
当然也不是没代价——多了 rescue 重试和 context compaction 的开销,响应延迟多了大概 30%。但对于离线任务或者对延迟不敏感的场景,这点代价完全可以接受。
## 几点吐槽
1. **文档偏工程化**。README 写得挺好,但具体配置项的说明不够细,有几个参数得翻源码才能搞明白。
2. **Python 3.12+ 限定**。如果你还在用 3.10/3.11,得先升级环境。
3. **代理模式还不支持流式输出**。这对于聊天场景有点伤,期待作者后续加上。
## 总结
Forge 让我重新思考了一个事情:小模型的边界到底在哪?
之前大家的共识是”本地模型干不了复杂 agent 活,得上云”。Forge 用工程手段证明——**问题不一定出在模型脑子不够,而是缺了一套好的管理框架。**
如果你手头有本地模型想做 agent 方向,Forge 值得花一个下午试试。它是 MIT 协议,随便拿去改。GitHub 地址:[antoinezambelli/forge](https://github.com/antoinezambelli/forge)
—
*另外今天 Google I/O 发布了 Gemini 3.5 Flash,把”行动能力”直接做到模型层了。Mistral 也收购了 Emmi AI 布局工业制造场景。本地小模型和云端大模型两条路线都在加速——这一年的 AI 工程化进程比过去三年都快。*