{"data":{"slug":"antoinezambelli-forge","name":"forge","tagline":"A Python framework for self-hosted LLM tool-calling and multi-step agentic workflows","github_url":"https://github.com/antoinezambelli/forge","owner":"antoinezambelli","repo":"forge","owner_avatar_url":"https://avatars.githubusercontent.com/u/2261593?v=4","primary_language":"Python","stars":2174,"forks":166,"topics":["agentic-ai","agentic-workflow","agents","function-calling","llama-cpp","llamafile","llm","ollama","python","self-hosted","tool-calling"],"archived":false,"github_pushed_at":"2026-07-10T15:30:45+00:00","maintenance_label":"Very active","url":"https://www.graphcanon.com/tools/antoinezambelli-forge","markdown_url":"https://www.graphcanon.com/tools/antoinezambelli-forge.md","api_url":"https://www.graphcanon.com/api/graphcanon/tools/antoinezambelli-forge","graph_url":"https://www.graphcanon.com/api/graphcanon/graph?tool=antoinezambelli-forge","description":"A Python framework for self-hosted LLM tool-calling and multi-step agentic workflows","homepage_url":null,"license":"MIT","open_issues":3,"watchers":13,"ai_summary":null,"readme_excerpt":"## Requirements\n\n- Python 3.12+\n- A running LLM backend (see below)\n\n---\n\n## Install\n\n```bash\npip install forge-guardrails                # core only\npip install \"forge-guardrails[anthropic]\"   # + Anthropic client\n```\n\nFor development:\n\n```bash\ngit clone https://github.com/antoinezambelli/forge.git\ncd forge\npip install -e \".[dev]\"\n```\n\n---\n\n# Install from https://github.com/ggml-org/llama.cpp/releases\nllama-server -m path/to/Ministral-3-8B-Instruct-2512-Q8_0.gguf --jinja -ngl 999 --port 8080\n```\n\n**Ollama** (alternative — easier setup, slightly weaker on harder workloads):\n```bash\n\n---\n\n# Install from https://ollama.com/download\nollama pull ministral-3:8b-instruct-2512-q4_K_M\n```\n\n**Anthropic** (API, no local GPU needed):\n```bash\npip install -e \".[anthropic]\"\nexport ANTHROPIC_API_KEY=sk-...\n```\n\nSee [Backend Setup](docs/BACKEND_SETUP.md) for full instructions and [Model Guide](docs/MODEL_GUIDE.md) for which model fits your hardware.\n\n---\n\n## Quick Start\n\nStart llama-server however you normally do (e.g. in a separate shell):\n\n```bash\nllama-server -m path/to/Ministral-3-8B-Instruct-2512-Q8_0.gguf --jinja -ngl 999 --port 8080\n```\n\nThen the Python you'll run (e.g. from another shell):\n\n```python\nimport asyncio\nfrom pydantic import BaseModel, Field\nfrom forge import (\n    Workflow, ToolDef, ToolSpec,\n    WorkflowRunner, LlamafileClient,\n    ContextManager, TieredCompact,\n)\n\ndef get_weather(city: str) -> str:\n    return f\"72°F and sunny in {city}\"\n\nclass GetWeatherParams(BaseModel):\n    city: str = Field(description=\"City name\")\n\nworkflow = Workflow(\n    name=\"weather\",\n    description=\"Look up weather for a city.\",\n    tools={\n        \"get_weather\": ToolDef(\n            spec=ToolSpec(\n                name=\"get_weather\",\n                description=\"Get current weather\",\n                parameters=GetWeatherParams,\n            ),\n            callable=get_weather,\n        ),\n    },\n    required_steps=[],\n    terminal_tool=\"get_weather\",\n    system_prompt_template=\"You are a helpful assistant. Use the available tools to answer the user.\",\n)\n\nasync def main():\n    client = LlamafileClient(\n        gguf_path=\"path/to/Ministral-3-8B-Instruct-2512-Q8_0.gguf\",\n        mode=\"native\",\n        recommended_sampling=True,\n    )\n    ctx = ContextManager(strategy=TieredCompact(keep_recent=2), budget_tokens=8192)\n    runner = WorkflowRunner(client=client, context_manager=ctx)\n    await runner.run(workflow, \"What's the weather in Paris?\")\n\nasyncio.run(main())\n```\n\nFor multi-step workflows, multi-turn conversations, and backend auto-management, see the [User Guide](docs/USER_GUIDE.md). If you're building a long-running session (CLI, chat server, voice assistant), see the [long-running session advisory](docs/USER_GUIDE.md#long-running-sessions-filtering-transient-messages) for important guidance on filtering transient messages.\n\n---\n\n### Docker\n\nYou can run the forge proxy as a Docker container.\n\n**Build the image:**\n\n```bash\ndocker build -t forge-proxy .\n```\n\n**Run the container:**\n\n```bash\n\n---\n\n## License\n\n[MIT](LICENSE) — Copyright (c) 2025-2026 Antoine Zambelli","github_created_at":"2026-02-16T16:59:06+00:00","created_at":"2026-07-15T11:18:20.276827+00:00","updated_at":"2026-07-15T11:18:23.030645+00:00","categories":[{"slug":"ai-agents","name":"AI Agents","url":"https://www.graphcanon.com/categories/ai-agents","markdown_url":"https://www.graphcanon.com/categories/ai-agents.md","api_url":"https://www.graphcanon.com/api/graphcanon/categories/ai-agents"},{"slug":"inference-serving","name":"Inference & Serving","url":"https://www.graphcanon.com/categories/inference-serving","markdown_url":"https://www.graphcanon.com/categories/inference-serving.md","api_url":"https://www.graphcanon.com/api/graphcanon/categories/inference-serving"},{"slug":"llm-frameworks","name":"LLM Frameworks","url":"https://www.graphcanon.com/categories/llm-frameworks","markdown_url":"https://www.graphcanon.com/categories/llm-frameworks.md","api_url":"https://www.graphcanon.com/api/graphcanon/categories/llm-frameworks"}],"tags":[{"slug":"agentic-ai","name":"agentic-ai"},{"slug":"agentic-workflow","name":"agentic-workflow"},{"slug":"agents","name":"agents"},{"slug":"function-calling","name":"function-calling"},{"slug":"llama-cpp","name":"llama-cpp"},{"slug":"llamafile","name":"llamafile"},{"slug":"llm","name":"llm"},{"slug":"ollama","name":"ollama"}],"trust":{"provenance":{"is_fork":false,"github_id":1159381774,"owner_type":"User","methodology":"github_public_v1","parent_repo":null,"near_duplicate_slugs":[]},"computed_at":"2026-07-15T11:18:21.243Z","maintenance":{"label":"Very active","score":96,"methodology":"github_public_v1","releases_90d":9,"days_since_push":4,"last_release_at":"2026-07-10T05:09:35Z"},"security_summary":{"status":"no_lockfile","scanner":null,"low_count":0,"high_count":0,"last_scan_at":"2026-07-15T11:18:21.670Z","medium_count":0,"scan_profile":"none","critical_count":0}},"capability_facts":{"scan":{"source":"repo_scan","observed_at":"2026-07-15T11:18:21.004Z"},"deploy":{"source":"dockerfile:Dockerfile","self_host":true,"observed_at":"2026-07-15T11:18:21.004Z","managed_saas":false},"has_cli":{"value":true,"source":"pyproject.toml:[project.scripts]","observed_at":"2026-07-15T11:18:21.004Z"},"languages":{"value":["python"],"source":"github.language+pyproject.toml","observed_at":"2026-07-15T11:18:21.004Z"},"has_docker":{"value":true,"source":"dockerfile:Dockerfile","observed_at":"2026-07-15T11:18:21.004Z"},"license_spdx":{"value":"MIT","source":"github.license","observed_at":"2026-07-15T11:18:21.004Z"}}}}