Model Parameter
One model parameter, one canonical name — model=
model= is the canonical name for the model on every agent class; llm= is a deprecated alias for it.
Quick Start
- Use the canonical name
python from praisonaiagents import Agent agent = Agent( instructions="Summarise the given article in three bullets.", model="gpt-4o", ) agent.start("<article text>") - The deprecated alias still works
python from praisonaiagents import Agent agent = Agent( instructions="Summarise the given article.", llm="gpt-4o", ) - Passing both is refused
python from praisonaiagents import Agent # ❌ Passing both is refused Agent(instructions="…", llm="gpt-4o", model="gpt-3.5-turbo") # TypeError: Agent() received both llm= and model=. They are the same # parameter, so passing both is ambiguous. Pass only one; model= is # the canonical name (llm= is a deprecated alias).
How It Works
Every agent class routes llm= and model= through one resolver so the rule is identical everywhere.
| Call | Result |
|---|---|
Agent(model="gpt-4o") | ✅ Canonical. Preferred everywhere. |
Agent(llm="gpt-4o") | ⚠️ Deprecated alias. Works, emits a DeprecationWarning. |
Agent(llm="gpt-4o", model="gpt-3.5-turbo") | ❌ TypeError — same parameter, so passing both is ambiguous. |
Agent(model=LLMConfig(model="gpt-4o", …)) | ✅ Accepted. Stored as the LLMConfig object (bare Agent uses it directly). |
VisionAgent(model=LLMConfig(model="gpt-4o", …)) (or any media/specialist agent) | ✅ Accepted. Unwrapped to the bare "gpt-4o" string; base_url / api_key on the config are dropped. |
AgentTeam(model=LLMConfig(model="gpt-4o", …)) / AgentFlow(model=LLMConfig(model="gpt-4o", …)) | ✅ Accepted. Unwrapped to the bare "gpt-4o" string before it fills in members. base_url / api_key / fallback_models on the config are dropped for containers today. |
Where It Applies
The llm= / model= pair resolves the same way on every class below.
| Class | Accepts model= | Accepts llm= (deprecated) |
|---|---|---|
Agent | ✅ | ✅ |
AgentTeam | ✅ | ✅ |
AgentFlow | ✅ | ✅ |
VisionAgent | ✅ | ✅ |
AudioAgent | ✅ | ✅ |
OCRAgent | ✅ | ✅ |
VideoAgent | ✅ | ✅ |
EmbeddingAgent | ✅ | ✅ |
ImageAgent | ✅ | ✅ |
ContextAgent | ✅ | ✅ |
CodeAgent | ✅ | ✅ |
RealtimeAgent | ✅ | ✅ |
from praisonaiagents import Agent, AgentTeam, Task
# Default model for members that did not name one themselves
team = AgentTeam(
agents=[Agent(instructions="Researcher"), Agent(instructions="Writer")],
tasks=[Task(description="Write a two-paragraph brief on quantum sensing.")],
model="gpt-4o-mini",
)
team.start()Custom LLM objects
Pass any object with a get_response or get_response_async method to llm= and the agent uses it as its backend instead of the OpenAI default. The tool loop calls llm_instance.get_response(**kwargs) (or its async twin), so those are the two surfaces the agent detects on.
from praisonaiagents import Agent
class MyBackend:
model = "my-backend"
def get_response(self, prompt, **kwargs):
return "answer from my backend"
agent = Agent(instructions="Use my backend.", llm=MyBackend())
agent.start("hello") # routed to MyBackend, not OpenAIAn async-only backend works too — expose get_response_async and the async tool loop drives it. Either method alone is enough; you do not need both.
from praisonaiagents import Agent
class MyAsyncBackend:
model = "my-async-backend"
async def get_response_async(self, prompt, **kwargs):
return "answer from my async backend"
agent = Agent(instructions="Use my async backend.", llm=MyAsyncBackend())
agent.start("hello")The agent detects on get_response and get_response_async, so any backend exposing either works — including the ScriptedModel test double from Offline Testing.
Migration
I use llm= in every example
No code change is required — llm= still works. Move to model= at your convenience; it is the canonical name.
I pass both llm= and model= today
Pick one. model= is the canonical name. Passing both now raises TypeError because the two are the same parameter and guessing a winner could change which vendor is billed.
I pass an LLMConfig to a specialised agent
On VisionAgent, AudioAgent, OCRAgent, VideoAgent, EmbeddingAgent, CodeAgent, RealtimeAgent, ImageAgent, and ContextAgent you no longer need to unwrap an LLMConfig yourself. The class stores its .model string and keeps its own base_url= / api_key=.
I pass an LLMConfig to a container (AgentTeam / AgentFlow)
AgentTeam(llm=LLMConfig(...)) and AgentFlow(llm=LLMConfig(...)) unwrap the config to its .model string before filling in members. Before this fix, the raw LLMConfig was pushed into every member and each member’s chat() returned None silently. base_url, api_key, auth, and fallback_models on the config are dropped for containers today — pin those on the individual member Agent(s) if you need them.
I use CodeAgent(llm=…), RealtimeAgent(llm=…), AgentTeam(llm=…), or AgentFlow(llm=…)
Those four now also accept model= (canonical). The alias llm= still works.