{
"cells": [
{
"cell_type": "markdown",
"id": "3a045dd3",
"metadata": {},
"source": [
"# π Basic Agent Workflows with GitHub Models (Python)\n",
"\n",
"## π Workflow Orchestration Tutorial\n",
"\n",
"This notebook introduces the powerful **Workflow Builder** capabilities of the Microsoft Agent Framework. Learn how to create sophisticated, multi-step agent workflows that can handle complex business processes and coordinate multiple AI operations seamlessly.\n",
"\n",
"## π― Learning Objectives\n",
"\n",
"### ποΈ **Workflow Architecture**\n",
"- **Workflow Builder**: Design and orchestrate complex multi-step processes\n",
"- **Event-Driven Execution**: Handle workflow events and state transitions\n",
"- **Visual Workflow Design**: Create and visualize workflow structures\n",
"- **GitHub Models Integration**: Leverage AI models within workflow contexts\n",
"\n",
"### π **Process Orchestration**\n",
"- **Sequential Operations**: Chain multiple agent tasks in logical order\n",
"- **Conditional Logic**: Implement decision points and branching workflows\n",
"- **Error Handling**: Robust error recovery and workflow resilience\n",
"- **State Management**: Track and manage workflow execution state\n",
"\n",
"### π **Enterprise Workflow Patterns**\n",
"- **Business Process Automation**: Automate complex organizational workflows\n",
"- **Multi-Agent Coordination**: Coordinate multiple specialized agents\n",
"- **Scalable Execution**: Design workflows for enterprise-scale operations\n",
"- **Monitoring & Observability**: Track workflow performance and outcomes\n",
"\n",
"## βοΈ Prerequisites & Setup\n",
"\n",
"### π¦ **Required Dependencies**\n",
"\n",
"Install the Agent Framework with workflow capabilities:\n",
"\n",
"```bash\n",
"pip install agent-framework-core -U\n",
"```\n",
"\n",
"### π **GitHub Models Configuration**\n",
"\n",
"**Environment Setup (.env file):**\n",
"```env\n",
"GITHUB_TOKEN=your_github_personal_access_token\n",
"GITHUB_ENDPOINT=https://models.inference.ai.azure.com\n",
"GITHUB_MODEL_ID=gpt-4o-mini\n",
"```\n",
"\n",
"### π’ **Enterprise Use Cases**\n",
"\n",
"**Business Process Examples:**\n",
"- **Customer Onboarding**: Multi-step verification and setup workflows\n",
"- **Content Pipeline**: Automated content creation, review, and publishing\n",
"- **Data Processing**: ETL workflows with AI-powered transformation\n",
"- **Quality Assurance**: Automated testing and validation processes\n",
"\n",
"**Workflow Benefits:**\n",
"- π― **Reliability**: Deterministic execution with error recovery\n",
"- π **Scalability**: Handle high-volume process automation\n",
"- π **Observability**: Complete audit trails and monitoring\n",
"- π§ **Maintainability**: Visual design and modular components\n",
"\n",
"## π¨ Workflow Design Patterns\n",
"\n",
"### Basic Workflow Structure\n",
"```mermaid\n",
"graph TD\n",
" A[Start] --> B[Agent Task 1]\n",
" B --> C{Decision Point}\n",
" C -->|Success| D[Agent Task 2]\n",
" C -->|Failure| E[Error Handler]\n",
" D --> F[End]\n",
" E --> F\n",
"```\n",
"\n",
"**Key Components:**\n",
"- **WorkflowBuilder**: Main orchestration engine\n",
"- **WorkflowEvent**: Event handling and communication\n",
"- **WorkflowViz**: Visual workflow representation and debugging\n",
"\n",
"Let's build your first intelligent workflow! π"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "43a02f8d",
"metadata": {},
"outputs": [],
"source": [
"####### Linux / MacOS Setup Instructions #######\n",
"\n",
"####### Linux Instructions #######\n",
"# ! sudo apt update \n",
"# ! sudo apt install graphviz -y\n",
"\n",
"####### macOS Instructions #######\n",
"# ! brew install graphviz"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "c0863be7",
"metadata": {},
"outputs": [],
"source": [
"# ! pip install -r ../../../Installation/requirements.txt -U\n",
"# "
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "580e76d9",
"metadata": {},
"outputs": [],
"source": [
"# π Import Workflow and Agent Framework Components\n",
"# Core components for building sophisticated agent workflows\n",
"\n",
"from agent_framework.openai import OpenAIChatCompletionClient # π€ GitHub Models client integration\n",
"from agent_framework import AgentResponse, WorkflowBuilder, WorkflowEvent, WorkflowViz # ποΈ Workflow orchestration tools"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "5fe71939",
"metadata": {},
"outputs": [],
"source": [
"# π¦ Import Environment and System Utilities\n",
"# Essential libraries for configuration and environment management\n",
"\n",
"import os # π§ Environment variable access\n",
"from typing import cast\n",
"from dotenv import load_dotenv # π Secure configuration loading"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "cf183974",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# π§ Initialize Environment Configuration\n",
"# Load GitHub Models API credentials from .env file\n",
"load_dotenv()"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "7a679634",
"metadata": {},
"outputs": [],
"source": [
"# π Initialize GitHub Models Chat Client for Workflow Operations\n",
"# Create the AI client that will power agents within our workflow\n",
"chat_client = OpenAIChatCompletionClient(\n",
" base_url=os.environ.get(\"GITHUB_ENDPOINT\"), # π GitHub Models API endpoint\n",
" api_key=os.environ.get(\"GITHUB_TOKEN\"), # π Authentication token\n",
" model=os.environ.get(\"GITHUB_MODEL_ID\") # π― Selected AI model\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "ba45c08b",
"metadata": {},
"outputs": [],
"source": [
"REVIEWER_NAME = \"Concierge\"\n",
"REVIEWER_INSTRUCTIONS = \"\"\"\n",
" You are an are hotel concierge who has opinions about providing the most local and authentic experiences for travelers.\n",
" The goal is to determine if the front desk travel agent has recommended the best non-touristy experience for a traveler.\n",
" If so, state that it is approved.\n",
" If not, provide insight on how to refine the recommendation without using a specific example. \n",
" \"\"\""
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "d9f520ff",
"metadata": {},
"outputs": [],
"source": [
"FRONTDESK_NAME = \"FrontDesk\"\n",
"FRONTDESK_INSTRUCTIONS = \"\"\"\n",
" You are a Front Desk Travel Agent with ten years of experience and are known for brevity as you deal with many customers.\n",
" The goal is to provide the best activities and locations for a traveler to visit.\n",
" Only provide a single recommendation per response.\n",
" You're laser focused on the goal at hand.\n",
" Don't waste time with chit chat.\n",
" Consider suggestions when refining an idea.\n",
" \"\"\""
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "ad4819e0",
"metadata": {},
"outputs": [],
"source": [
"reviewer_agent = chat_client.as_agent(\n",
" instructions=(\n",
" REVIEWER_INSTRUCTIONS\n",
" ),\n",
" name=REVIEWER_NAME,\n",
" )\n",
"\n",
"front_desk_agent = chat_client.as_agent(\n",
" instructions=(\n",
" FRONTDESK_INSTRUCTIONS\n",
" ),\n",
" name=FRONTDESK_NAME,\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "150bb29b",
"metadata": {},
"outputs": [],
"source": [
"workflow = WorkflowBuilder(start_executor=front_desk_agent).add_edge(front_desk_agent, reviewer_agent).build()"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "e913c773",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Generating workflow visualization...\n",
"Mermaid string: \n",
"=======\n",
"flowchart TD\n",
" FrontDesk[\"FrontDesk (Start)\"];\n",
" Concierge[\"Concierge\"];\n",
" FrontDesk --> Concierge;\n",
"=======\n",
"DiGraph string: \n",
"=======\n",
"digraph Workflow {\n",
" rankdir=TD;\n",
" node [shape=box, style=filled, fillcolor=lightblue];\n",
" edge [color=black, arrowhead=vee];\n",
"\n",
" \"FrontDesk\" [fillcolor=lightgreen, label=\"FrontDesk\\n(Start)\"];\n",
" \"Concierge\" [label=\"Concierge\"];\n",
" \"FrontDesk\" -> \"Concierge\";\n",
"}\n",
"=======\n",
"SVG file saved to: /var/folders/h1/d_gywhr90l1g98mqlt6wwrkh0000gn/T/tmp6su6rovm.svg\n"
]
}
],
"source": [
"\n",
"print(\"Generating workflow visualization...\")\n",
"viz = WorkflowViz(workflow)\n",
"# Print out the mermaid string.\n",
"print(\"Mermaid string: \\n=======\")\n",
"print(viz.to_mermaid())\n",
"print(\"=======\")\n",
"# Print out the DiGraph string.\n",
"print(\"DiGraph string: \\n=======\")\n",
"print(viz.to_digraph())\n",
"print(\"=======\")\n",
"svg_file = viz.export(format=\"svg\")\n",
"print(f\"SVG file saved to: {svg_file}\")"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "5fe90eb5",
"metadata": {},
"outputs": [],
"source": [
"class DatabaseEvent(WorkflowEvent): ..."
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "e802947c",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Attempting to display SVG file at: /var/folders/h1/d_gywhr90l1g98mqlt6wwrkh0000gn/T/tmp6su6rovm.svg\n"
]
},
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Display the exported workflow SVG inline in the notebook\n",
"\n",
"from IPython.display import SVG, display, HTML\n",
"import os\n",
"\n",
"print(f\"Attempting to display SVG file at: {svg_file}\")\n",
"\n",
"if svg_file and os.path.exists(svg_file):\n",
" try:\n",
" # Preferred: direct SVG rendering\n",
" display(SVG(filename=svg_file))\n",
" except Exception as e:\n",
" print(f\"β οΈ Direct SVG render failed: {e}. Falling back to raw HTML.\")\n",
" try:\n",
" with open(svg_file, \"r\", encoding=\"utf-8\") as f:\n",
" svg_text = f.read()\n",
" display(HTML(svg_text))\n",
" except Exception as inner:\n",
" print(f\"β Fallback HTML render also failed: {inner}\")\n",
"else:\n",
" print(\"β SVG file not found. Ensure viz.export(format='svg') ran successfully.\")\n"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "a0651dfc",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"FrontDesk: Visit the Eiffel Towerβiconic, must-see, and offers stunning city views.\n",
"\n",
"Concierge: This recommendation is very typical and leans toward a touristy experience. To offer a more authentic and local Parisian experience, suggest exploring lesser-known neighborhoods, local markets, or hidden gardens that showcase the everyday life and culture of Parisians rather than landmark attractions crowded with visitors.\n",
"\n",
"Final state: WorkflowRunState.IDLE\n"
]
}
],
"source": [
"events = await workflow.run(\"I would like to go to Paris.\")\n",
"\n",
"outputs = events.get_outputs()\n",
" # The outputs of the workflow are whatever the agents produce. So the outputs are expected to be a list\n",
" # of `AgentResponse` from the agents in the workflow.\n",
"outputs = cast(list[AgentResponse], outputs)\n",
"for output in outputs:\n",
" print(f\"{output.messages[0].author_name}: {output.text}\\n\")\n",
"\n",
" # Summarize the final run state (e.g., COMPLETED)\n",
"print(\"Final state:\", events.get_final_state())"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "agentdev",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.10"
},
"polyglot_notebook": {
"kernelInfo": {
"defaultKernelName": "csharp",
"items": [
{
"aliases": [],
"name": "csharp"
}
]
}
}
},
"nbformat": 4,
"nbformat_minor": 5
}