Forge 实战指南:用 Guardrails 让本地 8B 模型达到 99% Agent 任务成功率
title: Forge 实战指南:用 Guardrails 让本地 8B 模型达到 99% Agent 任务成功率
slug: forge-guardrails-local-llm-agent-guide
自研 LLM 跑工具调用,最让人头疼的问题不是模型不够聪明,而是明明知道该调用什么工具,但输出格式总是出错——tool call 参数拼错、用 JSON 代码块代替标准格式、或者干脆返回一段文字而非工具调用。这不是模型能力问题,是输出一致性问题。
Forge(MIT 协议, 1900+ Stars)是一个专门解决这个问题的 Python 框架。它的核心思想很简单:不改模型,只修输出。通过一套声明式的 guardrails(救援解析、重试循环、响应校验),让本地模型的 agent 任务成功率从 53% 提高到 99%。
Forge 的三种使用模式
Forge 提供了三个层次的接入方式,从零配置到完全定制:
1. Proxy 模式(推荐入门)
最省力的方式——Forge 作为一个反向代理服务器,放在你的客户端和模型后端之间。无需改一行 Python 代码:
pip install forge-guardrails python -m forge.proxy --backend-url http://localhost:8080 --port 8081
配置好后,把你的客户端指向 http://localhost:8081/v1。Forge 会自动做以下事情:
- 响应校验:检查每个 tool call 的工具名和参数格式
- 救援解析:当模型用非标准格式输出时(如 JSON 代码块、Mistral 的
[TOOL_CALLS]格式、Qwen 的 XML 标签),自动提取结构化调用并转换回 OpenAI 标准 schema - 重试循环:校验失败自动重试(默认 3 次),客户端感知不到异常
- 合成
respond工具注入:给模型一个专用的文本回复工具,避免小模型在 text 和 tool call 之间混乱抉择
更妙的是,Proxy 模式同时支持 OpenAI 和 Anthropic 两种 API 格式。配 Claude Code 只需设置:
ANTHROPIC_BASE_URL=http://localhost:8081 ANTHROPIC_AUTH_TOKEN=*** claude
2. WorkflowRunner 模式(Python SDK)
如果需要在代码中精细控制多步骤工作流,直接用 WorkflowRunner:
import asyncio
from pydantic import BaseModel, Field
from forge import (
Workflow, ToolDef, ToolSpec,
WorkflowRunner, LlamafileClient,
ContextManager, TieredCompact,
)
def get_weather(city: str) -> str:
return f"72°F and sunny in {city}"
class GetWeatherParams(BaseModel):
city: str = Field(description="城市名称")
workflow = Workflow(
name="weather",
description="查询城市天气",
tools={
"get_weather": ToolDef(
spec=ToolSpec(
name="get_weather",
description="获取当前天气",
parameters=GetWeatherParams,
),
callable=get_weather,
),
},
terminal_tool="get_weather",
)
async def main():
client = LlamafileClient(
gguf_path="path/to/model.gguf",
mode="native",
)
ctx = ContextManager(
strategy=TieredCompact(keep_recent=2),
budget_tokens=8192
)
runner = WorkflowRunner(client=client, context_manager=ctx)
await runner.run(workflow, "What's the weather in Paris?")
asyncio.run(main())
WorkflowRunner 比 Proxy 多两个能力:步骤顺序约束(比如先 create_task 再 complete_task)和上下文压缩(基于 token 预算自动精简历史记录)。
3. Guardrails 中间件模式(嵌入现有循环)
如果已经有自己的编排逻辑,只想借用 Forge 的 guardrails 能力:
from forge.guardrails import ResponseValidator, RescueParser validator = ResponseValidator(tools=my_tools) parser = RescueParser() model_response = await my_llm_call(messages) parsed = parser.rescue(model_response) validated = validator.check(parsed)
这种模式最灵活——你可以保留自己的循环逻辑,只让 Forge 处理”模型输出不可靠”这个核心痛點。
基准测试:数据不说谎
Forge 的 README 给出了令人信服的评测数据:
| 模型 | 无 Forge | 有 Forge | 提升 |
|---|---|---|---|
| 8B 本地模型 | 个位数 | 84% | 巨大 |
| Ministral 3-8B (Q8) | 53% | 99% | 46pp |
| Sonnet 4.6 (API) | 85% | 98% | 13pp |
注意最后一行:即使是 Sonnet 4.6 这样的顶级模型,在 Forge 的 guardrails 帮助下也从 85% 提升到了 98%。这说明无论模型大小,工具调用的输出一致性都不是”一定有”的事。
实际使用技巧
1. 选对后端和量化
Forge 官方推荐 llama-server + Ministral-3-8B-Instruct Q8_0。评测中 top 10 的配置都在 llama-server 上跑出。如果硬件有限,Ollama 也可以,但更复杂的工作负载上效果稍弱。
llama-server -m Ministral-3-8B-Instruct-2512-Q8_0.gguf --jinja -ngl 999 --port 8080
2. Proxy 模式下调整重试次数
默认 3 次重试对大部分场景足够。如果模型的输出质量特别不稳定(比如更低量化的 4-bit 模型),可以增加:
python -m forge.proxy --backend-url http://localhost:8080 --max-retries 5
3. 利用 SlotWorker 共享 GPU
Forge 的 SlotWorker 支持优先级队列和自动抢占——多个 workflow 共享同一块 GPU,高优任务可以中断低优任务的推理槽。适合多 Agent 架构中专业 workflow 共享 GPU 的场景。
适用场景
Forge 最适合三种情况:
- 自研 LLM + 工具调用:用本地模型做 agent,输出总是不稳定
- 降本优化:用小模型 + Forge guardrails 替代大模型 API 调用,成本效益明显
- 离线环境:不能连外网,但需要可靠的 agent 工作流
Forge 不是 agent 编排器。如果你需要多 Agent 协作、DAG 规划器,还是需要其他框架。但如果你只需要让一个 agent 的工具调用不出错,Forge 是目前最成熟的方案。
GitHub: github.com/antoinezambelli/forge
PyPI: pip install forge-guardrails