{"slug": "building-ai-agents-with-agno-i-actually-ran-it-with-gemini-and-built-in-tools", "title": "Building AI Agents with Agno — I Actually Ran It with Gemini and Built-in Tools", "summary": "A developer tested Agno v2.6.17, a lightweight AI agent framework that rebranded from Phidata in early 2025, using Gemini 2.5 Flash and built-in tools. The framework supports model-agnostic, multimodal, and multi-agent orchestration with minimal boilerplate. The developer encountered traps including a deprecated show_tool_calls parameter and a deprecated gemini-2.0-flash model, recommending debug_mode=True and gemini-2.5-flash instead.", "body_md": "If you've ever felt like LangChain was too heavy, you're not alone. The dependency tree is enormous. Abstraction layers pile up. At some point you lose track of what's actually happening underneath. That frustration has pushed a lot of people toward lighter alternatives — frameworks that prove you can build a capable agent without a hundred transitive dependencies.\n\nAgno is one of those alternatives. It started as Phidata and rebranded in early 2025. I spent an afternoon installing Agno v2.6.17 in a clean sandbox and running through Calculator tools, Wikipedia retrieval, Pydantic structured output, and a two-agent Team. I'll share the real execution logs and, more importantly, the traps I hit that the docs don't warn you about.\n\nPhidata built a solid reputation as \"the Python framework for AI assistants.\" When it rebranded to Agno in 2025, the design philosophy got articulated more clearly around three ideas.\n\n**Model-agnostic from day one.** Over 70 LLMs — OpenAI, Anthropic, Google, Ollama, Cohere — can plug in with the same code structure. Swap the model, keep the agent logic.\n\n**Multimodal as a default.** Text, image, audio, video agents all use the same API surface. You don't need a different abstraction layer for each modality.\n\n**Multi-agent orchestration as a first-class citizen.** The `Team`\n\nclass is built in. You can switch between `coordinate`\n\n, `route`\n\n, and `collaborate`\n\nmodes with a single parameter change.\n\nReading that, I thought: \"How is this different from LangChain?\" The answer showed up when I actually wrote code. Agno favors composition over class inheritance. One agent takes about 6 lines to set up. There's far less boilerplate to wade through.\n\n```\npip install agno google-genai ddgs wikipedia\n```\n\nThe `agno`\n\npackage installs just the core. Tools require their own extra dependencies — `wikipedia`\n\nfor the Wikipedia tool, `google-genai`\n\nfor Gemini. This lazy-loading approach keeps the base install clean.\n\n``` python\n$ python3 -c \"import agno; print(agno.__version__)\"\n2.6.17\n```\n\nI used the Gemini API key from my project `.env`\n\n. Agno auto-initializes the Gemini client from either `GOOGLE_API_KEY`\n\nor `GEMINI_API_KEY`\n\n. If both are set, it uses `GOOGLE_API_KEY`\n\nand prints a warning to stdout. Not a big deal, but you can't suppress it easily from code.\n\n``` python\nfrom agno.agent import Agent\nfrom agno.models.google import Gemini\nfrom agno.tools.calculator import CalculatorTools\n\nagent = Agent(\n    model=Gemini(id=\"gemini-2.5-flash\"),\n    tools=[CalculatorTools()],\n    description=\"A math helper agent\",\n)\n\nresponse = agent.run(\"What is 2^10 + 3^5? Please use the calculator.\")\nprint(response.content)\n```\n\nOutput:\n\n```\n2^10 is 1024 and 3^5 is 243. Adding them gives 1267.\n⏱ 8.98s\n```\n\nThe math is right: 1024 + 243 = 1267. The agent invoked the Calculator tool rather than letting the LLM guess. The 9-second latency includes a Gemini API round-trip plus the tool call overhead.\n\n**Trap #1: show_tool_calls is gone.** Older Agno tutorials use\n\n`show_tool_calls=True`\n\n. In v2.6.17, that raises `TypeError: Agent.__init__() got an unexpected keyword argument 'show_tool_calls'`\n\n. Use `debug_mode=True`\n\ninstead if you want verbose output.**Trap #2: gemini-2.0-flash is deprecated.** Using that model ID throws a 404:\n\n```\nERROR    Error from Gemini API: 404 NOT_FOUND.\n{'error': {'message': 'This model models/gemini-2.0-flash is no longer available.'}}\n```\n\nUse `gemini-2.5-flash`\n\n. Always verify the current model IDs on Google's docs before hardcoding them.\n\n``` python\nfrom agno.tools.wikipedia import WikipediaTools\n\nagent = Agent(\n    model=Gemini(id=\"gemini-2.5-flash\"),\n    tools=[WikipediaTools()],\n)\n\nresponse = agent.run(\n    \"What is the 'attention mechanism' in neural networks? 2 sentences only.\"\n)\n```\n\nExecution log:\n\n```\nINFO Searching wikipedia for: attention mechanism neural networks\nERROR Error searching Wikipedia for 'attention mechanism neural networks':\n      Page id \"attention mechanism neural network\" does not match any pages.\nINFO Searching wikipedia for: attention (machine learning)\n⏱ 9.98s\n\nIn machine learning, attention is a method that determines the importance\nof each component in a sequence relative to the other components...\n```\n\nThe interesting bit: the first search failed, and the agent automatically reformulated the query (`attention (machine learning)`\n\n) and retried. No extra code required. Agno runs a ReAct loop internally — plan, act, observe, adjust. Tool failures are handled gracefully.\n\nCompared with the code-execution approach in Smolagents (covered in the [Python AI agent library comparison post](https://dev.to/en/blog/en/python-ai-agent-library-comparison-2026)), Agno leans more toward tool composition than code generation. Neither is strictly better; it depends on what you're building.\n\n`output_schema`\n\n, Not `output_model`\n\nThis is the most confusing naming in the API. There's a parameter called `output_model`\n\n. Naturally you'd think: \"Put the Pydantic model here.\" That's wrong.\n\n```\n# This fails\nagent = Agent(\n    model=Gemini(id=\"gemini-2.5-flash\"),\n    output_model=DeveloperProfile,  # ← WRONG\n)\n# ValueError: Model must be a Model instance, string, or None\n```\n\n`output_model`\n\nexpects an LLM model instance (or string model ID). For Pydantic structured output, use `output_schema`\n\n:\n\n``` python\nfrom pydantic import BaseModel\nfrom typing import List\n\nclass Skill(BaseModel):\n    name: str\n    level: str\n    year_since: int\n\nclass DeveloperProfile(BaseModel):\n    name: str\n    skills: List[Skill]\n    summary: str\n\nagent = Agent(\n    model=Gemini(id=\"gemini-2.5-flash\"),\n    output_schema=DeveloperProfile,  # ← CORRECT\n)\n\nresponse = agent.run(\n    \"Create a developer profile for 'Kim Jangwook', a Korean developer \"\n    \"specializing in Claude Code, MCP, Python, TypeScript.\"\n)\n\nprint(type(response.content))   # <class '__main__.DeveloperProfile'>\nprint(response.content.name)    # Kim Jangwook\n```\n\nActual output:\n\n```\n⏱ 4.00s\nType: DeveloperProfile\nName: Kim Jangwook\nSkills:\n  - Claude Code: Expert (since 2022)\n  - MCP: Certified (since 2019)\n  - Python: Senior (since 2018)\n  - TypeScript: Intermediate (since 2020)\n```\n\n`response.content`\n\nreturns an actual Pydantic instance. Parsing is handled internally; you get full IDE autocomplete on the result. The 4-second latency (vs 9 seconds for the Calculator agent) reflects the absence of tool call round-trips.\n\nThis is similar in spirit to [PydanticAI's output_type parameter](https://dev.to/en/blog/en/pydantic-ai-type-safe-agent-tutorial-2026), but the naming diverges. When jumping between frameworks, you need to memorize each one's vocabulary — that's friction that accumulates.\n\n`members=`\n\n, Not `agents=`\n\n``` python\nfrom agno.team import Team\n\nresearcher = Agent(\n    name=\"Researcher\",\n    model=Gemini(id=\"gemini-2.5-flash\"),\n    tools=[WikipediaTools()],\n    role=\"researcher\",\n)\n\ncalculator = Agent(\n    name=\"Calculator\",\n    model=Gemini(id=\"gemini-2.5-flash\"),\n    tools=[CalculatorTools()],\n    role=\"calculator\",\n)\n\nteam = Team(\n    members=[researcher, calculator],  # ← NOT agents=\n    model=Gemini(id=\"gemini-2.5-flash\"),\n    name=\"Research & Calc Team\",\n    mode=\"coordinate\",\n)\n```\n\n**Trap #3: agents= doesn't exist in Team.** Writing\n\n`Team(agents=[...])`\n\nthrows:\n\n```\nTypeError: Team.__init__() got an unexpected keyword argument 'agents'\n```\n\nThe correct parameter is `members=[...]`\n\n. You'd only know this from reading the source — the documentation still shows `agents=`\n\nin some places.\n\nRunning the team:\n\n```\nresponse = team.run(\n    \"Find the year 'Attention is All You Need' was published on Wikipedia, \"\n    \"then calculate how many years ago that was from 2026.\"\n)\nprint(response.content)\n```\n\nResult:\n\n```\nINFO Searching wikipedia for: Attention is All You Need\n⏱ 13.83s\n\n'Attention is All You Need' was published in 2017. \nAs of 2026, that is 9 years ago.\n```\n\nThe team leader (the Gemini model passed to `Team`\n\n) analyzed the task, routed the Wikipedia lookup to the Researcher agent and the subtraction to the Calculator agent. Both returned correct results. The 14-second latency reflects sequential agent execution — `coordinate`\n\nmode doesn't parallelize in v2.6.17.\n\nOne of Agno's practical advantages: the built-in tool library.\n\n``` python\nimport agno.tools as t, pkgutil\ntools = [name for _, name, _ in pkgutil.iter_modules(t.__path__)]\n# Over 100 entries including: 'arxiv', 'bravesearch', 'calculator',\n# 'docker', 'duckduckgo', 'email', 'github', 'gmail',\n# 'google_bigquery', 'jira', 'mcp', 'mem0', 'notion',\n# 'postgres', 'slack', 'sql', 'tavily', 'wikipedia',\n# 'yfinance', 'youtube', 'zoom', ...\n```\n\nIn practice: give Agno a `BRAVE_API_KEY`\n\nand you have a web search agent running in under 5 minutes without writing any API wrapper code. Same story for Slack, Notion, GitHub, and Postgres integrations.\n\nThe catch: not all tools are zero-install. Each tool module has its own dependency. `agno.tools.duckduckgo`\n\nneeds `ddgs`\n\n, `agno.tools.wikipedia`\n\nneeds `wikipedia`\n\n, and so on. If you import before installing, you get `ImportError`\n\nat the import line for some tools and at first use for others. Inconsistent behavior across modules.\n\nThe latency is real. 9 seconds for a single Calculator call, 14 for a two-agent team — this is Gemini API round-trip cost compounded by tool calls, not an Agno inefficiency per se. But it matters for production APIs where users expect sub-second responses.\n\nDebugging is manual. `debug_mode=True`\n\nspits out unstructured logs. I haven't found an official integration guide for LangSmith or LangFuse. If observability matters, you'll need to wire it up yourself.\n\nThe docs lag behind the API. `show_tool_calls`\n\n, `output_model`\n\n, `agents=`\n\n— these are examples of parameters whose behavior in the docs doesn't match the current codebase. Always check the GitHub `examples/`\n\ndirectory for the latest version, not the tutorial blog posts.\n\nThe Team's `coordinate`\n\nmode is sequential. If you need parallel agent execution or complex conditional branching across many agents, [Google ADK or LangGraph](https://dev.to/en/blog/en/google-adk-vs-langgraph-agent-framework-comparison-2026) are better fits.\n\nThree scenarios where I'd reach for Agno:\n\n**Rapid prototyping.** An API key plus 10 lines of Python and you have a working agent. Great for PoCs, internal tools, solo projects where speed to first working version matters more than architectural elegance.\n\n**Multi-tool agents.** When you need an agent that touches Slack, reads from Postgres, sends an email, and searches the web — Agno's tool library means you spend time on the agent logic, not on writing API wrappers.\n\n**Small agent teams (2-4 agents).** Agno's `Team`\n\nclass handles small coordination problems cleanly. Once you get into dozens of agents with complex dependency graphs, a state-graph framework gives you more explicit control.\n\nWhere I wouldn't use Agno: real-time streaming UIs, production workflows requiring precise error handling and retry guarantees, or systems where you need to audit exactly what each agent decided and why at every step.\n\nTwo things I didn't test today:\n\n**Agent memory.** Agno has `enable_agentic_memory=True`\n\nwith SQLite-backed storage. Cross-session memory persistence is the piece that would make agents feel genuinely stateful rather than starting fresh each time.\n\n**MCP tool integration.** `agno.tools.mcp`\n\nexists. If Agno agents can connect to MCP servers as tool sources, that means reusing existing MCP server infrastructure without rewriting anything. Worth testing.\n\n`pip install agno`\n\n; Calculator, Wikipedia, Team all ran successfully`gemini-2.5-flash`\n\nas the model ID — `gemini-2.0-flash`\n\nis deprecated and returns 404`output_schema=YourPydanticModel`\n\n, not `output_model`\n\n`Team`\n\ntakes `members=[...]`\n\n, not `agents=[...]`\n\nIf you've been frustrated by LangChain's weight and want a Python agent framework that gets out of your way, Agno is worth an afternoon of experimentation.", "url": "https://wpnews.pro/news/building-ai-agents-with-agno-i-actually-ran-it-with-gemini-and-built-in-tools", "canonical_source": "https://dev.to/jangwook_kim_e31e7291ad98/building-ai-agents-with-agno-i-actually-ran-it-with-gemini-and-built-in-tools-49in", "published_at": "2026-06-18 06:41:11+00:00", "updated_at": "2026-06-18 06:51:21.675705+00:00", "lang": "en", "topics": ["ai-agents", "large-language-models", "developer-tools", "generative-ai", "natural-language-processing"], "entities": ["Agno", "Phidata", "Gemini", "Google", "LangChain", "OpenAI", "Anthropic", "Ollama"], "alternates": {"html": "https://wpnews.pro/news/building-ai-agents-with-agno-i-actually-ran-it-with-gemini-and-built-in-tools", "markdown": "https://wpnews.pro/news/building-ai-agents-with-agno-i-actually-ran-it-with-gemini-and-built-in-tools.md", "text": "https://wpnews.pro/news/building-ai-agents-with-agno-i-actually-ran-it-with-gemini-and-built-in-tools.txt", "jsonld": "https://wpnews.pro/news/building-ai-agents-with-agno-i-actually-ran-it-with-gemini-and-built-in-tools.jsonld"}}