real_agent¶
Level 6 · Real LLM — the first example that talks to an actual model.
Every other curated example runs on MockModelProvider so it's free and
deterministic. real_agent calls a live model: it prefers the ChatGPT
subscription credential written by codex login, then falls back to
ANTHROPIC_API_KEY. It's the bridge from "the framework runs" to "the
framework answers."
- Prerequisites:
pip install "symfonic-core[openai]"+codex login, orpip install "symfonic-core[anthropic]"+ANTHROPIC_API_KEY - Key concepts: automatic provider selection,
CodexOAuthProvider,AnthropicProvider
Get it and run it¶
Installed via pip? Copy it in and run against a real model — no checkout:
pip install "symfonic-core[cli,openai]"
codex login
symfonic examples add real_agent
python -m real_agent "What is the largest planet in our solar system?"
Or from a source checkout (run from the repo root):
Expected output:
Provider: Codex OAuth (gpt-5.6-sol)
Query: What is the largest planet in our solar system?
---
Response: Jupiter is the largest planet in our solar system.
Nodes: ['react']
Full code¶
"""Real LLM example — uses Codex OAuth or Anthropic's Claude API.
Provider selection defaults to ``auto``: Codex OAuth from ``codex login`` is
preferred, then ``ANTHROPIC_API_KEY`` is used as a fallback. Override with
``SYMFONIC_EXAMPLE_PROVIDER=codex`` or ``=anthropic``.
Usage: python -m examples.real_agent
python -m examples.real_agent "Your custom question here"
"""
import asyncio
import sys
from symfonic.core import (
AgentGraph,
AgentRuntime,
BaseAgentDeps,
)
from .provider import select_live_provider
async def main() -> None:
selected = select_live_provider()
if selected is None:
sys.exit(1)
query = " ".join(sys.argv[1:]) if len(sys.argv) > 1 else "What is symfonic? Make up a creative answer in 2 sentences."
config = selected.config
deps = BaseAgentDeps(ModelProvider=selected.provider)
graph = AgentGraph()
runtime = AgentRuntime(graph=graph, deps=deps, config=config)
print(f"Provider: {selected.label}")
print(f"Query: {query}")
print("---")
result = await runtime.run(query)
print(f"Response: {result['final_response']}")
print(f"Nodes: {result['node_execution_log']}")
if __name__ == "__main__":
asyncio.run(main())
Step by step¶
1. Select credentials and provider¶
In auto mode, the selector first checks the environment and
~/.codex/auth.json for a Codex credential. If the [openai] extra or Codex
credential is unavailable, it uses ANTHROPIC_API_KEY. Optional .env
loading remains supported when python-dotenv is installed.
Force a provider when testing a specific wire path:
SYMFONIC_EXAMPLE_PROVIDER=codex python -m real_agent
SYMFONIC_EXAMPLE_PROVIDER=anthropic python -m real_agent
2. Wire the selected provider and its model¶
deps = BaseAgentDeps(ModelProvider=selected.provider)
runtime = AgentRuntime(graph=graph, deps=deps, config=selected.config)
Provider and model travel together so Codex never receives Claude's default model name, and an explicit Anthropic run keeps its Claude model.
3. Run and read the answer¶
Same AgentRuntime.run as the mock examples; now final_response carries a
genuine model completion. Pass a question on the command line
(python -m real_agent "...") or it uses a built-in default.
Going further¶
- Swap the provider for another vendor —
OpenRouterProvider,AWSBedrockProvider— the rest of the code is unchanged. See Model Providers. - Add memory so the model reasons over stored context → see
real_agent_with_memoryin the Examples Index. - Ask for a validated object back → Structured Output.
See also¶
- Model Providers
- minimal_agent — the same graph on a mock provider