Many Python developers know:
import functools
But very few understand that LangGraph, FastAPI, Pydantic, AI Agents, Tool Calling Systems, and Production GenAI Platforms heavily rely on concepts provided by functools.
Think of functools as:
🛠️ A toolbox for enhancing functions without changing their original code.
It helps you:
✅ Cache results
✅ Wrap functions
✅ Create decorators
✅ Build reusable workflows
✅ Pass pre-configured functions
✅ Optimize performance
Imagine a restaurant.
Without functools:
Customer Orders Pizza
↓
Chef Makes Pizza
↓
Deliver
Next customer orders same pizza:
Customer Orders Pizza
↓
Chef Makes Again
↓
Deliver
Waste of time.
With functools caching:
Customer Orders Pizza
↓
Chef Makes Pizza
↓
Store Recipe Result
↓
Deliver
Next order:
Customer Orders Same Pizza
↓
Already Available
↓
Instant Delivery
🚀 Faster
💰 Cheaper
⚡ More Efficient
functools
│
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
lru_cache partial wraps
│ │ │
▼ ▼ ▼
Performance Reusable Decorator
Optimization Functions Support
@lru_cacheThis is the superstar.
Suppose your AI app repeatedly processes the same document.
def embed_document(text):
return expensive_embedding(text)
Every call:
Document
↓
Embedding Model
↓
Embedding Generated
Costly.
from functools import lru_cache
@lru_cache
def embed_document(text):
return expensive_embedding(text)
Now:
First Call:
Document
↓
Generate Embedding
↓
Store in Cache
Second Call:
Document
↓
Cache Hit
↓
Return Instantly
User Query
│
▼
Function Called
│
▼
Is Result Cached?
│
┌────┴────┐
│ │
No Yes
│ │
▼ ▼
Compute Return
Result Cached Result
│
▼
Store Cache
Imagine:
User 1 asks:
"What is LangGraph?"
User 2 asks:
"What is LangGraph?"
User 3 asks:
"What is LangGraph?"
Without cache:
LLM Call
LLM Call
LLM Call
With cache:
LLM Call
Cache
Cache
Huge savings.
@lru_cache(maxsize=1000)
def get_embedding(text):
return embedding_model.embed(text)
| Benefit | Result |
|---|---|
| Lower Cost | Fewer API Calls |
| Faster Response | Milliseconds |
| Reduced Compute | Less GPU Usage |
| Better UX | Faster Agents |
partial()A hidden gem.
Suppose:
def search_docs(query, top_k):
...
Need:
search_docs(
query="AI",
top_k=5
)
everywhere.
from functools import partial
fast_search = partial(
search_docs,
top_k=5
)
Now:
fast_search("AI")
Think of:
partial()
as
🎛️ Preconfigured Machine
Normal Coffee Machine:
Select Size
Select Sugar
Select Milk
Every time.
Partial Machine:
Already Configured
↓
Press Button
Different Retrieval Modes
rag_search = partial(
search_docs,
top_k=5
)
deep_research = partial(
search_docs,
top_k=20
)
Visual:
search_docs()
│
▼
┌────┴────┐
▼ ▼
RAG Deep Research
top=5 top=20
wraps()Used inside decorators.
Without wraps
def my_decorator(func):
def wrapper():
...
return wrapper
Python loses metadata.
With wraps
from functools import wraps
def my_decorator(func):
@wraps(func)
def wrapper():
...
return wrapper
LangGraph Tools
FastAPI Routes
Tool Calling
Agent Frameworks
all inspect functions dynamically.
Without wraps:
Tool Name Lost
Description Lost
Annotations Lost
With wraps:
Tool Name Preserved
Tool Signature Preserved
Metadata Preserved
@tool
def search_web(query:str):
...
Internally many frameworks rely on:
wraps()
to preserve metadata.
reduce()Combines items.
Example
from functools import reduce
nums = [1,2,3,4]
reduce(
lambda x,y: x+y,
nums
)
Result:
10
Visual
1 + 2
↓
3 + 3
↓
6 + 4
↓
10
Combining:
Chunk Summaries
↓
Intermediate Summaries
↓
Final Summary
Map Reduce Architecture
Document Chunks
│
▼
Summarize Each Chunk
│
▼
Reduce Summaries
│
▼
Final Report
Used in:
LangGraph
LangChain
Research Agents
cached_propertyAmazing for AI systems.
Example
from functools import cached_property
Without
obj.embedding
generates every time.
With
class Document:
@cached_property
def embedding(self):
return expensive_embedding()
First access:
Compute
Store
Later:
Return Cached Value
Document
│
▼
Embedding
│
▼
Store Once
│
▼
Reuse Forever
State
│
▼
Node
│
▼
Tool
│
▼
Cache
│
▼
Reuse
User Query
│
▼
Agent Router
│
┌───────────────┼───────────────┐
▼ ▼ ▼
Search Tool RAG Tool SQL Tool
│ │ │
▼ ▼ ▼
functools functools functools
│ │ │
Cache Calls Cached Data Preserved Metadata
| Area | Usage |
|---|---|
| LangGraph | Node optimization |
| LangChain | Tool wrappers |
| FastAPI | Decorators |
| Agent Systems | Metadata preservation |
| RAG | Embedding cache |
| LLM Apps | API call caching |
| Multi-Agent Systems | Shared computations |
| AI Workflows | Reusable pipelines |
| Rank | Feature | Why |
|---|---|---|
| 🥇 | lru_cache | Performance & Cost Savings |
| 🥈 | wraps | Tool Metadata Preservation |
| 🥉 | partial | Reusable AI Components |
Think of functools as an AI Operations Manager:
functools
│
┌────────────────┼────────────────┐
▼ ▼ ▼
Cache Preconfigure Preserve
Results Functions Metadata
(lru_cache) (partial) (wraps)
functoolsis Python’s function-enhancement toolkit that enables caching, reusable function creation, metadata preservation, and workflow optimization—making it one of the most important standard-library modules for scalable GenAI, LangGraph, and Agentic AI applications. 🚀
functools.lru_cache() valuable in GenAI?Answer:
Repeated Inputs
↓
Avoid Recalculation
↓
Reduce API Calls
↓
Lower Cost
↓
Faster Response
This is why caching is commonly used in embeddings, retrieval pipelines, document processing, prompt generation, and agent workflows.