forge
为自托管LLM提供可靠性层的Python框架,专注于工具调用和多步骤agent工作流。通过防护栏(重试、步骤强制)和上下文管理(VRAM感知预算、层级压缩),显著提升本地小模型(如8B参数)在复杂任务中的表现。亮点:组合多种可靠机制,即使用作代理服务器也能透明增强现有工具(如opencode、Continue)的LLM调用质量,且附有26场景评测数据证明效果。
README
forge
自托管 LLM 工具调用(tool-calling)的可靠性层。Forge 通过护栏(guardrails,包括救援解析、重试提示、步骤强制)和上下文管理(可感知 VRAM 的预算、分层压缩)将一个 8B 本地模型提升至多步 agent 工作流(multi-step agentic workflows)同类最佳水平。当前最佳自托管配置(Ministral-3 8B Instruct Q8 在 llama-server 上运行)在 forge 的 26 场景评估套件中得分 86.5%——在最困难层级上得分 76%。
三种使用方式:
WorkflowRunner —— 定义工具、选择后端、运行结构化 agent 循环。Forge 管理完整生命周期:系统提示、工具执行、上下文压缩和护栏。SlotWorker 提供优先级队列访问共享推理槽位,支持自动抢占——适用于专业工作流共享 GPU 槽位的多 agent 架构。当你直接基于 forge 构建时最为适用。
Guardrails(护栏)中间件 —— 在你自己的编排循环中使用 forge 的可靠性栈(可组合中间件)。你控制循环;forge 验证响应、修复非格式正确的工具调用、并强制执行所需步骤。
代理服务器 —— 即插即用的 OpenAI 兼容代理(
python -m forge.proxy),位于任意客户端(opencode、Continue、aider 等)与本地模型服务器之间。透明地应用护栏——客户端会认为自己正在与更智能的模型对话。
支持 Ollama、llama-server(llama.cpp)、Llamafile 和 Anthropic 作为后端。
需求
- Python 3.12+
- 一个正在运行的 LLM 后端(见下方)
安装
pip install forge-guardrails # 仅核心
pip install "forge-guardrails[anthropic]" # + Anthropic 客户端
开发环境:
git clone https://github.com/antoinezambelli/forge.git
cd forge
pip install -e ".[dev]"
后端设置(选其一)
llama-server(推荐——前十评估配置均运行于 llama-server):
# 从 https://github.com/ggml-org/llama.cpp/releases 安装
llama-server -m path/to/Ministral-3-8B-Instruct-2512-Q8_0.gguf --jinja -ngl 999 --port 8080
Ollama(替代方案——设置更简单,但较难任务上性能略弱):
# 从 https://ollama.com/download 安装
ollama pull ministral-3:8b-instruct-2512-q4_K_M
Anthropic(API,无需本地 GPU):
pip install -e ".[anthropic]"
export ANTHROPIC_API_KEY=sk-...
快速开始
import asyncio
from pydantic import BaseModel, Field
from forge import (
Workflow, ToolDef, ToolSpec,
WorkflowRunner, OllamaClient,
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,
),
},
required_steps=[],
terminal_tool="get_weather",
system_prompt_template="你是一个乐于助人的助手。使用可用工具回答用户问题。",
)
async def main():
client = OllamaClient(model="ministral-3:8b-instruct-2512-q4_K_M", recommended_sampling=True)
ctx = ContextManager(strategy=TieredCompact(keep_recent=2), budget_tokens=8192)
runner = WorkflowRunner(client=client, context_manager=ctx)
await runner.run(workflow, "巴黎的天气怎么样?")
asyncio.run(main())
关于多步工作流、多轮对话和后端自动管理,请参阅用户指南。如果你正在构建长期运行的会话(CLI、聊天服务器、语音助手),请阅读长期运行会话建议中关于过滤瞬时消息的重要指引。
代理服务器
可替换本地模型服务器的即插即用方案。将任意 OpenAI 兼容客户端指向代理,即可免费获得 forge 的护栏功能。
# 外部模式——你自行管理 llama-server,forge 代理它
python -m forge.proxy --backend-url http://localhost:8080 --port 8081
# 托管模式——forge 同时启动 llama-server 和代理
python -m forge.proxy --backend llamaserver --gguf path/to/model.gguf --port 8081
然后将客户端配置为使用 http://localhost:8081/v1 作为 API 基础 URL。
注意: 当请求中存在工具时,代理会自动注入一个合成 respond 工具。模型会调用 respond(message="...") 而不是生成纯文本,使其保持在工具调用模式下,以便 forge 完整的护栏栈得以应用。出站响应中会剥离 respond 调用——客户端看到一个正常的文本响应(finish_reason: "stop"),完全不知道该工具的存在。这对于小型本地模型(~8B)至关重要——它们无法可靠地在文本和工具调用之间做出正确选择,引导它们使用工具是必要的。完整分析请参见 ADR-013。
后端
| 后端 | 最适用于 | 原生函数调用 (Native FC)? |
|---|---|---|
| Ollama | 最简单设置,内置模型管理 | 是 |
| llama-server | 最佳性能,完全控制 | 是(需 --jinja) |
| Llamafile | 单二进制文件,零依赖 | 否(提示注入) |
| Anthropic | 前沿基线,混合工作流 | 是 |
运行测试
python -m pytest tests/ -v --tb=short
python -m pytest tests/ --cov=forge --cov-report=term-missing
评估框架
26 个场景,衡量模型+后端组合在多步工具调用工作流中的可靠性——分为 OG-18 基线层级和 8 个场景的高级推理层级,用于顶级区分。完整 CLI 参考请参见评估指南。
# llama-server(先在另一个终端启动;参见评估指南)
python -m tests.eval.eval_runner --backend llamafile --llamafile-mode prompt --gguf "path/to/Ministral-3-8B-Instruct-2512-Q8_0.gguf" --runs 10 --stream --verbose
# 批量评估(JSONL 输出,自动断点续跑)
python -m tests.eval.batch_eval --config all --runs 50
# 报告(ASCII 表格、HTML 仪表盘、Markdown 视图)
python -m tests.eval.report eval_results.jsonl
项目结构
src/forge/
__init__.py # 公开 API 导出
errors.py # ForgeError 异常层级
server.py # setup_backend(), ServerManager, BudgetMode
core/
messages.py # Message, MessageRole, MessageType, MessageMeta
workflow.py # ToolSpec, ToolDef, ToolCall, TextResponse, Workflow
inference.py # run_inference() —— 共享前半部分(压缩、折叠、验证、重试)
runner.py # WorkflowRunner —— agent 循环
slot_worker.py # SlotWorker —— 优先级队列槽位访问
steps.py # StepTracker
guardrails/
nudge.py # Nudge 数据类
response_validator.py # ResponseValidator, ValidationResult
step_enforcer.py # StepEnforcer, StepCheck
error_tracker.py # ErrorTracker
clients/
base.py # ChunkType, StreamChunk, LLMClient 协议
ollama.py # OllamaClient(原生函数调用)
llamafile.py # LlamafileClient(原生函数调用或提示注入)
anthropic.py # AnthropicClient(前沿基线)
context/
manager.py # ContextManager, CompactEvent
strategies.py # CompactStrategy, NoCompact, TieredCompact, SlidingWindowCompact
hardware.py # HardwareProfile, detect_hardware()
prompts/
templates.py # 工具提示构建器(提示注入路径)
nudges.py # 重试和步骤强制提示模板
tools/
respond.py # 合成 respond 工具 (respond_tool(), respond_spec())
proxy/
proxy.py # ProxyServer —— 程序化启动/停止 API
server.py # 原始 asyncio HTTP 服务器,SSE 流式传输
handler.py # 请求处理器 —— HTTP 与 run_inference 之间的桥梁
convert.py # OpenAI 消息 ↔ forge 消息转换
tests/
unit/ # 865 个确定性测试 —— 无需 LLM 后端
eval/ # 评估框架 —— 用于对真实后端进行模型认证
文档
- 用户指南 —— 使用模式、多轮对话、上下文管理、护栏、槽位工作器、长期运行会话建议
- 模型指南 —— 根据硬件选择模型和后端
- 后端设置 —— 后端安装和服务器设置
- 评估指南 —— 评估框架 CLI 参考、批量评估
- 架构 —— 完整设计文档
- 工作流内部 —— 工作流设计和运行器内部
- 贡献指南 —— 如何设置、测试以及添加新后端或新场景
论文
Forge 护栏框架及消融研究以论文形式发表:
Zambelli, A. Forge: A Reliability Layer for Self-Hosted LLM Tool-Calling. https://doi.org/10.1145/3786335.3813193
预发表版本也提供在 docs/forge_ieee_preprint.pdf —— 作为历史文档保留。请引用上述已发表版本;DOI 链接可能因出版商发布时间不同而无法立即解析。
许可协议
MIT —— 版权所有 (c) 2025-2026 Antoine Zambelli