agno 2.3.19__py3-none-any.whl → 2.3.21__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agno/agent/agent.py +2466 -2048
- agno/db/dynamo/utils.py +26 -3
- agno/db/firestore/utils.py +25 -10
- agno/db/gcs_json/utils.py +14 -2
- agno/db/in_memory/utils.py +14 -2
- agno/db/json/utils.py +14 -2
- agno/db/mysql/utils.py +13 -3
- agno/db/postgres/utils.py +13 -3
- agno/db/redis/utils.py +26 -10
- agno/db/schemas/memory.py +15 -19
- agno/db/singlestore/utils.py +13 -3
- agno/db/sqlite/utils.py +15 -3
- agno/db/utils.py +22 -0
- agno/eval/agent_as_judge.py +24 -14
- agno/knowledge/embedder/mistral.py +1 -1
- agno/models/litellm/chat.py +6 -0
- agno/os/routers/evals/evals.py +0 -9
- agno/os/routers/evals/utils.py +6 -6
- agno/os/routers/knowledge/schemas.py +1 -1
- agno/os/routers/memory/schemas.py +14 -1
- agno/os/routers/metrics/schemas.py +1 -1
- agno/os/schema.py +11 -9
- agno/run/__init__.py +2 -4
- agno/run/agent.py +19 -19
- agno/run/cancel.py +65 -52
- agno/run/cancellation_management/__init__.py +9 -0
- agno/run/cancellation_management/base.py +78 -0
- agno/run/cancellation_management/in_memory_cancellation_manager.py +100 -0
- agno/run/cancellation_management/redis_cancellation_manager.py +236 -0
- agno/run/team.py +19 -19
- agno/team/team.py +1217 -1136
- agno/utils/response.py +1 -13
- agno/vectordb/weaviate/__init__.py +1 -1
- agno/workflow/workflow.py +23 -16
- {agno-2.3.19.dist-info → agno-2.3.21.dist-info}/METADATA +60 -129
- {agno-2.3.19.dist-info → agno-2.3.21.dist-info}/RECORD +39 -35
- {agno-2.3.19.dist-info → agno-2.3.21.dist-info}/WHEEL +0 -0
- {agno-2.3.19.dist-info → agno-2.3.21.dist-info}/licenses/LICENSE +0 -0
- {agno-2.3.19.dist-info → agno-2.3.21.dist-info}/top_level.txt +0 -0
agno/utils/response.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import List, Set, Union
|
|
2
2
|
|
|
3
3
|
from agno.exceptions import RunCancelledException
|
|
4
4
|
from agno.models.response import ToolExecution
|
|
@@ -149,15 +149,3 @@ def get_paused_content(run_output: RunOutput) -> str:
|
|
|
149
149
|
elif external_execution_required:
|
|
150
150
|
paused_content = "I have tools to execute, but it needs external execution."
|
|
151
151
|
return paused_content
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
def generator_wrapper(
|
|
155
|
-
event: Union[RunOutputEvent, TeamRunOutputEvent],
|
|
156
|
-
) -> Iterator[Union[RunOutputEvent, TeamRunOutputEvent]]:
|
|
157
|
-
yield event
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
async def async_generator_wrapper(
|
|
161
|
-
event: Union[RunOutputEvent, TeamRunOutputEvent],
|
|
162
|
-
) -> AsyncIterator[Union[RunOutputEvent, TeamRunOutputEvent]]:
|
|
163
|
-
yield event
|
agno/workflow/workflow.py
CHANGED
|
@@ -37,13 +37,16 @@ from agno.models.metrics import Metrics
|
|
|
37
37
|
from agno.run import RunContext, RunStatus
|
|
38
38
|
from agno.run.agent import RunContentEvent, RunEvent, RunOutput
|
|
39
39
|
from agno.run.cancel import (
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
acleanup_run,
|
|
41
|
+
araise_if_cancelled,
|
|
42
|
+
aregister_run,
|
|
43
43
|
cleanup_run,
|
|
44
44
|
raise_if_cancelled,
|
|
45
45
|
register_run,
|
|
46
46
|
)
|
|
47
|
+
from agno.run.cancel import (
|
|
48
|
+
cancel_run as cancel_run_global,
|
|
49
|
+
)
|
|
47
50
|
from agno.run.team import RunContentEvent as TeamRunContentEvent
|
|
48
51
|
from agno.run.team import TeamRunEvent
|
|
49
52
|
from agno.run.workflow import (
|
|
@@ -1879,6 +1882,7 @@ class Workflow:
|
|
|
1879
1882
|
"""Execute a specific pipeline by name asynchronously"""
|
|
1880
1883
|
from inspect import isasyncgenfunction, iscoroutinefunction, isgeneratorfunction
|
|
1881
1884
|
|
|
1885
|
+
await aregister_run(run_context.run_id)
|
|
1882
1886
|
# Read existing session from database
|
|
1883
1887
|
workflow_session, run_context.session_state = await self._aload_or_create_session(
|
|
1884
1888
|
session_id=session_id, user_id=user_id, session_state=run_context.session_state
|
|
@@ -1902,14 +1906,14 @@ class Workflow:
|
|
|
1902
1906
|
elif isasyncgenfunction(self.steps): # type: ignore
|
|
1903
1907
|
async_gen = await self._acall_custom_function(self.steps, execution_input, **kwargs)
|
|
1904
1908
|
async for chunk in async_gen:
|
|
1905
|
-
|
|
1909
|
+
await araise_if_cancelled(workflow_run_response.run_id) # type: ignore
|
|
1906
1910
|
if hasattr(chunk, "content") and chunk.content is not None and isinstance(chunk.content, str):
|
|
1907
1911
|
content += chunk.content
|
|
1908
1912
|
else:
|
|
1909
1913
|
content += str(chunk)
|
|
1910
1914
|
workflow_run_response.content = content
|
|
1911
1915
|
else:
|
|
1912
|
-
|
|
1916
|
+
await araise_if_cancelled(workflow_run_response.run_id) # type: ignore
|
|
1913
1917
|
workflow_run_response.content = self._call_custom_function(self.steps, execution_input, **kwargs)
|
|
1914
1918
|
workflow_run_response.status = RunStatus.completed
|
|
1915
1919
|
|
|
@@ -1929,7 +1933,7 @@ class Workflow:
|
|
|
1929
1933
|
output_files: List[File] = (execution_input.files or []).copy() # Start with input files
|
|
1930
1934
|
|
|
1931
1935
|
for i, step in enumerate(self.steps): # type: ignore[arg-type]
|
|
1932
|
-
|
|
1936
|
+
await araise_if_cancelled(workflow_run_response.run_id) # type: ignore
|
|
1933
1937
|
step_name = getattr(step, "name", f"step_{i + 1}")
|
|
1934
1938
|
log_debug(f"Async Executing step {i + 1}/{self._get_step_count()}: {step_name}")
|
|
1935
1939
|
|
|
@@ -1944,7 +1948,7 @@ class Workflow:
|
|
|
1944
1948
|
)
|
|
1945
1949
|
|
|
1946
1950
|
# Check for cancellation before executing step
|
|
1947
|
-
|
|
1951
|
+
await araise_if_cancelled(workflow_run_response.run_id) # type: ignore
|
|
1948
1952
|
|
|
1949
1953
|
step_output = await step.aexecute( # type: ignore[union-attr]
|
|
1950
1954
|
step_input,
|
|
@@ -1962,7 +1966,7 @@ class Workflow:
|
|
|
1962
1966
|
)
|
|
1963
1967
|
|
|
1964
1968
|
# Check for cancellation after step execution
|
|
1965
|
-
|
|
1969
|
+
await araise_if_cancelled(workflow_run_response.run_id) # type: ignore
|
|
1966
1970
|
|
|
1967
1971
|
# Update the workflow-level previous_step_outputs dictionary
|
|
1968
1972
|
previous_step_outputs[step_name] = step_output
|
|
@@ -2042,7 +2046,7 @@ class Workflow:
|
|
|
2042
2046
|
else:
|
|
2043
2047
|
self.save_session(session=workflow_session)
|
|
2044
2048
|
# Always clean up the run tracking
|
|
2045
|
-
|
|
2049
|
+
await acleanup_run(workflow_run_response.run_id) # type: ignore
|
|
2046
2050
|
|
|
2047
2051
|
# Log Workflow Telemetry
|
|
2048
2052
|
if self.telemetry:
|
|
@@ -2065,6 +2069,8 @@ class Workflow:
|
|
|
2065
2069
|
"""Execute a specific pipeline by name with event streaming"""
|
|
2066
2070
|
from inspect import isasyncgenfunction, iscoroutinefunction, isgeneratorfunction
|
|
2067
2071
|
|
|
2072
|
+
await aregister_run(run_context.run_id)
|
|
2073
|
+
|
|
2068
2074
|
# Read existing session from database
|
|
2069
2075
|
workflow_session, run_context.session_state = await self._aload_or_create_session(
|
|
2070
2076
|
session_id=session_id, user_id=user_id, session_state=run_context.session_state
|
|
@@ -2096,7 +2102,7 @@ class Workflow:
|
|
|
2096
2102
|
content = ""
|
|
2097
2103
|
async_gen = await self._acall_custom_function(self.steps, execution_input, **kwargs)
|
|
2098
2104
|
async for chunk in async_gen:
|
|
2099
|
-
|
|
2105
|
+
await araise_if_cancelled(workflow_run_response.run_id) # type: ignore
|
|
2100
2106
|
if hasattr(chunk, "content") and chunk.content is not None and isinstance(chunk.content, str):
|
|
2101
2107
|
content += chunk.content
|
|
2102
2108
|
yield chunk
|
|
@@ -2131,7 +2137,7 @@ class Workflow:
|
|
|
2131
2137
|
|
|
2132
2138
|
for i, step in enumerate(self.steps): # type: ignore[arg-type]
|
|
2133
2139
|
if workflow_run_response.run_id:
|
|
2134
|
-
|
|
2140
|
+
await araise_if_cancelled(workflow_run_response.run_id)
|
|
2135
2141
|
step_name = getattr(step, "name", f"step_{i + 1}")
|
|
2136
2142
|
log_debug(f"Async streaming step {i + 1}/{self._get_step_count()}: {step_name}")
|
|
2137
2143
|
|
|
@@ -2169,7 +2175,7 @@ class Workflow:
|
|
|
2169
2175
|
background_tasks=background_tasks,
|
|
2170
2176
|
):
|
|
2171
2177
|
if workflow_run_response.run_id:
|
|
2172
|
-
|
|
2178
|
+
await araise_if_cancelled(workflow_run_response.run_id)
|
|
2173
2179
|
|
|
2174
2180
|
# Accumulate partial data from streaming events
|
|
2175
2181
|
partial_step_content = self._accumulate_partial_step_data(event, partial_step_content) # type: ignore
|
|
@@ -2399,7 +2405,7 @@ class Workflow:
|
|
|
2399
2405
|
await self._alog_workflow_telemetry(session_id=session_id, run_id=workflow_run_response.run_id)
|
|
2400
2406
|
|
|
2401
2407
|
# Always clean up the run tracking
|
|
2402
|
-
|
|
2408
|
+
await acleanup_run(workflow_run_response.run_id) # type: ignore
|
|
2403
2409
|
|
|
2404
2410
|
async def _arun_background(
|
|
2405
2411
|
self,
|
|
@@ -3119,7 +3125,8 @@ class Workflow:
|
|
|
3119
3125
|
if stream:
|
|
3120
3126
|
|
|
3121
3127
|
async def _stream():
|
|
3122
|
-
|
|
3128
|
+
await aregister_run(run_context.run_id)
|
|
3129
|
+
session, _ = await self._aload_session_for_workflow_agent(
|
|
3123
3130
|
run_context.session_id, run_context.user_id, run_context.session_state
|
|
3124
3131
|
)
|
|
3125
3132
|
async for event in self._arun_workflow_agent_stream(
|
|
@@ -3137,7 +3144,8 @@ class Workflow:
|
|
|
3137
3144
|
else:
|
|
3138
3145
|
|
|
3139
3146
|
async def _execute():
|
|
3140
|
-
|
|
3147
|
+
await aregister_run(run_context.run_id)
|
|
3148
|
+
session, _ = await self._aload_session_for_workflow_agent(
|
|
3141
3149
|
run_context.session_id, run_context.user_id, run_context.session_state
|
|
3142
3150
|
)
|
|
3143
3151
|
return await self._arun_workflow_agent(
|
|
@@ -3790,7 +3798,6 @@ class Workflow:
|
|
|
3790
3798
|
|
|
3791
3799
|
# Set the id for the run and register it immediately for cancellation tracking
|
|
3792
3800
|
run_id = run_id or str(uuid4())
|
|
3793
|
-
register_run(run_id)
|
|
3794
3801
|
|
|
3795
3802
|
self.initialize_workflow()
|
|
3796
3803
|
session_id, user_id = self._initialize_session(session_id=session_id, user_id=user_id)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agno
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.21
|
|
4
4
|
Summary: Agno: a lightweight library for building Multi-Agent Systems
|
|
5
5
|
Author-email: Ashpreet Bedi <ashpreet@agno.com>
|
|
6
6
|
Project-URL: homepage, https://agno.com
|
|
@@ -49,6 +49,7 @@ Requires-Dist: uvicorn; extra == "dev"
|
|
|
49
49
|
Requires-Dist: PyJWT; extra == "dev"
|
|
50
50
|
Requires-Dist: mcp; extra == "dev"
|
|
51
51
|
Requires-Dist: openai; extra == "dev"
|
|
52
|
+
Requires-Dist: fakeredis; extra == "dev"
|
|
52
53
|
Provides-Extra: os
|
|
53
54
|
Requires-Dist: fastapi; extra == "os"
|
|
54
55
|
Requires-Dist: uvicorn; extra == "os"
|
|
@@ -414,7 +415,7 @@ Dynamic: license-file
|
|
|
414
415
|
<div align="center">
|
|
415
416
|
<a href="https://docs.agno.com">Documentation</a>
|
|
416
417
|
<span> • </span>
|
|
417
|
-
<a href="https://
|
|
418
|
+
<a href="https://github.com/agno-agi/agno/tree/main/cookbook">Cookbook</a>
|
|
418
419
|
<span> • </span>
|
|
419
420
|
<a href="https://www.agno.com/?utm_source=github&utm_medium=readme&utm_campaign=agno-github">Website</a>
|
|
420
421
|
<br />
|
|
@@ -422,25 +423,27 @@ Dynamic: license-file
|
|
|
422
423
|
|
|
423
424
|
## What is Agno?
|
|
424
425
|
|
|
425
|
-
Agno is
|
|
426
|
+
Agno is a multi-agent framework, runtime, and control plane. Use it to build private and secure AI products that run in your cloud.
|
|
426
427
|
|
|
427
|
-
|
|
428
|
+
- **Build** agents, teams, and workflows with memory, knowledge, guardrails, and 100+ toolkits.
|
|
429
|
+
- **Run** in production with a stateless FastAPI runtime. Horizontally scalable.
|
|
430
|
+
- **Manage** with a control plane that connects directly to your runtime — no data leaves your environment.
|
|
428
431
|
|
|
429
|
-
|
|
432
|
+
## Why Agno?
|
|
430
433
|
|
|
431
|
-
- **
|
|
432
|
-
- **
|
|
433
|
-
- **
|
|
434
|
+
- **Your cloud, your data:** AgentOS runs entirely in your infrastructure. Zero data leaves your environment.
|
|
435
|
+
- **Production-ready from day one:** Pre-built FastAPI runtime with SSE endpoints, ready to deploy.
|
|
436
|
+
- **Actually fast:** 529× faster than LangGraph, 24× lower memory. Matters at scale.
|
|
434
437
|
|
|
435
|
-
|
|
438
|
+
## Getting Started
|
|
436
439
|
|
|
437
|
-
|
|
440
|
+
New to Agno? Start with the [getting started guide](https://github.com/agno-agi/agno/tree/main/cookbook/00_getting_started).
|
|
438
441
|
|
|
439
|
-
|
|
442
|
+
Then:
|
|
443
|
+
- Browse the [cookbooks](https://github.com/agno-agi/agno/tree/main/cookbook) for real-world examples
|
|
444
|
+
- Read the [docs](https://docs.agno.com) to learn more.
|
|
440
445
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
## Documentation, Community & More Examples
|
|
446
|
+
## Resources
|
|
444
447
|
|
|
445
448
|
- Docs: <a href="https://docs.agno.com" target="_blank" rel="noopener noreferrer">docs.agno.com</a>
|
|
446
449
|
- Cookbook: <a href="https://github.com/agno-agi/agno/tree/main/cookbook" target="_blank" rel="noopener noreferrer">Cookbook</a>
|
|
@@ -496,144 +499,72 @@ When you run the example script shared above, you get a FastAPI app that you can
|
|
|
496
499
|
|
|
497
500
|
https://github.com/user-attachments/assets/feb23db8-15cc-4e88-be7c-01a21a03ebf6
|
|
498
501
|
|
|
499
|
-
##
|
|
502
|
+
## Private by Design
|
|
500
503
|
|
|
501
|
-
|
|
504
|
+
This is the part we care most about.
|
|
502
505
|
|
|
503
|
-
|
|
504
|
-
- A ready-to-use FastAPI app that gets you building AI products on day one.
|
|
505
|
-
- A control plane for testing, monitoring and managing your system.
|
|
506
|
+
AgentOS runs in **your** cloud. The control plane UI connects directly to your runtime from your browser. Your data never touches our servers. No retention costs, no vendor lock-in, no compliance headaches.
|
|
506
507
|
|
|
507
|
-
|
|
508
|
+
This isn't a privacy mode or enterprise add-on. It's how Agno works.
|
|
508
509
|
|
|
509
510
|
## Features
|
|
510
511
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
| | **Data Governance** | Your data lives securely in your Agent database, no external data sharing or vendor lock-in. |
|
|
537
|
-
| | **Access Control** | Role-based access (RBAC) and per-agent permissions to protect sensitive contexts and tools. |
|
|
538
|
-
|
|
539
|
-
Every part of Agno is built for real-world deployment — where developer experience meets production performance.
|
|
540
|
-
|
|
541
|
-
## Setup Your Coding Agent to Use Agno
|
|
542
|
-
|
|
543
|
-
For LLMs and AI assistants to understand and navigate Agno's documentation, we provide an [llms.txt](https://docs.agno.com/llms.txt) or [llms-full.txt](https://docs.agno.com/llms-full.txt) file. This file is built for AI systems to efficiently parse and reference our documentation.
|
|
544
|
-
|
|
545
|
-
### IDE Integration
|
|
546
|
-
|
|
547
|
-
When building Agno agents, using Agno documentation as a source in your IDE is a great way to speed up your development. Here's how to integrate with Cursor:
|
|
548
|
-
|
|
549
|
-
1. In Cursor, go to the "Cursor Settings" menu.
|
|
550
|
-
2. Find the "Indexing & Docs" section.
|
|
551
|
-
3. Add `https://docs.agno.com/llms-full.txt` to the list of documentation URLs.
|
|
552
|
-
4. Save the changes.
|
|
553
|
-
|
|
554
|
-
Now, Cursor will have access to the Agno documentation. You can do the same with other IDEs like VSCode, Windsurf etc.
|
|
512
|
+
**Core**
|
|
513
|
+
- Model agnostic — works with OpenAI, Anthropic, Google, local models, whatever
|
|
514
|
+
- Type-safe I/O with `input_schema` and `output_schema`
|
|
515
|
+
- Async-first, built for long-running tasks
|
|
516
|
+
- Natively multimodal (text, images, audio, video, files)
|
|
517
|
+
|
|
518
|
+
**Memory & Knowledge**
|
|
519
|
+
- Persistent storage for session history and state
|
|
520
|
+
- User memory that persists across sessions
|
|
521
|
+
- Agentic RAG with 20+ vector stores, hybrid search, reranking
|
|
522
|
+
- Culture — shared long-term memory across agents
|
|
523
|
+
|
|
524
|
+
**Execution**
|
|
525
|
+
- Human-in-the-loop (confirmations, approvals, overrides)
|
|
526
|
+
- Guardrails for validation and security
|
|
527
|
+
- Pre/post hooks for the agent lifecycle
|
|
528
|
+
- First-class MCP and A2A support
|
|
529
|
+
- 100+ built-in toolkits
|
|
530
|
+
|
|
531
|
+
**Production**
|
|
532
|
+
- Ready-to-use FastAPI runtime
|
|
533
|
+
- Integrated control plane UI
|
|
534
|
+
- Evals for accuracy, performance, latency
|
|
535
|
+
- Durable execution for resumable workflows
|
|
536
|
+
- RBAC and per-agent permissions
|
|
555
537
|
|
|
556
538
|
## Performance
|
|
557
539
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
At Agno, we optimize performance across 3 dimensions:
|
|
561
|
-
|
|
562
|
-
1. **Agent performance:** We optimize static operations (instantiation, memory footprint) and runtime operations (tool calls, memory updates, history management).
|
|
563
|
-
2. **System performance:** The AgentOS API is async by default and has a minimal memory footprint. The system is stateless and horizontally scalable, with a focus on preventing memory leaks. It handles parallel and batch embedding generation during knowledge ingestion, metrics collection in background tasks, and other system-level optimizations.
|
|
564
|
-
3. **Agent reliability and accuracy:** Monitored through evals, which we'll explore later.
|
|
565
|
-
|
|
566
|
-
### Agent Performance
|
|
567
|
-
|
|
568
|
-
Let's measure the time it takes to instantiate an Agent and the memory footprint of an Agent. Here are the numbers (last measured in Oct 2025, on an Apple M4 MacBook Pro):
|
|
569
|
-
|
|
570
|
-
- **Agent instantiation:** ~3μs on average
|
|
571
|
-
- **Memory footprint:** ~6.6Kib on average
|
|
572
|
-
|
|
573
|
-
We'll show below that Agno Agents instantiate **529× faster than Langgraph**, **57× faster than PydanticAI**, and **70× faster than CrewAI**. Agno Agents also use **24× lower memory than Langgraph**, **4× lower than PydanticAI**, and **10× lower than CrewAI**.
|
|
574
|
-
|
|
575
|
-
> [!NOTE]
|
|
576
|
-
> Run time performance is bottlenecked by inference and hard to benchmark accurately, so we focus on minimizing overhead, reducing memory usage, and parallelizing tool calls.
|
|
577
|
-
|
|
578
|
-
### Instantiation Time
|
|
540
|
+
We're obsessive about performance because agent workloads spawn hundreds of instances and run long tasks. Stateless, horizontal scalability isn't optional.
|
|
579
541
|
|
|
580
|
-
|
|
542
|
+
**Benchmarks** (Apple M4 MacBook Pro, Oct 2025):
|
|
581
543
|
|
|
582
|
-
|
|
583
|
-
|
|
544
|
+
| Metric | Agno | LangGraph | PydanticAI | CrewAI |
|
|
545
|
+
|--------|------|-----------|------------|--------|
|
|
546
|
+
| Instantiation | **3μs** | 1,587μs (529× slower) | 170μs (57× slower) | 210μs (70× slower) |
|
|
547
|
+
| Memory | **6.6 KiB** | 161 KiB (24× higher) | 29 KiB (4× higher) | 66 KiB (10× higher) |
|
|
584
548
|
|
|
585
|
-
|
|
586
|
-
# Setup virtual environment
|
|
587
|
-
./scripts/perf_setup.sh
|
|
588
|
-
source .venvs/perfenv/bin/activate
|
|
589
|
-
|
|
590
|
-
# Agno
|
|
591
|
-
python cookbook/evals/performance/instantiate_agent_with_tool.py
|
|
592
|
-
|
|
593
|
-
# LangGraph
|
|
594
|
-
python cookbook/evals/performance/comparison/langgraph_instantiation.py
|
|
595
|
-
# CrewAI
|
|
596
|
-
python cookbook/evals/performance/comparison/crewai_instantiation.py
|
|
597
|
-
# Pydantic AI
|
|
598
|
-
python cookbook/evals/performance/comparison/pydantic_ai_instantiation.py
|
|
599
|
-
```
|
|
600
|
-
|
|
601
|
-
LangGraph is on the right, **let's start it first and give it a head start**. Then CrewAI and Pydantic AI follow, and finally Agno. Agno obviously finishes first, but let's see by how much.
|
|
549
|
+
Run the benchmarks yourself: [`cookbook/evals/performance`](https://github.com/agno-agi/agno/tree/main/cookbook/evals/performance)
|
|
602
550
|
|
|
603
551
|
https://github.com/user-attachments/assets/54b98576-1859-4880-9f2d-15e1a426719d
|
|
604
552
|
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
To measure memory usage, we use the `tracemalloc` library. We first calculate a baseline memory usage by running an empty function, then run the Agent 1000x times and calculate the difference. This gives a (reasonably) isolated measurement of the memory usage of the Agent.
|
|
608
|
-
|
|
609
|
-
We recommend running the evaluation yourself on your own machine, and digging into the code to see how it works. If we've made a mistake, please let us know.
|
|
610
|
-
|
|
611
|
-
### Results
|
|
612
|
-
|
|
613
|
-
Taking Agno as the baseline, we can see that:
|
|
614
|
-
|
|
615
|
-
| Metric | Agno | Langgraph | PydanticAI | CrewAI |
|
|
616
|
-
| ------------------ | ---- | ----------- | ---------- | ---------- |
|
|
617
|
-
| **Time (seconds)** | 1× | 529× slower | 57× slower | 70× slower |
|
|
618
|
-
| **Memory (MiB)** | 1× | 24× higher | 4× higher | 10× higher |
|
|
553
|
+
## IDE Integration
|
|
619
554
|
|
|
620
|
-
|
|
555
|
+
For AI-assisted development, add our docs to your IDE:
|
|
621
556
|
|
|
622
|
-
|
|
623
|
-
| ------------------ | -------- | --------- | ---------- | -------- |
|
|
624
|
-
| **Time (seconds)** | 0.000003 | 0.001587 | 0.000170 | 0.000210 |
|
|
625
|
-
| **Memory (MiB)** | 0.006642 | 0.161435 | 0.028712 | 0.065652 |
|
|
557
|
+
**Cursor:** Settings → Indexing & Docs → Add `https://docs.agno.com/llms-full.txt`
|
|
626
558
|
|
|
627
|
-
|
|
628
|
-
> Agno agents are designed for performance and while we share benchmarks against other frameworks, we should be mindful that accuracy and reliability are more important than speed.
|
|
559
|
+
Works with VSCode, Windsurf, and other AI-enabled editors too.
|
|
629
560
|
|
|
630
|
-
##
|
|
561
|
+
## Contributing
|
|
631
562
|
|
|
632
|
-
We welcome contributions
|
|
563
|
+
We welcome contributions. See the [contributing guide](https://github.com/agno-agi/agno/blob/v2.0/CONTRIBUTING.md).
|
|
633
564
|
|
|
634
565
|
## Telemetry
|
|
635
566
|
|
|
636
|
-
Agno logs which model
|
|
567
|
+
Agno logs which model providers are used so we can prioritize updates. Disable with `AGNO_TELEMETRY=false`.
|
|
637
568
|
|
|
638
569
|
<p align="left">
|
|
639
570
|
<a href="#top">⬆️ Back to Top</a>
|