开源项目

forge

为自托管LLM提供可靠性层的Python框架,专注于工具调用和多步骤agent工作流。通过防护栏(重试、步骤强制)和上下文管理(VRAM感知预算、层级压缩),显著提升本地小模型(如8B参数)在复杂任务中的表现。亮点:组合多种可靠机制,即使用作代理服务器也能透明增强现有工具(如opencode、Continue)的LLM调用质量,且附有26场景评测数据证明效果。

README

forge

PyPI Tests codecov Python 3.12+ License: MIT

自托管 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

开源项目antoinezambelli2026-05-21原文

相关内容