How to get the prompt token after each and every task? → I need this to raise the userdeifned exception if the token limit exceeded.
TaskOutput doesn’t have the attribute of usage metrics. Help me on this.
How to get the prompt token after each and every task? → I need this to raise the userdeifned exception if the token limit exceeded.
TaskOutput doesn’t have the attribute of usage metrics. Help me on this.
I was wondering the same issue and it was an dead end. I was trying to use from langchain.callbacks import get_openai_callback or
from langchain.callbacks.openai_info import OpenAICallbackHandler but it yields no result. If you have something in your mind, please share. Thank you!
Same issue, but I was able to estimate per-agent tokens based on output proportions and then distributed the total_usage accordingly. I know this might not be the cleanest approach but this is how I got it working.
"""
Standalone test script for CrewAI token tracking - Version 3 (Final).
This version uses CrewAI's result.token_usage for total tokens and
estimates per-agent usage based on task count and output lengths.
Since CrewAI doesn't expose per-task usage_metrics (as of v1.3.0),
we use a reasonable estimation approach.
Strategy:
1. Get total tokens from result.token_usage (crew-level)
2. Get task list with agents from result.tasks_output
3. Estimate per-agent usage based on:
- Equal division for simple cases
- Output length proportions for better estimation
Requirements:
- crewai
- GEMINI_API_KEY in .env file
Usage:
python test_crewai_token_tracking_v3.py
"""
print("Starting token tracking test v3...")
import os
import sys
import logging
# Windows compatibility
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src', 'backend'))
try:
import win_compat
print("✓ Windows compatibility patches loaded")
except ImportError:
print("⚠ Windows compatibility module not found")
from dotenv import load_dotenv
from crewai import Agent, Task, Crew, Process
from crewai.llm import LLM
from pathlib import Path
# Load environment variables
env_paths = [
Path(__file__).parent / '.env',
Path(__file__).parent / 'src' / 'backend' / '.env',
]
for env_path in env_paths:
if env_path.exists():
load_dotenv(env_path)
print(f"✓ Loaded environment from: {env_path}")
break
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
def estimate_per_agent_tokens(result):
"""
Estimate per-agent token usage from CrewAI result.
Args:
result: CrewOutput from crew.kickoff()
Returns:
dict: {agent_name: {total_tokens, prompt_tokens, completion_tokens, task_count}}
"""
per_agent = {}
# Get total usage
total_tokens = 0
total_prompt = 0
total_completion = 0
if hasattr(result, 'token_usage') and result.token_usage:
usage_obj = result.token_usage
total_tokens = getattr(usage_obj, 'total_tokens', 0)
total_prompt = getattr(usage_obj, 'prompt_tokens', 0)
total_completion = getattr(usage_obj, 'completion_tokens', 0)
# Get task list
if not hasattr(result, 'tasks_output') or not result.tasks_output:
logger.warning("No tasks_output found")
return per_agent
tasks = result.tasks_output
num_tasks = len(tasks)
if num_tasks == 0:
return per_agent
# Method 1: Equal division (simple but fair for similar tasks)
# For better accuracy, we could use output length proportions
# Calculate output lengths for proportional distribution
task_data = []
total_output_length = 0
for task_output in tasks:
# Extract agent
agent_name = "Unknown"
if hasattr(task_output, 'agent'):
agent_obj = task_output.agent
if hasattr(agent_obj, 'role'):
agent_name = str(agent_obj.role)
elif isinstance(agent_obj, str):
agent_name = agent_obj
# Extract output length
output_length = 0
if hasattr(task_output, 'raw'):
output_length = len(str(task_output.raw))
elif hasattr(task_output, 'description'):
output_length = len(str(task_output.description))
total_output_length += output_length
task_data.append({
'agent': agent_name,
'output_length': output_length
})
# Distribute tokens proportionally based on output length
if total_output_length > 0:
for task_info in task_data:
agent_name = task_info['agent']
proportion = task_info['output_length'] / total_output_length
if agent_name not in per_agent:
per_agent[agent_name] = {
'total_tokens': 0,
'prompt_tokens': 0,
'completion_tokens': 0,
'task_count': 0
}
per_agent[agent_name]['total_tokens'] += int(total_tokens * proportion)
per_agent[agent_name]['prompt_tokens'] += int(total_prompt * proportion)
per_agent[agent_name]['completion_tokens'] += int(total_completion * proportion)
per_agent[agent_name]['task_count'] += 1
else:
# Fallback: equal division
tokens_per_task = total_tokens / num_tasks
prompt_per_task = total_prompt / num_tasks
completion_per_task = total_completion / num_tasks
for task_info in task_data:
agent_name = task_info['agent']
if agent_name not in per_agent:
per_agent[agent_name] = {
'total_tokens': 0,
'prompt_tokens': 0,
'completion_tokens': 0,
'task_count': 0
}
per_agent[agent_name]['total_tokens'] += int(tokens_per_task)
per_agent[agent_name]['prompt_tokens'] += int(prompt_per_task)
per_agent[agent_name]['completion_tokens'] += int(completion_per_task)
per_agent[agent_name]['task_count'] += 1
return per_agent
def create_test_crew():
"""Create a simple test crew with 2 agents and 2 tasks."""
api_key = os.getenv("GEMINI_API_KEY")
if not api_key:
raise ValueError("GEMINI_API_KEY not found in environment!")
logger.info("🔧 Creating LLM instance...")
llm = LLM(
model="gemini/gemini-2.0-flash-exp",
api_key=api_key
)
# Create agents
logger.info("🤖 Creating agents...")
researcher = Agent(
role="Research Analyst",
goal="Research and summarize information about a given topic",
backstory="You are an expert research analyst who excels at finding and summarizing information.",
llm=llm,
verbose=False, # Reduce verbosity for cleaner output
allow_delegation=False
)
writer = Agent(
role="Content Writer",
goal="Write engaging content based on research",
backstory="You are a skilled content writer who creates compelling narratives from research data.",
llm=llm,
verbose=False,
allow_delegation=False
)
# Create tasks
logger.info("📝 Creating tasks...")
research_task = Task(
description="Research the history of artificial intelligence and list 3 key milestones.",
expected_output="A list of 3 key milestones in AI history with brief descriptions.",
agent=researcher
)
writing_task = Task(
description="Write a brief 2-paragraph summary of AI history based on the research.",
expected_output="A 2-paragraph summary of AI history.",
agent=writer
)
# Create crew
logger.info("🚀 Creating crew...")
crew = Crew(
agents=[researcher, writer],
tasks=[research_task, writing_task],
process=Process.sequential,
verbose=False # Reduce verbosity
)
return crew
def main():
"""Run the token tracking test."""
print("\n" + "="*70)
print("CrewAI Token Tracking Test - Version 3 (Production Ready)")
print("="*70 + "\n")
# Create crew
print("Creating crew...")
crew = create_test_crew()
print("✓ Crew created\n")
# Run crew
print("-"*70)
print("Running CrewAI Workflow (this takes 1-2 minutes)...")
print("-"*70 + "\n")
try:
result = crew.kickoff()
logger.info("✅ Crew execution completed")
except Exception as e:
logger.error(f"❌ Crew execution failed: {e}", exc_info=True)
return
# Extract and display token usage
print("\n" + "="*70)
print("📊 Token Usage Report")
print("="*70 + "\n")
# 1. Total usage
if hasattr(result, 'token_usage') and result.token_usage:
usage_obj = result.token_usage
total_tokens = getattr(usage_obj, 'total_tokens', 0)
total_prompt = getattr(usage_obj, 'prompt_tokens', 0)
total_completion = getattr(usage_obj, 'completion_tokens', 0)
print("Total Crew Usage:")
print(f" Total Tokens: {total_tokens:,}")
print(f" Prompt Tokens: {total_prompt:,}")
print(f" Completion Tokens: {total_completion:,}")
# 2. Per-agent estimation
per_agent = estimate_per_agent_tokens(result)
if per_agent:
print("\nPer-Agent Breakdown (Estimated):")
print("─" * 70)
for agent_name, metrics in per_agent.items():
print(f"\n{agent_name}:")
print(f" Tasks Completed: {metrics['task_count']}")
print(f" Total Tokens: {metrics['total_tokens']:,}")
print(f" Prompt Tokens: {metrics['prompt_tokens']:,}")
print(f" Completion Tokens: {metrics['completion_tokens']:,}")
else:
print("\n⚠️ Could not estimate per-agent breakdown")
print("\n" + "="*70)
print("✅ Test Complete!")
print("="*70 + "\n")
print("Note: Per-agent tokens are estimated based on output length proportions.")
print("CrewAI v1.3.0 does not expose per-task usage_metrics.")
print("\n")
if __name__ == "__main__":
main()