Welcome to the Builder Track! In this first module, we'll dive into the Python fundamentals that are essential for building modern AI applications. We'll start by exploring the latest features in Python 3.12 and beyond that are particularly useful for AI engineers.
While Python has been a dominant language in AI for years, recent versions have introduced powerful features that make code faster, more readable, and less error-prone, especially in the context of complex AI workflows.
1. More Flexible F-Strings (PEP 701)
F-strings are a developer favorite for formatting strings. In Python 3.12, they became even more powerful. The restrictions on what you can put inside an f-string have been lifted, allowing for multi-line expressions, comments, and more.
💡 Why is this important for AI?
- Dynamic Prompt Engineering: When you're creating complex prompts for LLMs, you often need to embed multiple variables, function calls, and even snippets of logic. Flexible f-strings make this much cleaner.
- Richer Logging: Create more descriptive and readable logs for debugging your AI agents or RAG pipelines.
Example: Building a Complex Prompt
# Before Python 3.12, this would be a syntax error
import json
user_query = "What are the top 3 trending AI tools in 2025?"
search_results = ["Vercel AI SDK", "Phidata", "Railway"]
prompt = f"""
You are a helpful AI assistant. Your task is to answer the user's query
based on the provided search results.
User Query: {user_query}
Search Results:
{json.dumps(
search_results,
indent=2 # You can now have comments and newlines inside!
)}
Please provide a concise answer.
"""
print(prompt)
This flexibility is invaluable when building complex prompts that need to incorporate multiple variables, API responses, or structured data formats.
2. Advanced Type Hinting (PEP 695 & PEP 698)
Clean, type-safe code is critical in production AI systems. Python 3.12 introduces two major improvements to type hinting.
a. New type Statement for Type Aliases (PEP 695)
Creating complex type aliases is now cleaner and more explicit.
💡 Why is this important for AI?
Modeling API Schemas: When working with libraries like Pydantic to define the expected structure of data from an LLM or an external API, you often deal with complex, nested data. Clear type aliases make this much easier to manage.
# The new, cleaner way in Python 3.12
type Point = tuple[float, float]
type Vector = list[Point]
def find_closest_point(points: Vector, target: Point) -> Point:
# ... function logic ...
return points[0] # Dummy return
b. @override Decorator for Subclassing (PEP 698)
This new decorator makes it explicit when a method in a subclass is intended to override a method from its parent. The type checker will raise an error if the parent method doesn't exist.
💡 Why is this important for AI?
Customizing Agents and Tools: When using frameworks like LangChain or Phidata, you often subclass base classes (BaseTool, BaseAgent, etc.) to create custom functionality. @override ensures that your custom methods correctly match the framework's expected interface, preventing subtle bugs.
from typing import override
class BaseSearchTool:
def run(self, query: str) -> str:
"""Run the search tool."""
raise NotImplementedError
class WebSearchTool(BaseSearchTool):
@override
def run(self, query: str) -> str:
print(f"Searching the web for: {query}")
return "Results..."
# A type checker like pyright will now catch typos
# e.g., if you wrote `def run_tool(...)` instead of `def run(...)`
3. Performance Boosts: Inlined Comprehensions & Asyncio
AI workloads can be computationally intensive. Python 3.12 brings some welcome speed-ups.
- Inlined Comprehensions: List, dict, and set comprehensions are now significantly faster. This is great for data preprocessing and transformation tasks that are common in AI.
- Faster Asyncio: The
asynciolibrary, which is the backbone of modern async Python, has received significant performance improvements. This is crucial for building responsive, high-throughput AI applications that make many concurrent calls to LLM APIs. We will coverasyncioin detail in Chapter 5.
4. "New in 2025" Trending Tools
To write modern Python, you need modern tools. Here are the essentials for 2025:
pip and pip-tools and is rapidly gaining popularity. We'll use it throughout this course.
curl -LsSf https://astral.sh/uv/install.sh | shUsage:
uv pip install requests
flake8, isort, and black.
uv pip install ruffUsage:
ruff check . | ruff format .
npm install -g pyrightUsage:
pyright .
Complete Example: Modern Python 3.12+ Features
Here's a complete example that demonstrates the features we've covered. You can download this code and run it locally to see these features in action.
# example-01-python-3-12-features.py
# New in Python 3.12: More flexible f-strings (PEP 701)
import json
def create_llm_prompt(user_query: str, search_results: list[str]) -> str:
"""
Demonstrates the flexible f-string formatting to build a complex
prompt for a Large Language Model.
"""
print("--- Demonstrating Flexible F-Strings ---")
prompt = f"""
You are a helpful AI assistant. Your task is to answer the user's query
based on the provided search results.
User Query: {user_query}
# You can now include comments inside f-strings!
Search Results:
{json.dumps(
search_results,
indent=2
)}
Please provide a concise and accurate answer based on the results.
"""
return prompt
# New in Python 3.12: Type Aliases and @override (PEP 695 & 698)
from typing import override
# Using the new `type` statement for cleaner type aliases
type Document = str
type DocumentStore = list[Document]
class BaseRetriever:
"""A base class for retrieving documents."""
def retrieve(self, query: str) -> DocumentStore:
raise NotImplementedError("Subclasses must implement this method.")
class SimpleRetriever(BaseRetriever):
"""A simple retriever that performs a basic search."""
def __init__(self, documents: DocumentStore):
self._documents = documents
@override # This ensures we are correctly overriding the parent method
def retrieve(self, query: str) -> DocumentStore:
print("\n--- Demonstrating @override Decorator ---")
print(f"Retrieving documents for query: '{query}'")
return [doc for doc in self._documents if query.lower() in doc.lower()]
# --- Main Execution ---
if __name__ == "__main__":
# 1. Demonstrate f-string prompt generation
query = "What are the best new agent frameworks in 2025?"
tools = ["LangGraph", "Phidata", "CrewAI"]
llm_prompt = create_llm_prompt(query, tools)
print(llm_prompt)
# 2. Demonstrate new typing features
knowledge_base: DocumentStore = [
"Phidata is a new AI agent framework known for its clean API.",
"LangGraph allows building stateful, multi-agent applications.",
"CrewAI is excellent for orchestrating role-playing agents.",
"Vercel AI SDK is primarily for frontend AI applications.",
]
# Use our retriever
retriever = SimpleRetriever(knowledge_base)
retrieved_docs = retriever.retrieve("phidata")
print("\nRetrieved Documents:")
for doc in retrieved_docs:
print(f"- {doc}")
📥 Download Example Code
Download example-01-python-3-12-features.py
Run with: python example-01-python-3-12-features.py
Key Takeaways
- Flexible f-strings make prompt engineering and logging cleaner and more powerful
- Type aliases and the
@overridedecorator improve code maintainability for complex AI systems - Performance improvements in Python 3.12 make data processing and async operations faster
- Modern tools like uv, ruff, and pyright are essential for professional Python development in 2025