This page provides practical implementation guides for building AI agents in Python and .NET, the two primary languages supported in this course. Each language guide covers framework usage patterns, async programming models, plugin development, memory management, and Azure service integration specific to that language ecosystem.
For framework architecture details and selection criteria, see AI Agent Frameworks. For production deployment patterns independent of language choice, see Production Deployment.
The repository supports dual-language development with distinct framework ecosystems optimized for each language's strengths:
| Language | Primary Frameworks | Typical Use Cases | Notebook Count |
|---|---|---|---|
| Python | Semantic Kernel, AutoGen, Azure AI Agent Service | Research, rapid prototyping, data science workflows, Jupyter-based development | ~40+ notebooks |
| .NET | Microsoft Agent Framework, Semantic Kernel | Enterprise applications, production systems, strongly-typed workflows, integration with .NET ecosystems | ~15+ notebooks |
Both languages share common infrastructure components (Azure AI Search, Azure OpenAI, GitHub Models) but differ in API patterns, type systems, and concurrency models.
Sources: requirements.txt1-31 .env.example1-26
The following diagram maps how language-specific SDKs interact with shared infrastructure, showing actual class names and package structures from the codebase:
Key Observations:
GITHUB_TOKEN, AZURE_OPENAI_API_KEY)SearchClient, AsyncOpenAI) provide language-idiomatic APIs to same underlying servicesSources: requirements.txt1-31 02-semantic-kernel.ipynb27-42 02-autogen.ipynb27-37 14-human-loop.ipynb99-124 01-intro-to-ai-agents/code_samples/01-dotnet-agent-framework.cs67-76
Both languages use .env files for configuration but load them differently:
Python Pattern:
.NET Pattern:
All samples consistently use these environment variables defined in .env.example1-26:
GITHUB_TOKEN - GitHub Models authenticationGITHUB_ENDPOINT - Base URL for inference APIAZURE_OPENAI_* - Azure OpenAI service configurationAZURE_SEARCH_* - Azure AI Search endpointsPROJECT_ENDPOINT - Azure AI Foundry project endpointSources: .env.example1-26 02-semantic-kernel.ipynb103-119 14-human-loop.ipynb126-133 01-intro-to-ai-agents/code_samples/01-dotnet-agent-framework.cs45-51
Both languages use async patterns but with different syntax:
Python (async/await):
.NET (Task-based):
Both patterns enable streaming responses, cancellation, and concurrent operations, but .NET uses Task<T> while Python uses Coroutine[T].
Sources: 04-semantic-kernel-tool.ipynb186-292 14-human-loop.ipynb99-134 01-intro-to-ai-agents/code_samples/01-dotnet-agent-framework.cs82-86
Python notebooks follow a consistent import pattern across all frameworks:
Framework Detection Pattern:
The choice of imports indicates which framework a notebook uses:
semantic_kernel.agents.ChatCompletionAgentautogen_agentchat.agents.AssistantAgentazure.ai.projects.AIProjectClientSources: 04-semantic-kernel-tool.ipynb18-37 02-autogen.ipynb27-37 02-azureaiagent.ipynb9-17
Semantic Kernel plugins use the @kernel_function decorator to expose Python functions as AI-callable tools:
Example from codebase:
The pattern in 04-semantic-kernel-tool.ipynb57-82 shows:
@kernel_function(description="...")Annotated[ReturnType, "Description"] for type hintsChatCompletionAgent(plugins=[...])The @kernel_function decorator:
Sources: 04-semantic-kernel-tool.ipynb57-82 05-semantic-kernel-azuresearch.ipynb94-155
Python notebooks consistently use async for to handle streaming responses with content type inspection:
Implementation Pattern:
04-semantic-kernel-tool.ipynb186-292 demonstrates the canonical streaming pattern:
full_response, function_calls, argument_buffer)async for response in agent.invoke_stream(...)response.items for content typeFunctionCallContent.arguments until completeFunctionResultContent.result when receivedStreamingTextContent.text to response bufferthread = response.thread for conversation continuityThis pattern enables:
Sources: 04-semantic-kernel-tool.ipynb186-292 02-semantic-kernel.ipynb166-243 05-semantic-kernel-azuresearch.ipynb243-326
Python Semantic Kernel uses ChatHistoryAgentThread for conversation state management:
The thread object:
invoke_stream() for persistence.delete() for cleanupSources: 04-semantic-kernel-tool.ipynb186-292 01-semantic-kernel.ipynb160-187
AutoGen uses a different architecture focused on message-based agent communication:
Key Differences from Semantic Kernel:
| Aspect | Semantic Kernel | AutoGen |
|---|---|---|
| Agent Creation | ChatCompletionAgent(service=..., plugins=...) | AssistantAgent(model_client=..., tools=...) |
| Message Format | String or ChatMessage | TextMessage(content=..., source=...) |
| Execution | invoke_stream(messages=...) | on_messages([messages], CancellationToken()) |
| Response | Streaming with async for | Single response.chat_message.content |
| Memory | ChatHistoryAgentThread | Agent state managed internally |
The AutoGen pattern emphasizes:
Sources: 02-autogen.ipynb54-156 05-autogen-chromadb.ipynb63-106
Python samples demonstrate vector database integration using azure-search-documents:
Implementation in 05-semantic-kernel-azuresearch.ipynb167-217:
Index Schema Definition (lines 188-194):
SimpleField(name="id", type=SearchFieldDataType.String, key=True)SearchableField(name="content", type=SearchFieldDataType.String)Client Initialization (lines 177-186):
Document Upload (line 216):
Retrieval in Plugin (lines 115-124):
This pattern enables:
Sources: 05-semantic-kernel-azuresearch.ipynb167-217 13-agent-memory.ipynb154-191
Advanced Python samples combine mem0ai with Azure AI Search for persistent agent memory:
Configuration Pattern from 13-agent-memory.ipynb154-191:
Memory Types Tracked:
Sources: 13-agent-memory.ipynb154-191
The .NET ecosystem centers on the Microsoft.Agents.AI and Microsoft.Extensions.AI packages with strong typing and workflow orchestration:
Fundamental Pattern from 01-intro-to-ai-agents/code_samples/01-dotnet-agent-framework.cs67-76:
Sources: 01-intro-to-ai-agents/code_samples/01-dotnet-agent-framework.cs67-76 02-explore-agentic-frameworks/code_samples/02-dotnet-agent-framework.cs93-100
[Description].NET samples define tools using static methods decorated with [Description] attributes, which the AIFunctionFactory uses to generate function schemas:
Key aspects:
[Description] attribute on the method provides the tool's overall purpose to the LLM.[Description] attribute on parameters provides details for each argument, enabling the LLM to correctly extract values.AIFunctionFactory.Create(MethodName) registers the method as a callable tool for the AIAgent.Sources: 01-intro-to-ai-agents/code_samples/01-dotnet-agent-framework.cs19-43 03-agentic-design-patterns/code_samples/03-dotnet-agent-framework.cs26-58
The .NET AIAgent uses AgentSession to maintain conversation context across multiple turns:
The AgentSession object:
RunStreamingAsync to continue the conversation contextually.Sources: 03-agentic-design-patterns/code_samples/03-dotnet-agent-framework.cs131 02-explore-agentic-frameworks/code_samples/02-dotnet-agent-framework.cs106
Both languages use identical GitHub Models authentication but with different client libraries:
Python (Semantic Kernel):
Python (AutoGen):
.NET (Microsoft Agent Framework):
All three patterns:
GITHUB_TOKEN from environmenthttps://models.inference.ai.azure.comgpt-4o-mini, gpt-4o)Sources: 02-semantic-kernel.ipynb103-119 02-autogen.ipynb54-76 01-intro-to-ai-agents/code_samples/01-dotnet-agent-framework.cs54-63
For production deployments, samples use Azure OpenAI Service:
Python (Azure AI Search + OpenAI):
Python (Azure AI Agent Service):
Environment Variables Required:
AZURE_OPENAI_ENDPOINT - Azure OpenAI resource endpointAZURE_OPENAI_API_KEY - API key (or use DefaultAzureCredential)AZURE_OPENAI_CHAT_DEPLOYMENT_NAME - Deployment name (e.g., "gpt-4o")AZURE_OPENAI_API_VERSION - API version (e.g., "2024-02-15-preview")PROJECT_ENDPOINT - Azure AI Foundry project endpoint (for Agent Service)Sources: 13-agent-memory.ipynb119-142 02-azureaiagent.ipynb21-34
All language implementations follow consistent notebook organization:
Standard Sections:
@kernel_function or [Description] decorated functionsasync def main() or await foreach with streaming response handlingThis structure ensures:
Sources: 04-semantic-kernel-tool.ipynb1-50 02-autogen.ipynb1-50 01-intro-to-ai-agents/code_samples/01-dotnet-agent-framework.cs1-10
Python notebooks use IPython.display for rich HTML formatting:
Common Styling Patterns:
This provides:
Sources: 14-conditional-workflow.ipynb138-162 14-human-loop.ipynb254-260 14-middleware.ipynb189-254
| Decision Factor | Choose Python | Choose .NET |
|---|---|---|
| Primary Use Case | Research, data science, rapid prototyping, Jupyter workflows | Enterprise applications, production systems, business process automation |
| Framework Preference | Semantic Kernel, AutoGen, Azure AI Agent Service | Microsoft Agent Framework, Semantic Kernel (.NET) |
| Type Safety Needs | Dynamic typing acceptable, prefer flexibility | Strong typing required, compile-time validation |
| Existing Codebase | Python/Flask/Django/FastAPI | ASP.NET/Blazor/.NET MAUI |
| Team Expertise | Data scientists, ML engineers | Enterprise developers, .NET architects |
| Development Speed | Fastest iteration (REPL, notebooks) | Slower initial setup, faster debugging |
| Workflow Complexity | Simple to moderate agent chains | Complex multi-step business processes with HITL |
| Deployment Target | Cloud functions, notebooks, APIs | Azure App Service, Kubernetes, Windows services |
| Observability Needs | Built-in with Langfuse/OpenLit | Built-in with OpenTelemetry + Azure Monitor |
Recommendation:
Sources: requirements.txt1-31 14-conditional-workflow.ipynb1-400 02-semantic-kernel.ipynb1-267
Issue: Streaming Response Buffer Management
Sources: 04-semantic-kernel-tool.ipynb207-260
Issue: Thread Memory Not Persisting
Sources: 04-semantic-kernel-tool.ipynb186-292
Issue: Missing AgentSession for Context
Sources: 03-agentic-design-patterns/code_samples/03-dotnet-agent-framework.cs131 02-explore-agentic-frameworks/code_samples/02-dotnet-agent-framework.cs106
Issue: Incorrect Tool Definition
Sources: 01-intro-to-ai-agents/code_samples/01-dotnet-agent-framework.cs19
Both languages benefit from proper async patterns:
Python:
async for for streaming responses (avoid blocking)asyncio.gather()nest_asyncio if running in Jupyter with existing event loopExample from 05-autogen-chromadb.ipynb22:
.NET:
await foreach for streamingTask.Wait() or Task.Result (causes deadlocks)ConfigureAwait(false) in library codeIAsyncEnumerable<T> for streamingSources: 05-autogen-chromadb.ipynb22 01-intro-to-ai-agents/code_samples/01-dotnet-agent-framework.cs82-86
Python:
await thread.delete() if thread else Nonegc.collect() for long-running notebook sessionsExample from 01-semantic-kernel.ipynb184-186:
.NET:
AgentSession objects when no longer needed using await using var session = ...AgentSession content.Sources: 01-semantic-kernel.ipynb184-186 03-agentic-design-patterns/code_samples/03-dotnet-agent-framework.cs131
This guide has covered language-specific patterns for implementing AI agents in Python and .NET, including:
Python Ecosystem:
@kernel_function plugins and ChatHistoryAgentThreadAssistantAgent and message passingAIProjectClient for managed deployments.NET Ecosystem:
AIAgent for core agent functionality[Description] attributes for tool definitionAgentSession for conversation context managementawait foreachBoth languages share:
For detailed framework comparisons, see AI Agent Frameworks. For production deployment strategies, see Production Deployment. For specific implementation examples in your chosen language, see Python Development Guide or .NET Development Guide.
Refresh this wiki