Skip to content

Commit a395a5c

Browse files
devin-ai-integration[bot]João
andcommitted
feat: Add prompt caching support for AWS Bedrock and Anthropic models
- Add enable_prompt_caching and cache_control parameters to LLM class - Implement cache_control formatting for Anthropic models via LiteLLM - Add helper method to detect prompt caching support for different providers - Create comprehensive tests covering all prompt caching functionality - Add example demonstrating usage with kickoff_for_each and kickoff_async - Supports OpenAI, Anthropic, Bedrock, and Deepseek providers - Enables cost optimization for workflows with repetitive context Addresses issue #3535 for prompt caching support in CrewAI Co-Authored-By: João <[email protected]>
1 parent 578fa8c commit a395a5c

File tree

3 files changed

+634
-113
lines changed

3 files changed

+634
-113
lines changed

examples/prompt_caching_example.py

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
"""
2+
Example demonstrating prompt caching with CrewAI for cost optimization.
3+
4+
This example shows how to use prompt caching with kickoff_for_each() and
5+
kickoff_async() to reduce costs when processing multiple similar inputs.
6+
"""
7+
8+
from crewai import Agent, Crew, Task, LLM
9+
import asyncio
10+
11+
12+
def create_crew_with_caching():
13+
"""Create a crew with prompt caching enabled."""
14+
15+
llm = LLM(
16+
model="anthropic/claude-3-5-sonnet-20240620",
17+
enable_prompt_caching=True,
18+
temperature=0.1
19+
)
20+
21+
analyst = Agent(
22+
role="Data Analyst",
23+
goal="Analyze data and provide insights",
24+
backstory="""You are an experienced data analyst with expertise in
25+
statistical analysis, data visualization, and business intelligence.
26+
You have worked with various industries including finance, healthcare,
27+
and technology. Your approach is methodical and you always provide
28+
actionable insights based on data patterns.""",
29+
llm=llm
30+
)
31+
32+
analysis_task = Task(
33+
description="""Analyze the following dataset: {dataset}
34+
35+
Please provide:
36+
1. Summary statistics
37+
2. Key patterns and trends
38+
3. Actionable recommendations
39+
4. Potential risks or concerns
40+
41+
Be thorough in your analysis and provide specific examples.""",
42+
expected_output="A comprehensive analysis report with statistics, trends, and recommendations",
43+
agent=analyst
44+
)
45+
46+
return Crew(agents=[analyst], tasks=[analysis_task])
47+
48+
49+
def example_kickoff_for_each():
50+
"""Example using kickoff_for_each with prompt caching."""
51+
print("Running kickoff_for_each example with prompt caching...")
52+
53+
crew = create_crew_with_caching()
54+
55+
datasets = [
56+
{"dataset": "Q1 2024 sales data showing 15% growth in mobile segment"},
57+
{"dataset": "Q2 2024 customer satisfaction scores with 4.2/5 average rating"},
58+
{"dataset": "Q3 2024 website traffic data with 25% increase in organic search"},
59+
{"dataset": "Q4 2024 employee engagement survey with 78% satisfaction rate"}
60+
]
61+
62+
results = crew.kickoff_for_each(datasets)
63+
64+
for i, result in enumerate(results, 1):
65+
print(f"\n--- Analysis {i} ---")
66+
print(result.raw)
67+
68+
if crew.usage_metrics:
69+
print(f"\nTotal usage metrics:")
70+
print(f"Total tokens: {crew.usage_metrics.total_tokens}")
71+
print(f"Prompt tokens: {crew.usage_metrics.prompt_tokens}")
72+
print(f"Completion tokens: {crew.usage_metrics.completion_tokens}")
73+
74+
75+
async def example_kickoff_for_each_async():
76+
"""Example using kickoff_for_each_async with prompt caching."""
77+
print("Running kickoff_for_each_async example with prompt caching...")
78+
79+
crew = create_crew_with_caching()
80+
81+
datasets = [
82+
{"dataset": "Marketing campaign A: 12% CTR, 3.5% conversion rate"},
83+
{"dataset": "Marketing campaign B: 8% CTR, 4.1% conversion rate"},
84+
{"dataset": "Marketing campaign C: 15% CTR, 2.8% conversion rate"}
85+
]
86+
87+
results = await crew.kickoff_for_each_async(datasets)
88+
89+
for i, result in enumerate(results, 1):
90+
print(f"\n--- Async Analysis {i} ---")
91+
print(result.raw)
92+
93+
if crew.usage_metrics:
94+
print(f"\nTotal async usage metrics:")
95+
print(f"Total tokens: {crew.usage_metrics.total_tokens}")
96+
97+
98+
def example_bedrock_caching():
99+
"""Example using AWS Bedrock with prompt caching."""
100+
print("Running Bedrock example with prompt caching...")
101+
102+
llm = LLM(
103+
model="bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0",
104+
enable_prompt_caching=True
105+
)
106+
107+
agent = Agent(
108+
role="Legal Analyst",
109+
goal="Review legal documents and identify key clauses",
110+
backstory="Expert legal analyst with 10+ years experience in contract review",
111+
llm=llm
112+
)
113+
114+
task = Task(
115+
description="Review this contract section: {contract_section}",
116+
expected_output="Summary of key legal points and potential issues",
117+
agent=agent
118+
)
119+
120+
crew = Crew(agents=[agent], tasks=[task])
121+
122+
contract_sections = [
123+
{"contract_section": "Section 1: Payment terms and conditions"},
124+
{"contract_section": "Section 2: Intellectual property rights"},
125+
{"contract_section": "Section 3: Termination clauses"}
126+
]
127+
128+
results = crew.kickoff_for_each(contract_sections)
129+
130+
for i, result in enumerate(results, 1):
131+
print(f"\n--- Legal Review {i} ---")
132+
print(result.raw)
133+
134+
135+
def example_openai_caching():
136+
"""Example using OpenAI with prompt caching."""
137+
print("Running OpenAI example with prompt caching...")
138+
139+
llm = LLM(
140+
model="gpt-4o",
141+
enable_prompt_caching=True
142+
)
143+
144+
agent = Agent(
145+
role="Content Writer",
146+
goal="Create engaging content for different audiences",
147+
backstory="Professional content writer with expertise in various writing styles and formats",
148+
llm=llm
149+
)
150+
151+
task = Task(
152+
description="Write a {content_type} about: {topic}",
153+
expected_output="Well-structured and engaging content piece",
154+
agent=agent
155+
)
156+
157+
crew = Crew(agents=[agent], tasks=[task])
158+
159+
content_requests = [
160+
{"content_type": "blog post", "topic": "benefits of renewable energy"},
161+
{"content_type": "social media post", "topic": "importance of cybersecurity"},
162+
{"content_type": "newsletter", "topic": "latest AI developments"}
163+
]
164+
165+
results = crew.kickoff_for_each(content_requests)
166+
167+
for i, result in enumerate(results, 1):
168+
print(f"\n--- Content Piece {i} ---")
169+
print(result.raw)
170+
171+
172+
if __name__ == "__main__":
173+
print("=== CrewAI Prompt Caching Examples ===\n")
174+
175+
example_kickoff_for_each()
176+
177+
print("\n" + "="*50 + "\n")
178+
179+
asyncio.run(example_kickoff_for_each_async())
180+
181+
print("\n" + "="*50 + "\n")
182+
183+
example_bedrock_caching()
184+
185+
print("\n" + "="*50 + "\n")
186+
187+
example_openai_caching()

0 commit comments

Comments
 (0)