Author: waltergavarrete26

  • SQL Server + AI

    Advanced

    Your data already lives in SQL Server. Your application queries run against it thousands of times per day. So why move data out to a separate AI service when you can bring AI capabilities directly into the database? From native vector search in Azure SQL to in-database Python/R execution and direct Azure OpenAI integration, SQL Server is becoming an AI-ready platform.

    This guide covers the AI features across SQL Server 2022, Azure SQL Database, and Azure SQL Managed Instance — with production-ready T-SQL and Python code for each capability.


    The AI capabilities in SQL Server

    SQL SERVER AI CAPABILITIES SQL Server 2022 / Azure SQL Your Data Lives Here Vector Search Native embeddings + similarity Machine Learning Services In-database Python & R Azure OpenAI Integration Call LLMs from T-SQL PREDICT Function Native ONNX model scoring Intelligent Query Processing Query Store + Auto-Tuning

    Vector search in Azure SQL

    Azure SQL Database now supports native vector operations, enabling RAG (Retrieval-Augmented Generation) patterns directly in your database. Store embeddings alongside your relational data and perform similarity searches without an external vector database.

    Storing embeddings

    CREATE TABLE Documents (
        Id INT IDENTITY PRIMARY KEY,
        Title NVARCHAR(500),
        Content NVARCHAR(MAX),
        Embedding VECTOR(1536)  -- matches text-embedding-3-small dimensions
    );
    
    -- Insert a document with its embedding
    INSERT INTO Documents (Title, Content, Embedding)
    VALUES (
        'Remote Work Policy',
        'Employees may work remotely up to 3 days per week...',
        CAST('[0.0023, -0.0112, 0.0451, ...]' AS VECTOR(1536))
    );

    Similarity search

    DECLARE @query_embedding VECTOR(1536) = /* embedding of the user's question */;
    
    SELECT TOP 5
        Id,
        Title,
        VECTOR_DISTANCE('cosine', Embedding, @query_embedding) AS distance
    FROM Documents
    ORDER BY VECTOR_DISTANCE('cosine', Embedding, @query_embedding);

    The VECTOR_DISTANCE function supports cosine, euclidean, and dot product distance metrics. Combined with a columnstore index, it handles millions of vectors efficiently.

    Building a RAG pipeline in T-SQL

    Here’s the complete pattern — generate an embedding for the user’s question, find relevant documents, and send both to Azure OpenAI for a grounded answer:

    -- Step 1: Generate embedding for the user's question
    DECLARE @question NVARCHAR(MAX) = 'Can I work from home on Fridays?';
    DECLARE @embedding VECTOR(1536);
    
    EXEC sp_invoke_external_rest_endpoint
        @url = 'https://your-resource.openai.azure.com/openai/deployments/text-embedding-3-small/embeddings?api-version=2024-02-01',
        @method = 'POST',
        @payload = '{"input": "Can I work from home on Fridays?"}',
        @response = @embedding OUTPUT;
    
    -- Step 2: Find relevant documents
    SELECT TOP 3 Content
    INTO #context
    FROM Documents
    ORDER BY VECTOR_DISTANCE('cosine', Embedding, @embedding);
    
    -- Step 3: Send context + question to Azure OpenAI
    DECLARE @context NVARCHAR(MAX) = (SELECT STRING_AGG(Content, CHAR(10)) FROM #context);
    
    EXEC sp_invoke_external_rest_endpoint
        @url = 'https://your-resource.openai.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2024-02-01',
        @method = 'POST',
        @payload = /* JSON with system message + context + question */;
    Why this matters: Your data stays in the database. No ETL to an external vector store, no data synchronization issues, no additional infrastructure. The same security, backup, and compliance policies that protect your SQL data also protect your embeddings.

    Machine Learning Services

    SQL Server 2022 includes Machine Learning Services, which lets you run Python and R scripts directly inside the database engine using sp_execute_external_script.

    EXEC sp_execute_external_script
        @language = N'Python',
        @script = N'
    import pandas as pd
    from sklearn.cluster import KMeans
    
    # InputDataSet is automatically populated from @input_data
    model = KMeans(n_clusters=4, random_state=42)
    InputDataSet["cluster"] = model.fit_predict(
        InputDataSet[["total_purchases", "avg_order_value", "days_since_last_order"]]
    )
    OutputDataSet = InputDataSet
    ',
        @input_data_1 = N'SELECT customer_id, total_purchases, avg_order_value, days_since_last_order FROM CustomerMetrics'
    WITH RESULT SETS ((
        customer_id INT,
        total_purchases DECIMAL(10,2),
        avg_order_value DECIMAL(10,2),
        days_since_last_order INT,
        cluster INT
    ));

    This runs the Python script in a sandboxed process alongside the SQL Server engine. Data flows in via InputDataSet and out via OutputDataSet — no data leaves the server.

    Native PREDICT function

    SQL Server 2022 can score ONNX models natively with the PREDICT function — no external runtime needed:

    -- Load an ONNX model into the database
    CREATE TABLE MLModels (
        model_name NVARCHAR(100) PRIMARY KEY,
        model_data VARBINARY(MAX)
    );
    
    INSERT INTO MLModels (model_name, model_data)
    SELECT 'churn_predictor', BulkColumn
    FROM OPENROWSET(BULK '/models/churn_model.onnx', SINGLE_BLOB) AS model;
    
    -- Score data inline with a SELECT query
    DECLARE @model VARBINARY(MAX) = (
        SELECT model_data FROM MLModels WHERE model_name = 'churn_predictor'
    );
    
    SELECT
        c.customer_id,
        c.customer_name,
        p.predicted_churn,
        p.churn_probability
    FROM PREDICT(MODEL = @model, DATA = Customers AS c)
    WITH (predicted_churn INT, churn_probability FLOAT) AS p
    WHERE p.churn_probability > 0.7;

    This enables real-time scoring at query time — every SELECT can include predictions without any application-layer ML infrastructure.

    Calling Azure OpenAI from T-SQL

    Azure SQL Database’s sp_invoke_external_rest_endpoint lets you call REST APIs directly from T-SQL — including Azure OpenAI:

    DECLARE @response NVARCHAR(MAX);
    
    EXEC sp_invoke_external_rest_endpoint
        @url = 'https://your-resource.openai.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2024-02-01',
        @method = 'POST',
        @headers = '{"api-key": "your-key"}',
        @payload = '
        {
            "messages": [
                {"role": "system", "content": "Classify this support ticket into: billing, technical, account. Reply with one word."},
                {"role": "user", "content": "I was charged twice for my subscription this month"}
            ],
            "max_tokens": 10,
            "temperature": 0
        }',
        @response = @response OUTPUT;
    
    SELECT JSON_VALUE(@response, '$.result.choices[0].message.content') AS category;
    Security: Use managed identity authentication instead of API keys. Azure SQL can authenticate to Azure OpenAI via @credential_name parameter, leveraging the database’s system-assigned managed identity.

    Intelligent Query Processing

    Beyond explicit AI features, SQL Server 2022 uses AI internally to optimize performance:

    • Intelligent query processing (IQP) — automatic plan optimization, adaptive joins, and memory grant feedback.
    • Query Store hints — the engine learns from past executions and applies query-level optimizations automatically.
    • Cardinality estimation feedback — the optimizer corrects its estimates based on actual execution data.
    • DOP (Degree of Parallelism) feedback — automatically adjusts parallelism per query based on runtime behavior.
    • Optimized plan forcing — the Query Store detects and prevents plan regressions by forcing previously good plans.

    These features require no code changes — enable them at the database level and the engine self-optimizes over time.

    SQL Server + AI: feature matrix

    FeatureSQL Server 2022Azure SQL DBAzure SQL MI
    Vector search (VECTOR type)Coming soonAvailableAvailable
    ML Services (Python/R)AvailableNot availableAvailable
    PREDICT (ONNX)AvailableAvailableAvailable
    REST endpoint (sp_invoke_external)Not availableAvailableNot available
    Intelligent query processingAvailableAvailableAvailable

    Production architecture

    1. Embeddings pipeline — generate embeddings on INSERT/UPDATE using a trigger or a scheduled job that calls Azure OpenAI. Cache embeddings in the VECTOR column to avoid recomputing.
    2. Index strategy — use a columnstore index on your vector column for large-scale similarity search. For smaller tables (< 100K rows), brute-force cosine distance is fast enough.
    3. Security — use row-level security (RLS) to ensure users only search documents they have access to. The same RLS policies apply to vector searches.
    4. Monitoring — track AI-related query costs with Extended Events. Monitor sp_invoke_external_rest_endpoint call durations and error rates.
    5. Fallback — wrap external API calls in TRY/CATCH blocks. If Azure OpenAI is unavailable, return a graceful error instead of failing the entire query.

    Next steps

    1. Enable vector support in Azure SQL Database — it’s available in the latest compatibility level.
    2. Store your first embeddings — pick a small table and add a VECTOR column.
    3. Try PREDICT — export a scikit-learn model to ONNX and score it in T-SQL.
    4. Read the docs: learn.microsoft.com/sql/machine-learning
    What would in-database AI change for your application? When AI runs where the data lives, you eliminate latency, simplify architecture, and keep data secure. Share your scenario in the comments — I’ll help you design the SQL-side implementation.
  • Microsoft Fabric + AI

    Advanced

    Most organizations run their data stack across disconnected services — a data lake here, a warehouse there, separate tools for ETL, BI, data science, and real-time analytics. Microsoft Fabric unifies all of these into a single SaaS platform built on a shared OneLake foundation. One copy of data, one security model, one governance layer — from ingestion to machine learning to dashboards.

    This guide covers Fabric’s architecture in depth, walks through the major workloads with real code, and shows how AI capabilities are woven into every layer of the platform.


    Architecture: OneLake and the Lakehouse

    Fabric’s central innovation is OneLake — a single, multi-cloud data lake for your entire organization. Think of it as “OneDrive for data.” Every Fabric workload reads and writes to OneLake, which means:

    • No data duplication — the data warehouse, data science notebooks, and Power BI reports all reference the same underlying data.
    • One security model — define access once in OneLake; it applies everywhere.
    • Open format — data is stored in Delta/Parquet format, accessible via standard tools and APIs.
    MICROSOFT FABRIC ARCHITECTURE OneLake (Delta / Parquet) Unified storage • One security model • Open format Data Factory ETL / Data Pipelines 130+ Connectors Synapse DE Spark Notebooks Data Engineering Synapse DW SQL Analytics T-SQL Endpoint Real-Time Intel. KQL / Eventstream Streaming Analytics Data Science ML Models / MLflow Experiments Power BI Reports / Dashboards Direct Lake Mode Data Activator Trigger Actions on Data Patterns

    The Lakehouse: where SQL meets Spark

    A Lakehouse in Fabric combines the scalability of a data lake with the query performance of a data warehouse. It’s the primary analytical data structure, and it gives you two interfaces:

    • Spark notebooks — transform and process data with PySpark, Scala, or SparkSQL.
    • SQL analytics endpoint — query the same data with standard T-SQL, no data movement needed.

    Creating a Lakehouse and loading data

    # PySpark notebook in Fabric
    
    # Read CSV from external source into the Lakehouse
    df = spark.read \
        .option("header", "true") \
        .option("inferSchema", "true") \
        .csv("abfss://raw@onelake.dfs.fabric.microsoft.com/sales_2024.csv")
    
    # Clean and transform
    from pyspark.sql import functions as F
    
    df_clean = df \
        .withColumn("order_date", F.to_date("order_date", "yyyy-MM-dd")) \
        .withColumn("revenue", F.col("quantity") * F.col("unit_price")) \
        .filter(F.col("status") != "cancelled")
    
    # Write as Delta table to the Lakehouse
    df_clean.write \
        .mode("overwrite") \
        .format("delta") \
        .saveAsTable("sales_clean")

    Once the Delta table exists, it’s immediately queryable through the SQL endpoint — no import step required:

    -- SQL analytics endpoint (T-SQL)
    SELECT
        YEAR(order_date) AS year,
        MONTH(order_date) AS month,
        SUM(revenue) AS total_revenue,
        COUNT(*) AS order_count
    FROM sales_clean
    GROUP BY YEAR(order_date), MONTH(order_date)
    ORDER BY year, month;

    Data pipelines with Data Factory

    Fabric’s Data Factory handles ETL/ELT at scale. It supports 130+ connectors and provides a visual pipeline designer:

    • Copy activity — move data from any source to OneLake (databases, APIs, SaaS apps, files).
    • Dataflows Gen2 — low-code transformations with Power Query for business users.
    • Notebook activity — run Spark notebooks as pipeline steps for complex transformations.
    • Orchestration — schedule pipelines, set dependencies, handle retries and error paths.

    Data Science: ML models in Fabric

    Fabric’s Data Science workload provides a full ML lifecycle:

    import mlflow
    from sklearn.ensemble import GradientBoostingRegressor
    from sklearn.model_selection import train_test_split
    
    # Load data from the Lakehouse
    df = spark.sql("SELECT * FROM sales_clean").toPandas()
    
    X = df[["quantity", "unit_price", "discount", "region_code"]]
    y = df["revenue"]
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
    
    # Track with MLflow (built into Fabric)
    mlflow.set_experiment("revenue-prediction")
    
    with mlflow.start_run():
        model = GradientBoostingRegressor(n_estimators=200, max_depth=5)
        model.fit(X_train, y_train)
    
        score = model.score(X_test, y_test)
        mlflow.log_metric("r2_score", score)
        mlflow.sklearn.log_model(model, "revenue_model")
    
        print(f"R² Score: {score:.4f}")

    Models tracked in MLflow can be registered, versioned, and deployed directly as Fabric ML endpoints for batch or online predictions — without leaving the platform.

    PREDICT function: ML in T-SQL

    Once a model is registered, you can call it directly from SQL queries:

    SELECT *,
        PREDICT(revenue_model, *) AS predicted_revenue
    FROM sales_forecast_input;

    This bridges the gap between data scientists who build models and analysts who consume them — no API calls, no separate infrastructure.

    Real-Time Intelligence

    For streaming data, Fabric provides Eventhouse (KQL-based) and Eventstream:

    • Eventstream — ingest from Azure Event Hubs, IoT Hub, Kafka, or custom sources.
    • Eventhouse — store and query streaming data with KQL (Kusto Query Language).
    • Real-time dashboards — Power BI visuals that refresh every few seconds.
    • Data Activator — trigger alerts and actions when data patterns match your conditions (e.g., “notify me if temperature exceeds 80°C for 5 minutes”).
    // KQL query in Eventhouse
    SensorReadings
    | where Timestamp > ago(1h)
    | summarize AvgTemp = avg(Temperature), MaxTemp = max(Temperature)
        by bin(Timestamp, 5m), DeviceId
    | where AvgTemp > 75
    | order by Timestamp desc

    Copilot in Fabric

    Copilot is integrated across Fabric workloads:

    WorkloadCopilot capability
    Data FactoryGenerate pipeline steps from natural language descriptions
    NotebooksWrite and explain PySpark code, fix errors, add documentation
    SQLGenerate T-SQL queries from questions about your data
    Power BICreate reports, suggest visuals, build DAX measures from descriptions
    Data ScienceGenerate ML code, suggest feature engineering, explain model results

    Capacity and pricing

    Fabric uses a Capacity Unit (CU) model. All workloads share the same capacity pool:

    SKUCUsBest for
    F22Development and testing
    F1616Small teams, light production
    F6464Department-level analytics
    F256+256+Enterprise, heavy workloads
    TrialLimited60-day free trial with full features
    Cost management: Fabric supports pause/resume on capacity — pause during off-hours to avoid charges when no workloads are running. Use capacity metrics dashboards to monitor which workloads consume the most resources.

    Fabric vs. the alternatives

    AspectMicrosoft FabricDatabricksSnowflake
    ArchitectureUnified SaaS (all workloads integrated)Lakehouse (Spark-centric)Cloud data warehouse
    StorageOneLake (Delta/Parquet)Delta LakeProprietary columnar
    Data engineeringSpark + Data FactorySpark + WorkflowsSnowpark (limited)
    BI integrationNative Power BIPartner integrationsPartner integrations
    Real-timeEventhouse (KQL)Structured StreamingSnowpipe Streaming
    Best forMicrosoft-stack orgs, unified analyticsData engineering teams, ML at scaleSQL-centric analytics

    Next steps

    1. Start a free trial at app.fabric.microsoft.com — 60 days with full capabilities.
    2. Create a Lakehouse — load a CSV, transform it with Spark, and query it with SQL.
    3. Build a pipeline — connect an external data source and schedule automatic ingestion.
    4. Read the docs: learn.microsoft.com/fabric
    Ready to unify your data stack? Fabric eliminates the complexity of managing separate services for data engineering, science, and BI. Share your current setup in the comments — I’ll help you plan the migration.
  • Power Apps + Copilot

    Intermediate

    Building a business application used to mean weeks of development, design reviews, and deployment pipelines. With Copilot in Power Apps, you describe what you need in plain English and the AI generates a working app — tables, screens, formulas, and navigation included. Then you customize it visually until it fits your exact requirements.

    This guide covers how to create apps with Copilot, add AI-powered features to canvas apps, connect to enterprise data sources, and govern AI usage across your organization.


    What Copilot brings to Power Apps

    Copilot is embedded throughout the Power Apps experience:

    • App generation — describe your app in natural language and get a working prototype with a data model, screens, and navigation.
    • Copilot control — add a conversational AI assistant directly inside your app that users interact with.
    • Formula assistance — write Power Fx formulas by describing what you want instead of remembering syntax.
    • Edit with Copilot — modify existing apps by telling Copilot what to change (“add a status filter to the gallery”, “make the header blue”).

    Building your first app with Copilot

    Step 1: Describe your app

    1. Go to make.powerapps.com.
    2. In the home screen, you’ll see the Copilot prompt: “Describe the app you want to build”.
    3. Type a description, for example:
    "Create an app to track equipment maintenance requests.
    Each request has an equipment name, location, priority
    (low/medium/high), description of the issue, assigned
    technician, status (open/in progress/completed), and
    date submitted."

    Step 2: Review the generated table

    Copilot creates a Dataverse table based on your description — with columns, data types, and sample data already populated. You can:

    • Add or remove columns.
    • Change data types (text, choice, date, number).
    • Edit the sample data to better reflect your real content.
    • Ask Copilot to modify the table: “Add a column for estimated repair cost”.

    Step 3: Generate the app

    Click Create app and Copilot generates a full canvas app with:

    • A gallery screen listing all records with search and filter.
    • A detail screen showing the full record.
    • A form screen for creating and editing records.
    • Navigation between screens already wired up.
    • A Copilot control embedded in the app for users to ask questions about the data.
    Important: The generated app is a starting point, not a finished product. Plan to spend 30-60 minutes customizing the layout, adding business rules, and connecting additional data sources.

    The Copilot control

    The Copilot control is an AI chat component you can add to any canvas app. It lets end users interact with the app’s data conversationally:

    • “Show me all high-priority requests from this week” — Copilot filters the data and displays results.
    • “How many open tickets does each technician have?” — Copilot generates a summary.
    • “Create a new request for the HVAC unit in Building 3” — Copilot pre-fills a form.

    The control is data-aware: it understands your Dataverse tables and can query, summarize, and present information without you writing any formulas.

    Adding the Copilot control to an existing app

    1. Open your canvas app in the editor.
    2. Go to InsertAICopilot.
    3. Place the control on your screen.
    4. In the control’s properties, set the data source to your Dataverse table.
    5. Configure allowed actions: read-only (queries only) or read-write (can also create/update records).

    Formula assistance with Copilot

    Power Fx — the formula language behind Power Apps — has a learning curve. Copilot helps by translating natural language into formulas:

    You sayCopilot generates
    “Filter the gallery to show only open requests”Filter(Requests, Status.Value = "Open")
    “Sort by priority: high first, then medium, then low”SortByColumns(Gallery1.AllItems, "Priority", SortOrder.Descending)
    “Show the count of requests per technician”GroupBy(Requests, "Technician", "Count", CountRows(Requests))
    “Change the header color to red if overdue”If(DateDiff(Today(), ThisItem.DueDate) < 0, Red, Color.DarkBlue)

    Click the Copilot icon in the formula bar, describe what you want, and it generates the Power Fx expression. Review it, then accept or modify.

    Connecting to enterprise data

    Generated apps start with Dataverse, but most business scenarios need data from multiple sources:

    • SharePoint — connect to lists for document libraries, task tracking, and team data.
    • SQL Server / Azure SQL — pull data from your relational databases.
    • Dynamics 365 — access CRM, ERP, and business application data.
    • Custom APIs — connect to any REST API via custom connectors.
    • Excel / OneDrive — use spreadsheets as lightweight data sources for prototyping.

    Power Apps supports 1,000+ connectors out of the box. For data that doesn't have a connector, build a custom connector by providing the API's OpenAPI specification.

    Model-driven apps vs. canvas apps

    AspectCanvas appsModel-driven apps
    Design approachPixel-perfect, drag-and-drop layoutData model defines the UI automatically
    Best forCustom UIs, mobile apps, specific workflowsComplex data models, CRM-style applications
    Copilot supportFull (generation, editing, formulas, control)Table generation, form customization
    Data sourceAny connector (Dataverse, SQL, SharePoint, APIs)Dataverse only
    ResponsiveManual configuration requiredBuilt-in responsive layout

    For most scenarios with Copilot, start with a canvas app — it gives you full control over the user experience. Use model-driven apps when you have complex relational data with many entities and relationships.

    Real-world scenarios

    Inventory tracker with barcode scanning

    Ask Copilot to generate an inventory management app. Add the barcode scanner control to let warehouse staff scan items with their phone camera. Connect to a SharePoint list where inventory data lives, and add a Power Automate flow that sends low-stock alerts.

    Field service inspection app

    Build an app where technicians log inspections with photos, GPS coordinates, and checklists. The Copilot control lets them ask: "Show me all failed inspections in Zone B this month." Add an AI Builder model to auto-classify inspection photos (pass/fail).

    Employee onboarding dashboard

    Generate an app that tracks new hire onboarding tasks. Each task has an owner, due date, and status. The Copilot control lets HR managers ask: "Which new hires haven't completed compliance training?" Connect to Microsoft 365 to pull employee profiles automatically.

    Governance and security

    • Environment strategy — use separate environments for dev, test, and production. Promote apps through managed solutions.
    • DLP policies — control which connectors can be used together to prevent data leakage.
    • Copilot controls — administrators can enable or disable Copilot features per environment via the Power Platform admin center.
    • Sharing — share apps with specific security groups. Users only see data they have permission to access in the underlying data sources.

    Next steps

    1. Try the Copilot app builder at make.powerapps.com — generate an app from a description in under 5 minutes.
    2. Add the Copilot control to an existing canvas app and connect it to a Dataverse table.
    3. Explore the formula bar — use Copilot to generate a complex filter or conditional formatting formula.
    4. Read the docs: learn.microsoft.com/power-apps
    What app would you build in 5 minutes? Copilot in Power Apps turns ideas into working prototypes faster than ever. Describe your app idea in the comments — let's see what Copilot can generate.
  • Power Automate + AI Builder

    Intermediate

    Your team processes hundreds of invoices manually. Employees copy data from emails into spreadsheets. Approval chains stall because someone forgot to forward a document. Power Automate + AI Builder eliminates these bottlenecks by combining workflow automation with ready-to-use AI models — no machine learning expertise required.

    This guide shows you how to build AI-powered automations that read documents, classify emails, analyze sentiment, and route decisions automatically across your organization.


    How Power Automate and AI Builder work together

    Power Automate is Microsoft’s automation platform — it connects triggers (an email arrives, a file is uploaded, a form is submitted) to actions (send a notification, update a database, create a task). AI Builder adds intelligence to those flows by providing pre-built and custom AI models that you can drop into any automation step.

    POWER AUTOMATE + AI BUILDER Trigger Email arrives File uploaded Form submitted AI Builder Extract invoice data Classify & route Analyze sentiment Logic Conditions Approvals Loops Action Update CRM Send notification Create record

    AI Builder model types

    ModelWhat it doesUse case
    Invoice processingExtracts fields from invoices (vendor, amount, date, line items)Accounts payable automation
    Receipt processingReads receipt data (merchant, total, date, items)Expense reporting
    Document processingExtracts data from custom document formatsContracts, forms, applications
    Text classificationCategorizes text into custom categoriesSupport ticket routing, email triage
    Sentiment analysisDetects positive, negative, or neutral toneCustomer feedback, social monitoring
    Entity extractionIdentifies names, dates, addresses, and custom entitiesData entry, document parsing
    Object detectionIdentifies objects in imagesQuality inspection, inventory
    GPT (prompt-based)Generates text, summarizes, translates using Azure OpenAIContent creation, summarization, Q&A

    Building an invoice processing flow

    Let’s build a complete automation: invoices arrive via email, AI Builder extracts the data, and the flow creates records and routes approvals.

    Step 1: Create the flow trigger

    1. Go to make.powerautomate.com.
    2. Click CreateAutomated cloud flow.
    3. Choose the trigger: When a new email arrives (V3) from the Outlook connector.
    4. Add a filter: Has attachments = Yes and Subject contains “invoice”.

    Step 2: Add AI Builder invoice processing

    1. Add a new step and search for “AI Builder”.
    2. Select Extract information from invoices.
    3. Set the Invoice file to the email attachment content.
    4. AI Builder returns structured data: vendor name, invoice number, amount due, due date, line items, and confidence scores.

    Step 3: Add business logic

    Condition: Amount due > $5,000
      Yes → Start an approval (Manager)
        Approved → Create row in SharePoint "Approved Invoices"
        Rejected → Send email to vendor with rejection reason
      No → Auto-approve → Create row in SharePoint
    
    Always: Update Excel tracker with extracted data

    Step 4: Error handling

    AI Builder returns a confidence score for each extracted field. Build conditions around it:

    • Confidence > 0.85 → auto-process the invoice.
    • Confidence 0.60 – 0.85 → route to a human for review.
    • Confidence < 0.60 → flag as unreadable and notify the sender.
    Pro tip: Always add a “Configure run after” setting on your error-handling steps so they execute even when a previous step fails. This prevents silent failures in production flows.

    Building a custom text classifier

    Pre-built models cover common scenarios, but what if you need to classify support tickets into your own categories? AI Builder lets you train custom models with your data.

    1. Go to AI BuilderBuildText classification.
    2. Define your categories (e.g., “billing”, “technical”, “shipping”, “returns”).
    3. Upload or connect your training data — a minimum of 10 tagged examples per category, though 50+ produces better results.
    4. Click Train. AI Builder trains and evaluates the model automatically.
    5. Review the accuracy metrics and publish the model when satisfied.

    Once published, use it in Power Automate just like any pre-built model:

    Trigger: When a new item is created in SharePoint "Support Tickets"
    Step 1: AI Builder → Classify text (your custom model)
      Input: Ticket description
    Step 2: Condition on classification result
      "billing" → Assign to finance team
      "technical" → Assign to engineering team
      "shipping" → Assign to logistics team
      "returns" → Start return process flow

    Using GPT in Power Automate

    AI Builder includes a GPT-based action (powered by Azure OpenAI) that lets you add generative AI to any flow without managing API keys or deployments.

    Summarize long emails automatically

    Trigger: When an email arrives with body length > 500 characters
    Step 1: AI Builder → Create text with GPT
      Prompt: "Summarize this email in 3 bullet points: {{email body}}"
    Step 2: Post summary to Teams channel

    Generate customer response drafts

    Trigger: New support ticket created
    Step 1: AI Builder → Create text with GPT
      Prompt: "Draft a professional response to this customer complaint.
       Be empathetic and offer a concrete next step: {{ticket description}}"
    Step 2: Create draft email (not sent — human reviews first)
    Step 3: Send Teams notification to support agent for review

    Governance and monitoring

    In enterprise environments, you need to control who uses AI Builder and track usage:

    • AI Builder credits — each AI action consumes credits. Monitor usage in the Power Platform Admin Center.
    • Data Loss Prevention (DLP) policies — restrict which connectors can be used together to prevent data leakage.
    • Environment controls — isolate production flows from development using Power Platform environments.
    • Flow analytics — track run history, failure rates, and processing times in the admin center.

    Licensing

    PlanAI Builder includedNotes
    Power Automate Premium5,000 AI credits/monthPer user, includes attended + unattended flows
    AI Builder add-on1M credits/month (per unit)Add to any Power Platform plan
    TrialLimited credits for 30 daysAvailable at make.powerautomate.com

    One invoice extraction costs approximately 1 credit. One GPT prompt costs 1-3 credits depending on token usage. Monitor your consumption to avoid surprises.

    Next steps

    1. Start a trial at make.powerautomate.com and explore the AI Builder templates.
    2. Build an invoice flow — connect your Outlook and let AI Builder extract data from a real invoice.
    3. Train a text classifier — use 50 support tickets to build a custom routing model.
    4. Read the docs: learn.microsoft.com/ai-builder
    What process would you automate first? Power Automate + AI Builder can eliminate hours of manual work. Tell me about your most tedious workflow in the comments — let’s figure out how to automate it.
  • AI Toolkit en VS Code

    Intermediate

    You don’t need a cloud subscription to experiment with AI models. The AI Toolkit for Visual Studio Code brings model discovery, local inference, fine-tuning, and evaluation directly into your editor — the same place you already write code. It’s a complete AI development workbench without leaving VS Code.

    This guide covers the full workflow: browsing the model catalog, running models locally, fine-tuning with your own data, and deploying to Azure when you’re ready for production.


    What is the AI Toolkit?

    The AI Toolkit is a VS Code extension developed by Microsoft that provides:

    • Model catalog — browse and download models from Hugging Face, Azure AI, and ONNX collections directly in VS Code.
    • Local playground — run models on your machine for testing, prototyping, and evaluation without any API calls.
    • Fine-tuning — customize models with your own datasets using QLoRA or LoRA, running locally or on remote compute.
    • Evaluation — benchmark model quality with built-in metrics before deployment.
    • Deployment — push fine-tuned models to Azure AI endpoints with a few clicks.

    It integrates with your existing VS Code workflow — terminal, source control, debugging — so AI development feels like any other coding task.

    Development workflow

    AI TOOLKIT WORKFLOW Discover Model Catalog Browse & Download Playground Local Inference Test & Iterate Fine-Tune QLoRA / LoRA Your Data Evaluate Quality Metrics Compare Models Deploy Azure AI Endpoints

    Installation and setup

    1. Open VS Code and go to the Extensions panel (Ctrl+Shift+X).
    2. Search for “AI Toolkit” and install the extension by Microsoft.
    3. After installation, a new AI Toolkit icon appears in the activity bar (left sidebar).
    4. Click it to open the toolkit panel with the model catalog, playground, and fine-tuning options.

    Hardware requirements

    FeatureMinimumRecommended
    Model playground (small models)16 GB RAM, integrated GPU32 GB RAM, NVIDIA GPU 6+ GB VRAM
    Fine-tuning (QLoRA)NVIDIA GPU with 8 GB VRAMNVIDIA GPU with 16+ GB VRAM
    Remote fine-tuningAny machine + Azure subscriptionAzure ML compute with GPU
    No GPU? You can still browse the catalog and use the playground with CPU-optimized ONNX models. Fine-tuning without a GPU requires remote compute via Azure ML.

    Browsing the model catalog

    The model catalog is the starting point. It aggregates models from multiple sources:

    • Hugging Face — thousands of open models (Phi, Llama, Mistral, Gemma).
    • Azure AI model catalog — Microsoft’s curated collection optimized for enterprise.
    • ONNX Runtime models — optimized for fast local inference on CPU and GPU.

    You can filter by task (text generation, classification, embeddings), size, license, and hardware requirements. Each model card shows parameter count, quantization options, and benchmark scores.

    Downloading a model

    Click any model in the catalog and select Download. The toolkit handles everything — downloading weights, setting up the runtime, and configuring the inference engine. Models are stored locally in your workspace.

    For a quick start, try Phi-3-mini-4k-instruct-onnx — a capable, small model that runs well on most hardware.

    The playground

    Once you download a model, the playground lets you interact with it immediately:

    • Chat interface — test conversational models with a familiar chat UI.
    • System prompt editor — configure the model’s persona and behavior.
    • Parameter controls — adjust temperature, top-p, max tokens, and other generation settings in real time.
    • Batch testing — run multiple prompts and compare outputs side by side.

    The playground runs entirely locally. No data leaves your machine, which makes it ideal for testing with sensitive prompts or proprietary data.

    Example: testing a classification prompt

    System prompt:
    You are a support ticket classifier. Classify each ticket into exactly
    one category: billing, technical, account, or general.
    Respond with only the category name.
    
    User:
    I can't access my dashboard after changing my password yesterday.
    
    Model output:
    account

    Test multiple inputs, tweak the system prompt, and adjust temperature until you’re confident in the model’s behavior — all without API costs.

    Fine-tuning with QLoRA

    When a pre-trained model almost works but needs domain-specific knowledge, fine-tuning closes the gap. The AI Toolkit supports QLoRA (Quantized Low-Rank Adaptation), which lets you fine-tune large models on consumer GPUs by training only a small set of adapter weights.

    Preparing your dataset

    Create a JSONL file with your training examples:

    {"messages": [{"role": "system", "content": "You are a medical coding assistant."}, {"role": "user", "content": "Patient presents with acute bronchitis"}, {"role": "assistant", "content": "ICD-10: J20.9 - Acute bronchitis, unspecified"}]}
    {"messages": [{"role": "system", "content": "You are a medical coding assistant."}, {"role": "user", "content": "Follow-up for type 2 diabetes with neuropathy"}, {"role": "assistant", "content": "ICD-10: E11.40 - Type 2 diabetes with diabetic neuropathy, unspecified"}]}

    Configuring fine-tuning

    1. In the AI Toolkit panel, click Fine-tune.
    2. Select your base model (e.g., Phi-3-mini).
    3. Upload your JSONL dataset.
    4. Configure training parameters:
      • Epochs: 3-5 for most tasks.
      • Learning rate: 2e-4 is a good starting point for QLoRA.
      • LoRA rank: 16-64 (higher = more capacity, more VRAM).
      • Batch size: depends on your GPU memory.
    5. Click Start training. The toolkit shows real-time loss curves and progress.

    Remote fine-tuning with Azure ML

    If your local hardware isn’t sufficient, the toolkit can offload fine-tuning to Azure ML compute:

    # The toolkit generates this configuration automatically
    # You just need to connect your Azure subscription
    Compute: Standard_NC24ads_A100_v4
    GPU: NVIDIA A100 (80 GB)
    Estimated time: ~45 minutes for 1000 examples

    The workflow is the same — select the model, upload data, configure parameters — but training runs on cloud GPUs. Results are downloaded back to your workspace when complete.

    Evaluation

    After fine-tuning, you need to measure quality before deployment. The AI Toolkit provides built-in evaluation metrics:

    MetricWhat it measuresGood for
    CoherenceLogical flow and readability of responsesConversational models, content generation
    RelevanceHow well the response addresses the inputQ&A, classification, extraction
    GroundednessWhether the response stays factualRAG applications, knowledge bases
    FluencyGrammar and natural language qualityCustomer-facing outputs
    SimilarityHow close the output matches expected resultsStructured output, code generation

    Create an evaluation dataset with expected outputs and run it against both the base model and your fine-tuned version. The toolkit shows a side-by-side comparison so you can confirm the fine-tuning improved quality without introducing regressions.

    Deploying to Azure

    When your model is ready for production:

    1. Right-click your fine-tuned model in the toolkit and select Deploy to Azure.
    2. Choose your Azure subscription and resource group.
    3. Select the compute tier (GPU instances for inference).
    4. The toolkit packages your model, creates an Azure AI endpoint, and deploys it.
    5. You get a REST API endpoint that you can call from your application.
    import requests
    
    endpoint = "https://your-model.eastus.inference.ml.azure.com/score"
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
    }
    
    response = requests.post(endpoint, headers=headers, json={
        "messages": [
            {"role": "user", "content": "Classify this ticket: I need a refund"}
        ]
    })
    
    print(response.json())

    AI Toolkit vs. Azure AI Foundry

    AspectAI Toolkit (VS Code)Azure AI Foundry (Web)
    EnvironmentLocal-first, runs in VS CodeCloud-first, web-based studio
    Best forIndividual developers, prototyping, experimentationTeams, production pipelines, governance
    Fine-tuningLocal QLoRA + remote Azure MLManaged fine-tuning service
    CostFree (local compute) or Azure ML pricingAzure pricing for all operations
    IntegrationSource control, terminal, debuggerAzure ecosystem, Prompt Flow

    Use the AI Toolkit for fast experimentation on your machine, then move to Azure AI Foundry when you need team collaboration, managed infrastructure, and production-grade monitoring.

    Next steps

    1. Install the extension — search “AI Toolkit” in the VS Code marketplace.
    2. Download Phi-3-mini — run it locally in the playground with zero setup.
    3. Fine-tune a small model — prepare 50-100 examples in JSONL format and run a QLoRA training session.
    4. Read the docs: learn.microsoft.com/windows/ai/toolkit
    What model would you fine-tune? The AI Toolkit makes it possible to customize AI models right from your editor. Share your use case in the comments — I’ll help you pick the right base model and training approach.
  • AutoGen multi-agent

    Intermediate

    A single AI agent has limits — it can only do so much on its own. But what happens when you put multiple specialized agents together, each with a distinct role, and let them collaborate on complex tasks? That’s the core idea behind AutoGen, Microsoft’s open-source framework for building multi-agent AI systems.

    This guide walks through AutoGen’s architecture, shows you how to build agent teams that collaborate autonomously, and covers real-world patterns for code generation, analysis, and human-in-the-loop workflows.


    Why multi-agent?

    A single LLM call is stateless and limited by its context window. Multi-agent systems break complex problems into specialized roles:

    • Specialization — each agent has a focused system prompt and tools, making it better at its specific job.
    • Verification — one agent generates, another reviews. Errors that slip past a single agent get caught by a critic.
    • Decomposition — complex tasks split into subtasks that agents handle in parallel or sequence.
    • Human-in-the-loop — agents can pause, ask for approval, and incorporate human feedback before proceeding.

    AutoGen (now in version 0.4, rewritten as AutoGen AgentChat) provides the primitives to build these systems: agents, teams, and conversation patterns.

    Architecture overview

    AUTOGEN MULTI-AGENT ARCHITECTURE Task / User Input AGENT TEAM Coder Agent Writes code based on task requirements Reviewer Agent Reviews code for bugs, style, and correctness Executor Agent Runs code and reports results or errors Feedback loop Termination Condition

    AutoGen agents communicate through messages. A team defines how agents take turns (round-robin, selector-based, or custom). A termination condition decides when the conversation is done — after a keyword, a maximum number of turns, or when an agent signals completion.

    Setting up AutoGen

    pip install autogen-agentchat autogen-ext[openai,azure]

    AutoGen 0.4 is a complete rewrite. If you’ve used the older pyautogen package, the API has changed significantly — the new version is more modular and production-ready.

    Configure the model client

    from autogen_ext.models.openai import AzureOpenAIChatCompletionClient
    from azure.identity import DefaultAzureCredential
    
    model_client = AzureOpenAIChatCompletionClient(
        azure_deployment="gpt-4o",
        azure_endpoint="https://your-resource.openai.azure.com/",
        credential=DefaultAzureCredential(),
        model="gpt-4o",
        api_version="2025-01-01-preview",
    )

    Your first multi-agent team

    Let’s build a code-generation team with three agents: a coder, a reviewer, and an executor.

    from autogen_agentchat.agents import AssistantAgent, CodeExecutorAgent
    from autogen_agentchat.teams import RoundRobinGroupChat
    from autogen_agentchat.conditions import TextMentionTermination
    from autogen_ext.code_executors.local import LocalCommandLineCodeExecutor
    
    coder = AssistantAgent(
        name="coder",
        model_client=model_client,
        system_message="""You are an expert Python developer.
        Write clean, well-documented code to solve the task.
        Always include error handling and type hints.
        When the code is approved and tested, respond with TERMINATE.""",
    )
    
    reviewer = AssistantAgent(
        name="reviewer",
        model_client=model_client,
        system_message="""You are a senior code reviewer.
        Review the code for:
        - Correctness and edge cases
        - Security vulnerabilities
        - Performance concerns
        - Code style and readability
        Provide specific, actionable feedback.
        If the code is production-ready, say APPROVED.""",
    )
    
    executor = CodeExecutorAgent(
        name="executor",
        code_executor=LocalCommandLineCodeExecutor(work_dir="./workspace"),
    )

    Assemble the team

    termination = TextMentionTermination("TERMINATE")
    
    team = RoundRobinGroupChat(
        participants=[coder, reviewer, executor],
        termination_condition=termination,
        max_turns=12,
    )
    
    # Run the team on a task
    result = await team.run(
        task="Write a Python function that validates email addresses using regex. Include unit tests."
    )
    
    for message in result.messages:
        print(f"[{message.source}]: {message.content[:200]}")

    The flow: the coder writes the code, the reviewer checks it, the executor runs it. If the reviewer finds issues, the loop continues. When the coder says “TERMINATE,” the conversation ends.

    Selector-based teams

    Round-robin is predictable but rigid. For more dynamic conversations, use SelectorGroupChat — a model decides which agent should speak next based on the conversation context:

    from autogen_agentchat.teams import SelectorGroupChat
    
    planner = AssistantAgent(
        name="planner",
        model_client=model_client,
        system_message="""You are a project planner.
        Break tasks into clear steps and delegate to the right agent.
        Coordinate the team's work and track progress.""",
    )
    
    researcher = AssistantAgent(
        name="researcher",
        model_client=model_client,
        system_message="""You are a research specialist.
        Gather information, find best practices, and provide context
        for the team's decisions.""",
    )
    
    team = SelectorGroupChat(
        participants=[planner, coder, reviewer, researcher],
        model_client=model_client,  # used to select the next speaker
        termination_condition=termination,
    )

    The selector model analyzes each message and picks the most appropriate next agent. The planner might start by breaking down the task, then the researcher gathers requirements, the coder implements, and the reviewer verifies — all orchestrated dynamically.

    Tools and function calling

    Agents become much more powerful when they can call external tools. Define tools as Python functions:

    from autogen_agentchat.agents import AssistantAgent
    
    async def search_database(query: str, limit: int = 10) -> str:
        """Search the product database for matching items."""
        # In production, query your actual database
        results = await db.search(query, limit=limit)
        return json.dumps(results)
    
    async def send_notification(recipient: str, message: str) -> str:
        """Send a notification to a user via email."""
        await email_service.send(recipient, message)
        return f"Notification sent to {recipient}"
    
    support_agent = AssistantAgent(
        name="support",
        model_client=model_client,
        tools=[search_database, send_notification],
        system_message="""You are a customer support agent.
        Use the available tools to look up product information
        and send notifications when needed.""",
    )

    Human-in-the-loop

    For sensitive operations, you’ll want human approval before agents take action. AutoGen supports this through the UserProxyAgent or by adding a handoff mechanism:

    from autogen_agentchat.agents import UserProxyAgent
    
    human = UserProxyAgent(
        name="human",
        description="A human user who provides approvals and feedback.",
    )
    
    team = RoundRobinGroupChat(
        participants=[planner, coder, human],
        termination_condition=termination,
    )
    
    # When running in a console, the human agent prompts for input
    # In a web app, you'd connect it to your UI
    result = await team.run(
        task="Refactor the authentication module to use OAuth 2.0"
    )
    Safety first: When agents can execute code or call APIs, always run them in sandboxed environments. Use DockerCommandLineCodeExecutor instead of LocalCommandLineCodeExecutor in production to isolate code execution.

    Conversation patterns

    PatternImplementationBest for
    Round-robinRoundRobinGroupChatPredictable pipelines (write → review → test)
    Dynamic selectionSelectorGroupChatComplex tasks where the next speaker depends on context
    Two-agent chatDirect agent.run()Simple back-and-forth between two agents
    Nested teamsTeams as participants in other teamsHierarchical workflows with sub-teams
    SwarmSwarm with handoffsCustomer service routing, escalation flows

    Real-world scenario: data analysis pipeline

    Here’s a practical example — a team that analyzes a CSV dataset and produces a report:

    analyst = AssistantAgent(
        name="analyst",
        model_client=model_client,
        system_message="""You are a data analyst.
        When given a dataset, write Python code using pandas
        to explore the data: shape, dtypes, missing values,
        key statistics, and notable patterns.""",
    )
    
    visualizer = AssistantAgent(
        name="visualizer",
        model_client=model_client,
        system_message="""You are a data visualization expert.
        Take the analyst's findings and create matplotlib charts
        that tell a clear story. Save charts as PNG files.
        Use a clean, professional style.""",
    )
    
    writer = AssistantAgent(
        name="writer",
        model_client=model_client,
        system_message="""You are a technical writer.
        Synthesize the analysis and visualizations into a
        concise executive summary. Include key findings,
        recommendations, and the charts.
        End with TERMINATE when the report is complete.""",
    )
    
    executor = CodeExecutorAgent(
        name="executor",
        code_executor=LocalCommandLineCodeExecutor(work_dir="./analysis"),
    )
    
    pipeline = RoundRobinGroupChat(
        participants=[analyst, executor, visualizer, executor, writer],
        termination_condition=TextMentionTermination("TERMINATE"),
        max_turns=20,
    )
    
    result = await pipeline.run(
        task="Analyze the sales data in ./data/sales_2024.csv. Find trends, seasonality, and anomalies."
    )

    AutoGen vs. other frameworks

    FeatureAutoGenCrewAILangGraph
    Multi-agent patternsRound-robin, selector, swarm, nestedSequential, hierarchicalState machine graphs
    Code executionBuilt-in (local + Docker)Via toolsVia tools
    Human-in-the-loopNative UserProxyAgentHuman input toolInterrupt nodes
    LanguagePython, .NET (preview)PythonPython, JavaScript
    Model supportOpenAI, Azure, Ollama, etc.OpenAI, Azure, OllamaVia LangChain
    Best forResearch, complex collaborationRole-based agent teamsDeterministic workflows

    AutoGen excels at open-ended collaboration where agents need to iterate and refine. LangGraph is stronger for workflows where you need precise control over every state transition. CrewAI offers a simpler API for straightforward role-based teams.

    Production considerations

    1. Sandbox code execution — always use Docker-based executors in production. Never let agents run arbitrary code on your host machine.
    2. Set turn limits — agents can get stuck in loops. Always configure max_turns and combine with timeout-based termination.
    3. Monitor token usage — multi-agent conversations consume tokens fast. Each agent turn is a full API call. Track costs per conversation.
    4. Log everything — save the full conversation transcript for debugging. AutoGen supports structured logging out of the box.
    5. Start simple — begin with two agents (generator + reviewer) and add complexity only when needed. More agents means more coordination overhead.
    6. Test termination conditions — the most common production issue is agents that never terminate. Test edge cases where the task can’t be completed.

    The .NET preview

    AutoGen also has a .NET version (Microsoft.AutoGen) in preview. It follows the same multi-agent concepts but integrates with the .NET ecosystem:

    using Microsoft.AutoGen.AgentChat;
    using Microsoft.AutoGen.Contracts;
    
    var coder = new AssistantAgent(
        name: "coder",
        modelClient: azureClient,
        systemMessage: "You are an expert C# developer...");
    
    var reviewer = new AssistantAgent(
        name: "reviewer",
        modelClient: azureClient,
        systemMessage: "You are a senior code reviewer...");
    
    var team = new RoundRobinGroupChat(
        [coder, reviewer],
        terminationCondition: new MaxMessageTermination(10));
    
    var result = await team.RunAsync("Build a REST API for a todo app");

    Next steps

    1. Clone the repo: github.com/microsoft/autogen — check the /python/samples folder for patterns.
    2. Start with two agents — a coder and a reviewer working on a real task in your codebase.
    3. Add code execution — let the executor run the generated code and feed errors back for automatic debugging.
    4. Explore the docs: microsoft.github.io/autogen
    What would your agent team look like? Multi-agent systems shine when tasks need multiple perspectives. Share what you’d build in the comments — research pipelines, code review teams, data analysis squads — and I’ll help you design the architecture.
  • Microsoft.Extensions.AI

    Intermediate

    Every AI library has its own way to call a model: OpenAI’s SDK, Azure’s SDK, Ollama’s client — each with different interfaces, different types, different patterns. Microsoft.Extensions.AI solves this by providing a unified abstraction layer that works with any AI provider, the same way ILogger unified logging in .NET.

    This guide covers the core abstractions, shows practical code with Azure OpenAI, and demonstrates how the middleware pipeline lets you add caching, logging, and rate limiting without changing your application code.


    The problem it solves

    Consider a .NET application that uses Azure OpenAI today. Your code is tightly coupled to the Azure SDK — if you want to add local Ollama support for development or switch to another provider, you’re rewriting every call site. Unit testing means mocking provider-specific types.

    Microsoft.Extensions.AI introduces provider-agnostic interfaces that any AI library can implement. Your application codes against the interface; the provider is a configuration decision.

    MICROSOFT.EXTENSIONS.AI ARCHITECTURE Your Application Code IChatClient · IEmbeddingGenerator · IChatClient Pipeline Microsoft.Extensions.AI Abstractions Logging · Caching · Rate Limiting · Telemetry Azure OpenAI OpenAI Ollama Any Provider

    Core interfaces

    The library defines two primary interfaces:

    InterfacePurposeKey methods
    IChatClientChat completions (text, tool calls, streaming)CompleteAsync, CompleteStreamingAsync
    IEmbeddingGenerator<TInput, TEmbedding>Generate embeddings for text or other inputsGenerateAsync

    Both interfaces ship in the Microsoft.Extensions.AI.Abstractions package — a lightweight, dependency-free package that library authors reference. Application developers reference the provider-specific packages which include the implementations.

    Getting started

    dotnet new console -n AISdkDemo
    cd AISdkDemo
    dotnet add package Microsoft.Extensions.AI.OpenAI
    dotnet add package Azure.AI.OpenAI

    Basic chat completion

    using Azure.AI.OpenAI;
    using Microsoft.Extensions.AI;
    
    var azureClient = new AzureOpenAIClient(
        new Uri("https://your-resource.openai.azure.com/"),
        new DefaultAzureCredential());
    
    IChatClient client = azureClient
        .GetChatClient("gpt-4o")
        .AsIChatClient();
    
    var response = await client.CompleteAsync("Explain dependency injection in 3 sentences.");
    Console.WriteLine(response.Message.Text);

    The key line is .AsIChatClient() — this extension method wraps the Azure-specific client into the generic IChatClient interface. From here on, your code only knows about IChatClient.

    Streaming responses

    await foreach (var update in client.CompleteStreamingAsync("Write a haiku about Azure."))
    {
        Console.Write(update.Text);
    }

    Structured conversations

    For multi-turn conversations, build a list of ChatMessage objects:

    var messages = new List<ChatMessage>
    {
        new(ChatRole.System, """
            You are a .NET architecture advisor.
            Give concise, opinionated recommendations.
            Cite specific NuGet packages when relevant.
            """),
        new(ChatRole.User, "Should I use MediatR or just call services directly?")
    };
    
    var response = await client.CompleteAsync(messages);
    Console.WriteLine(response.Message.Text);
    
    // Continue the conversation
    messages.Add(response.Message);
    messages.Add(new(ChatRole.User, "What about in a modular monolith?"));
    
    var followUp = await client.CompleteAsync(messages);

    Tool calling (function calling)

    The AI SDK supports tool calling through the AIFunction abstraction. Define tools as regular methods and let the SDK handle serialization:

    using System.ComponentModel;
    using Microsoft.Extensions.AI;
    
    public static class WeatherTools
    {
        [Description("Gets the current weather for a city")]
        public static string GetWeather(
            [Description("City name, e.g. Seattle")] string city)
        {
            // In production, call a real weather API
            return $"Weather in {city}: 72°F, partly cloudy";
        }
    
        [Description("Gets the 5-day forecast for a city")]
        public static string GetForecast(
            [Description("City name")] string city,
            [Description("Number of days (1-5)")] int days = 5)
        {
            return $"{days}-day forecast for {city}: sunny, then rain Thursday";
        }
    }

    Wire the tools into the chat options:

    var tools = new[]
    {
        AIFunctionFactory.Create(WeatherTools.GetWeather),
        AIFunctionFactory.Create(WeatherTools.GetForecast)
    };
    
    var options = new ChatOptions
    {
        Tools = tools,
        ToolMode = ChatToolMode.Auto
    };
    
    var response = await client.CompleteAsync(
        "What's the weather like in Seattle and will it rain this week?",
        options);
    
    Console.WriteLine(response.Message.Text);
    // The model calls both GetWeather and GetForecast, then composes a natural answer
    Important: The ChatToolMode.Auto setting lets the model decide which tools to call. Use ChatToolMode.RequireAny to force at least one tool call, which is useful when you know the user’s request needs external data.

    The middleware pipeline

    One of the most powerful features is the ability to compose middleware around any IChatClient — just like ASP.NET middleware for HTTP requests:

    MIDDLEWARE PIPELINE Your Code CompleteAsync() Logging OpenTelemetry Caching IDistributedCache Function Calling Loop Azure OpenAI Inner Client
    using Microsoft.Extensions.AI;
    using Microsoft.Extensions.Caching.Distributed;
    
    IChatClient client = new ChatClientBuilder(azureClient.GetChatClient("gpt-4o").AsIChatClient())
        .UseOpenTelemetry()
        .UseDistributedCache(cache)
        .UseFunctionInvocation()
        .Build();

    Each Use* call wraps the client in a delegating handler. The order matters — requests flow left to right, responses right to left. In this example:

    • OpenTelemetry records traces and metrics for every call.
    • DistributedCache returns cached responses for identical prompts (great for deterministic queries).
    • FunctionInvocation handles the tool-call loop, executing your AIFunction tools when the model requests them.

    Dependency injection

    The SDK integrates naturally with .NET’s DI container — essential for ASP.NET Core and background services:

    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddDistributedMemoryCache();
    
    builder.Services.AddChatClient(services =>
    {
        var azureClient = new AzureOpenAIClient(
            new Uri(builder.Configuration["AzureOpenAI:Endpoint"]!),
            new DefaultAzureCredential());
    
        return new ChatClientBuilder(azureClient.GetChatClient("gpt-4o").AsIChatClient())
            .UseOpenTelemetry()
            .UseDistributedCache()
            .UseFunctionInvocation()
            .Build();
    });
    
    var app = builder.Build();
    
    // Now inject IChatClient anywhere
    app.MapPost("/chat", async (IChatClient chat, ChatRequest req) =>
    {
        var response = await chat.CompleteAsync(req.Message);
        return Results.Ok(new { response.Message.Text });
    });

    Embeddings

    The embedding interface follows the same pattern:

    IEmbeddingGenerator<string, Embedding<float>> embedder = azureClient
        .GetEmbeddingClient("text-embedding-3-small")
        .AsIEmbeddingGenerator();
    
    var embeddings = await embedder.GenerateAsync(new[]
    {
        "Azure OpenAI provides enterprise-grade AI models",
        "Kubernetes orchestrates containerized workloads",
        "Semantic Kernel connects LLMs to your business logic"
    });
    
    foreach (var e in embeddings)
    {
        Console.WriteLine($"Dimension: {e.Vector.Length}");  // 1536
    }

    Swapping providers

    The real power of the abstraction: switch from Azure to a local Ollama instance for development by changing one line:

    // Production: Azure OpenAI
    IChatClient client = azureClient.GetChatClient("gpt-4o").AsIChatClient();
    
    // Development: Ollama running locally
    IChatClient client = new OllamaChatClient("http://localhost:11434", "llama3.1");

    Every downstream consumer that injects IChatClient works identically. Your middleware pipeline (logging, caching) applies to both. No code changes needed.

    Microsoft.Extensions.AI vs. Semantic Kernel

    AspectMicrosoft.Extensions.AISemantic Kernel
    LevelLow-level abstraction (interfaces + middleware)High-level orchestration framework
    PurposeUnified provider interface for any .NET appAI agent orchestration with plugins, planners, memory
    RelationshipSemantic Kernel uses Microsoft.Extensions.AI interfaces internally
    When to useDirect AI calls in services, APIs, background jobsComplex agents, multi-step reasoning, plugin orchestration
    MiddlewarePipeline builder (logging, caching, function calling)Filters (prompt, function, auto-function)
    OverheadMinimal — thin abstraction layerMore setup — kernel, plugins, settings

    They’re complementary, not competing. Use Microsoft.Extensions.AI when you need straightforward AI calls with clean architecture. Use Semantic Kernel when you need an agent that orchestrates multiple tools and reasons across steps. Semantic Kernel is built on top of these same abstractions.

    Building a custom middleware

    You can write your own middleware by implementing DelegatingChatClient:

    public class RateLimitingChatClient : DelegatingChatClient
    {
        private readonly SemaphoreSlim _semaphore;
    
        public RateLimitingChatClient(IChatClient inner, int maxConcurrency)
            : base(inner)
        {
            _semaphore = new SemaphoreSlim(maxConcurrency);
        }
    
        public override async Task<ChatCompletion> CompleteAsync(
            IList<ChatMessage> messages,
            ChatOptions? options = null,
            CancellationToken ct = default)
        {
            await _semaphore.WaitAsync(ct);
            try
            {
                return await base.CompleteAsync(messages, options, ct);
            }
            finally
            {
                _semaphore.Release();
            }
        }
    }
    
    // Use it in the pipeline
    IChatClient client = new ChatClientBuilder(innerClient)
        .Use(inner => new RateLimitingChatClient(inner, maxConcurrency: 5))
        .UseOpenTelemetry()
        .Build();

    Production patterns

    1. Always use DI — register IChatClient as a singleton and inject it. Don’t create clients per-request.
    2. Configure via appsettings — put endpoints and model names in configuration so you can swap providers without redeploying.
    3. Add OpenTelemetry early — the telemetry middleware captures token usage, latency, and errors. Essential for cost tracking.
    4. Cache deterministic calls — if you’re classifying text or extracting structured data, caching saves both latency and money.
    5. Handle streaming for UX — use CompleteStreamingAsync in user-facing applications so responses appear incrementally.
    6. Set reasonable timeouts — AI calls can take 10-30 seconds. Configure HttpClient timeouts and cancellation tokens.

    Next steps

    1. Explore the official samples: github.com/dotnet/ai-samples
    2. Add AI to an existing API — inject IChatClient into an ASP.NET Core controller and add a summarization or classification endpoint.
    3. Build a RAG pipeline — combine IEmbeddingGenerator with a vector database to ground answers in your data.
    4. Read the docs: learn.microsoft.com/dotnet/ai
    Ready to unify your AI calls? The Microsoft.Extensions.AI abstractions turn AI integration into a first-class .NET citizen. Drop a comment with what you’re building — let’s figure out the right architecture together.
  • Semantic Kernel

    Intermediate

    You’ve used Azure OpenAI to send prompts and get completions. But how do you build a real AI application — one that remembers context, calls your business logic, and orchestrates multi-step workflows? Semantic Kernel is Microsoft’s answer: an open-source SDK that turns LLMs into the reasoning engine of your application.

    This guide goes beyond the basics. We’ll explore the architecture, build plugins, wire up planners, and integrate memory — all with production-ready C# code.


    Why Semantic Kernel?

    Calling an LLM directly works for simple scenarios, but production AI applications need more: structured function calling, conversation memory, multi-step reasoning, and integration with your existing codebase. Semantic Kernel provides these capabilities through a modular architecture that plugs into .NET’s dependency injection system.

    Key advantages over raw API calls:

    • Plugin system — expose your C# methods as tools the AI can call automatically.
    • Automatic function calling — the kernel handles the tool-call loop, including retries and argument marshaling.
    • Memory & embeddings — built-in support for vector stores and semantic search.
    • Filters & middleware — intercept and modify prompts, function calls, and responses.
    • Multi-model support — Azure OpenAI, OpenAI, Hugging Face, Ollama, and more through connectors.

    Architecture overview

    SEMANTIC KERNEL ARCHITECTURE Your Application Kernel Plugins Native Functions Prompt Templates OpenAPI Specs AI Services Chat Completion Text Embedding Image Generation Memory Vector Store Semantic Search Chat History Filters & Middleware Pipeline

    The Kernel is the central orchestrator. It connects your application to AI services, manages plugins (your code exposed to the AI), and coordinates the execution loop. Filters let you intercept every step for logging, validation, or modification.

    Setting up your project

    Start with a .NET 8 console application:

    dotnet new console -n SemanticKernelDemo
    cd SemanticKernelDemo
    dotnet add package Microsoft.SemanticKernel
    dotnet add package Microsoft.SemanticKernel.Plugins.Core

    Configure the kernel with Azure OpenAI:

    using Microsoft.SemanticKernel;
    
    var builder = Kernel.CreateBuilder();
    
    builder.AddAzureOpenAIChatCompletion(
        deploymentName: "gpt-4o",
        endpoint: "https://your-resource.openai.azure.com/",
        apiKey: "your-api-key"
    );
    
    var kernel = builder.Build();
    Tip: In production, use DefaultAzureCredential instead of API keys. Semantic Kernel supports token credentials natively through the AddAzureOpenAIChatCompletion overload that accepts a TokenCredential.

    Building plugins

    Plugins are the core mechanism for giving the AI access to your business logic. A plugin is simply a class with methods decorated with [KernelFunction].

    Native plugin example

    using System.ComponentModel;
    using Microsoft.SemanticKernel;
    
    public class OrderPlugin
    {
        private readonly IOrderService _orderService;
    
        public OrderPlugin(IOrderService orderService)
        {
            _orderService = orderService;
        }
    
        [KernelFunction]
        [Description("Gets the current status of an order by its ID")]
        public async Task<string> GetOrderStatus(
            [Description("The order ID, e.g. ORD-12345")] string orderId)
        {
            var order = await _orderService.GetByIdAsync(orderId);
            return order is null
                ? $"Order {orderId} not found."
                : $"Order {orderId}: {order.Status}, shipped {order.ShipDate:d}";
        }
    
        [KernelFunction]
        [Description("Lists the most recent orders for a customer")]
        public async Task<string> GetRecentOrders(
            [Description("Customer email address")] string email,
            [Description("Max results to return")] int count = 5)
        {
            var orders = await _orderService.GetRecentAsync(email, count);
            return JsonSerializer.Serialize(orders);
        }
    }

    Register the plugin with the kernel:

    kernel.Plugins.AddFromObject(new OrderPlugin(orderService), "Orders");

    The [Description] attributes are critical — the AI reads them to decide when and how to call each function. Write them as clear, concise instructions.

    Prompt plugin (semantic function)

    You can also define plugins as prompt templates:

    var summarize = kernel.CreateFunctionFromPrompt(
        """
        Summarize the following text in {{$style}} style.
        Keep it under {{$maxWords}} words.
    
        Text: {{$input}}
        """,
        new OpenAIPromptExecutionSettings
        {
            MaxTokens = 300,
            Temperature = 0.3
        }
    );
    
    var result = await kernel.InvokeAsync(summarize, new()
    {
        ["input"] = longArticle,
        ["style"] = "executive briefing",
        ["maxWords"] = "100"
    });

    Automatic function calling

    This is where Semantic Kernel shines. When you enable automatic function calling, the kernel handles the entire tool-call loop: the AI decides which functions to call, the kernel executes them, feeds the results back, and lets the AI formulate the final answer.

    using Microsoft.SemanticKernel.Connectors.OpenAI;
    
    var settings = new OpenAIPromptExecutionSettings
    {
        FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
    };
    
    var chatService = kernel.GetRequiredService<IChatCompletionService>();
    var history = new ChatHistory();
    history.AddSystemMessage("You are a helpful order support assistant.");
    history.AddUserMessage("What's the status of order ORD-78901?");
    
    var response = await chatService.GetChatMessageContentAsync(
        history, settings, kernel);
    
    Console.WriteLine(response.Content);
    // "Order ORD-78901 is currently shipped and was dispatched on June 28."

    Behind the scenes, the AI called GetOrderStatus("ORD-78901"), received the result, and composed a natural language response. You didn’t write any routing logic — the kernel handled it.

    Filters: intercepting the pipeline

    Filters let you hook into every prompt and function call for logging, validation, caching, or modification. This is essential for production applications.

    public class AuditFilter : IFunctionInvocationFilter
    {
        private readonly ILogger<AuditFilter> _logger;
    
        public AuditFilter(ILogger<AuditFilter> logger) => _logger = logger;
    
        public async Task OnFunctionInvocationAsync(
            FunctionInvocationContext context, Func<FunctionInvocationContext, Task> next)
        {
            _logger.LogInformation(
                "Calling {Plugin}.{Function} with {Args}",
                context.Function.PluginName,
                context.Function.Name,
                context.Arguments);
    
            await next(context);
    
            _logger.LogInformation(
                "Result from {Function}: {Result}",
                context.Function.Name,
                context.Result?.ToString()?[..200]);
        }
    }
    
    // Register the filter
    builder.Services.AddSingleton<IFunctionInvocationFilter, AuditFilter>();

    There are three filter types: IPromptRenderFilter (before/after prompt rendering), IFunctionInvocationFilter (before/after function execution), and IAutoFunctionInvocationFilter (specifically for the auto function calling loop).

    Memory and vector search

    Semantic Kernel integrates with vector databases to give your AI long-term memory and the ability to search through documents semantically.

    Documents PDFs, emails, knowledge base Chunk & Embed Vector Store Azure AI Search Qdrant, Pinecone Semantic Search Kernel + Context Grounded Answer
    using Microsoft.SemanticKernel.Memory;
    using Microsoft.SemanticKernel.Connectors.AzureAISearch;
    
    // Configure memory with Azure AI Search as the vector store
    var memoryBuilder = new MemoryBuilder()
        .WithAzureOpenAITextEmbeddingGeneration(
            "text-embedding-3-small", endpoint, apiKey)
        .WithMemoryStore(new AzureAISearchMemoryStore(
            searchEndpoint, searchApiKey));
    
    var memory = memoryBuilder.Build();
    
    // Save documents to memory
    await memory.SaveInformationAsync(
        collection: "company-policies",
        id: "remote-work-policy",
        text: "Employees may work remotely up to 3 days per week...");
    
    // Search memory semantically
    var results = memory.SearchAsync(
        collection: "company-policies",
        query: "Can I work from home on Fridays?",
        limit: 3,
        minRelevanceScore: 0.75);
    
    await foreach (var result in results)
    {
        Console.WriteLine($"[{result.Relevance:P0}] {result.Metadata.Text}");
    }

    Putting it together: a support agent

    Here’s a complete example that combines plugins, automatic function calling, and chat history into a functional support agent:

    var builder = Kernel.CreateBuilder();
    builder.AddAzureOpenAIChatCompletion("gpt-4o", endpoint, apiKey);
    builder.Services.AddSingleton<IOrderService, OrderService>();
    builder.Services.AddSingleton<IFunctionInvocationFilter, AuditFilter>();
    var kernel = builder.Build();
    
    kernel.Plugins.AddFromType<OrderPlugin>("Orders");
    
    var chat = kernel.GetRequiredService<IChatCompletionService>();
    var history = new ChatHistory("""
        You are a customer support agent for Contoso Electronics.
        Use the available tools to look up order information.
        Be concise and helpful. If you can't find information,
        say so — don't make anything up.
        """);
    
    var settings = new OpenAIPromptExecutionSettings
    {
        FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
    };
    
    // Chat loop
    while (true)
    {
        Console.Write("You: ");
        var input = Console.ReadLine();
        if (string.IsNullOrEmpty(input)) break;
    
        history.AddUserMessage(input);
        var response = await chat.GetChatMessageContentAsync(
            history, settings, kernel);
        history.Add(response);
        Console.WriteLine($"Agent: {response.Content}");
    }

    Semantic Kernel vs. LangChain

    AspectSemantic KernelLangChain
    Primary languageC# (.NET), PythonPython, JavaScript
    Plugin modelNative class methods with attributesTools as functions or classes
    Enterprise integrationAzure-first, DI-nativeCloud-agnostic
    Function callingAutomatic loop with filtersAgent executors
    MemoryBuilt-in vector store abstractionMemory modules + retrievers
    Best for.NET shops, Azure stack, enterprisePython-first teams, rapid prototyping

    If your team works in .NET and Azure, Semantic Kernel is the natural choice — it integrates with your existing DI, logging, and deployment patterns. LangChain offers broader community tools but less polish in the .NET ecosystem.

    Production checklist

    1. Use managed identity — replace API keys with DefaultAzureCredential for all Azure services.
    2. Add filters — log every function call and prompt for debugging and compliance.
    3. Set token limits — configure MaxTokens and FunctionChoiceBehavior.Auto(maxRounds: 5) to prevent runaway loops.
    4. Handle errors in plugins — return user-friendly error messages instead of throwing exceptions.
    5. Version your prompts — store prompt templates in configuration, not hardcoded strings.
    6. Test with mocks — Semantic Kernel’s interfaces are mockable for unit testing without hitting real AI services.

    Next steps

    1. Clone the samples repo: github.com/microsoft/semantic-kernel — the /dotnet/samples folder has production-grade examples.
    2. Try the Agents framework — Semantic Kernel includes an experimental Agent abstraction for multi-agent scenarios.
    3. Explore the Process framework — for complex, multi-step business workflows with state management.
    4. Read the official docs: learn.microsoft.com/semantic-kernel
    What plugin would you build first? Semantic Kernel turns your existing C# code into AI-callable tools. Share your use case in the comments — I’ll help you design the plugin architecture.
  • Copilot Studio

    What if you could build an AI-powered assistant for your company — one that answers questions, automates tasks, and connects to your internal systems — without writing a single line of code? That’s exactly what Microsoft Copilot Studio delivers, and it’s more accessible than you might think.

    This guide walks you through what Copilot Studio can do, how to build your first copilot, and where it fits in the broader Microsoft AI ecosystem.


    What is Copilot Studio?

    Copilot Studio (formerly Power Virtual Agents) is Microsoft’s low-code platform for creating custom AI assistants — called copilots. These copilots can:

    • Answer questions using your own data (SharePoint, websites, uploaded files).
    • Follow conversation flows with branching logic, conditions, and variables.
    • Take actions by calling Power Automate flows, APIs, or connectors.
    • Operate across channels: Microsoft Teams, websites, Facebook, Slack, and more.

    The key difference from a simple chatbot: Copilot Studio combines generative AI (GPT-powered answers grounded in your data) with deterministic topics (structured conversation paths you control). You get the flexibility of AI with the reliability of predefined logic.

    Generative answers vs. authored topics

    Copilot Studio gives you two ways to handle user questions:

    ApproachHow it worksBest for
    Generative answersThe copilot searches your data sources and generates a natural language response using AIFAQs, knowledge bases, documentation, general inquiries
    Authored topicsYou design a specific conversation flow with triggers, questions, conditions, and actionsProcesses that require specific steps, data collection, system integrations

    In practice, most copilots use both. Generative answers handle the broad “long tail” of questions, while authored topics manage critical processes where you need full control over the experience.

    What can you build?

    IT help desk assistant

    A copilot that answers common IT questions (“How do I reset my password?”, “How do I connect to the VPN?”) using your internal documentation, and escalates to a human agent when needed.

    HR onboarding companion

    New employees ask about benefits, policies, and procedures. The copilot pulls answers from SharePoint and guides them through onboarding tasks step by step.

    Customer support agent

    Deploy a copilot on your website that handles product questions, checks order status (via API calls), and creates support tickets when it can’t resolve an issue.

    Internal operations bot

    A Teams-based copilot that lets employees submit vacation requests, check remaining PTO, or look up project status — all through natural conversation.

    Building your first copilot

    Step 1: Access Copilot Studio

    1. Go to copilotstudio.microsoft.com.
    2. Sign in with your Microsoft 365 or Power Platform account.
    3. Click Create in the left menu and select New copilot.

    Step 2: Describe your copilot

    Copilot Studio lets you set up your assistant by simply describing what it should do. Provide:

    • A name (e.g., “Contoso IT Helper”).
    • A description of its purpose and behavior.
    • Instructions that guide tone and boundaries (e.g., “Answer only IT-related questions. Be concise and professional. If unsure, suggest contacting the IT help desk.”).

    Step 3: Add knowledge sources

    This is where your copilot gets its intelligence. Add one or more data sources:

    • SharePoint sites: point to your documentation libraries.
    • Public websites: the copilot will crawl and index the content.
    • Uploaded files: PDFs, Word documents, and other files.
    • Dataverse tables: structured business data from your Power Platform environment.

    Once connected, the copilot uses generative AI to answer questions based on these sources — no training required.

    Step 4: Create an authored topic

    For specific processes, create a topic:

    1. Go to the Topics tab and click Add a topic.
    2. Define trigger phrases (e.g., “reset my password”, “I can’t log in”, “password help”).
    3. Build the conversation flow using the visual editor:
      • Ask questions to collect information.
      • Add conditions to branch the conversation.
      • Call a Power Automate flow to take action (e.g., send a password reset link).
      • Display a message confirming the action was completed.

    Step 5: Test and publish

    Use the built-in Test copilot panel to simulate conversations. Once satisfied:

    1. Click Publish in the top menu.
    2. Choose your channel: Microsoft Teams, a website embed (via iframe), or external channels like Slack or Facebook.
    3. For Teams, your copilot appears as a chat app that users can find in the Teams app store.

    Connecting to external systems

    Copilot Studio integrates with 1,000+ connectors through Power Automate. Common integrations include:

    • ServiceNow: create and update support tickets.
    • Salesforce: look up customer information and log activities.
    • SAP: check inventory or order status.
    • Custom APIs: call any REST API using the HTTP connector.
    • Azure OpenAI: run advanced AI prompts beyond the built-in generative capabilities.

    These integrations turn your copilot from a Q&A bot into a genuine virtual assistant that gets things done.

    Copilot Studio vs. Azure Bot Service

    FeatureCopilot StudioAzure Bot Service
    Target audienceBusiness users, citizen developersProfessional developers
    Code requiredNo (low-code visual editor)Yes (C#, JavaScript, Python)
    Built-in AIGenerative answers includedManual integration with AI services
    Connectors1,000+ via Power AutomateCustom code for integrations
    Best forBusiness scenarios, fast deploymentComplex, custom-coded bots

    If you need a copilot up and running fast and your team doesn’t have dedicated developers, Copilot Studio is the right choice. For deeply custom scenarios requiring full code control, Azure Bot Service gives you maximum flexibility.

    Licensing and pricing

    Copilot Studio is licensed per tenant with a capacity-based model:

    • Copilot Studio license: includes 25,000 messages per month per tenant.
    • Additional message packs can be purchased for higher volumes.
    • Microsoft 365 users with certain plans get limited Copilot Studio capabilities as part of their license.
    • A free trial is available at copilotstudio.microsoft.com — no credit card required.

    A “message” is a single interaction (user message + copilot response). Generative AI responses consume more messages than simple authored topic responses.

    Next steps

    1. Start a free trial at copilotstudio.microsoft.com and build your first copilot in under 30 minutes.
    2. Connect a SharePoint site as a knowledge source to see generative answers in action.
    3. Create one authored topic for a specific process your team handles frequently.
    4. Explore the official docs: learn.microsoft.com/microsoft-copilot-studio

    Conclusion

    Copilot Studio puts AI assistant creation in the hands of business teams. You don’t need to be a developer to build a copilot that answers employee questions, automates routine processes, and integrates with the tools your organization already uses. With generative AI handling the broad questions and authored topics managing critical workflows, it strikes the right balance between intelligence and control.

    In the next article, we’ll dive into Semantic Kernel, Microsoft’s open-source SDK for building AI agents and plugins with C# and Python.

    Already thinking about a use case? Tell me what your copilot would do in the comments — I’d love to help you plan it out.
  • Azure AI Document Intelligence

    Every organization deals with paperwork — invoices, receipts, contracts, ID cards, tax forms. Extracting data from these documents manually is slow and error-prone. Azure AI Document Intelligence uses machine learning to read, understand, and extract structured data from documents automatically.

    This article covers what the service offers, which models to use for different scenarios, and how to process your first document with just a few lines of code.


    What is Azure AI Document Intelligence?

    Azure AI Document Intelligence (formerly Form Recognizer) is an AI service that extracts text, key-value pairs, tables, and structures from documents. It handles:

    • Scanned PDFs and images (via built-in OCR).
    • Digital PDFs with complex layouts.
    • Photos of receipts, business cards, and forms.
    • Handwritten text in multiple languages.

    Unlike basic OCR that just reads text, Document Intelligence understands the structure of your documents — it knows which text is a header, which values belong to which fields, and how tables are organized.

    Prebuilt models vs. custom models

    The service comes with two categories of models:

    Prebuilt models

    Ready to use with zero training. Microsoft has already trained these on millions of documents:

    ModelWhat it extracts
    InvoiceVendor name, amounts, line items, tax, due date
    ReceiptMerchant, total, items, date, payment method
    ID DocumentName, date of birth, document number, expiration
    W-2 (US tax)Employer info, wages, tax withholdings
    Health Insurance CardMember ID, group number, plan details
    Business CardName, title, company, phone, email, address
    LayoutText, tables, selection marks, document structure
    ReadPlain text extraction (OCR) with line and word positions

    Custom models

    When your documents don’t match any prebuilt model — like internal forms, proprietary reports, or industry-specific paperwork — you can train a custom model using as few as 5 labeled samples.

    Real-world use cases

    Accounts payable automation

    Process incoming invoices automatically: extract vendor, amount, line items, and PO numbers, then push the data into your ERP system. Teams that used to spend hours on manual data entry can process hundreds of invoices in minutes.

    Expense report processing

    Employees snap photos of receipts. Document Intelligence reads the merchant, date, total, and category, then populates the expense report automatically.

    Contract analysis

    Extract key clauses, dates, and parties from contracts. Combine with Azure OpenAI to summarize terms or flag unusual conditions.

    Healthcare intake

    Read insurance cards and patient forms at check-in. Extract member IDs, group numbers, and patient details to reduce front-desk workload and data entry errors.

    Getting started

    Step 1: Create the resource

    1. Go to the Azure Portal and search for “Document Intelligence”.
    2. Click Create.
    3. Choose your subscription, resource group, region, and pricing tier.
    4. Click Review + Create.

    Step 2: Try it in Document Intelligence Studio

    Before writing any code, explore Document Intelligence Studio at documentintelligence.ai.azure.com. Upload a sample document, pick a prebuilt model, and see the extracted data instantly. It’s the fastest way to evaluate whether a prebuilt model fits your documents.

    Step 3: Analyze a document with Python

    Here’s how to extract data from an invoice using Python:

    from azure.ai.documentintelligence import DocumentIntelligenceClient
    from azure.core.credentials import AzureKeyCredential
    
    client = DocumentIntelligenceClient(
        endpoint="https://YOUR-RESOURCE.cognitiveservices.azure.com/",
        credential=AzureKeyCredential("YOUR-API-KEY")
    )
    
    # Analyze an invoice from a URL
    poller = client.begin_analyze_document(
        "prebuilt-invoice",
        analyze_request={"url_source": "https://example.com/invoice.pdf"}
    )
    result = poller.result()
    
    for doc in result.documents:
        print(f"Vendor: {doc.fields['VendorName'].content}")
        print(f"Total: {doc.fields['InvoiceTotal'].content}")
        print(f"Date:  {doc.fields['InvoiceDate'].content}")
    
        if "Items" in doc.fields:
            for item in doc.fields["Items"].value:
                desc = item.value["Description"].content
                amount = item.value["Amount"].content
                print(f"  - {desc}: {amount}")

    Install the SDK:

    pip install azure-ai-documentintelligence

    Step 4: Extract tables and layout

    For documents that don’t match a prebuilt model, the Layout model extracts all text, tables, and structure:

    poller = client.begin_analyze_document(
        "prebuilt-layout",
        analyze_request={"url_source": "https://example.com/report.pdf"}
    )
    result = poller.result()
    
    # Extract tables
    for table in result.tables:
        print(f"Table: {table.row_count} rows x {table.column_count} columns")
        for cell in table.cells:
            print(f"  [{cell.row_index},{cell.column_index}] {cell.content}")

    Combining with Azure OpenAI

    Document Intelligence and Azure OpenAI are a powerful combination. A common pattern:

    1. Extract text and tables from a PDF using Document Intelligence.
    2. Send the extracted content to GPT-4o with a prompt like “Summarize this contract” or “Find all penalties and deadlines.”
    3. Get structured, actionable output that would have taken hours to compile manually.

    This is especially effective for contracts, financial reports, and regulatory filings where you need both extraction accuracy and natural language understanding.

    Pricing overview

    ModelPrice per page (approx.)
    Read (OCR)$0.001
    Layout$0.01
    Prebuilt (Invoice, Receipt, etc.)$0.01
    Custom$0.03 (training is free for first model)

    At these prices, processing 1,000 invoices costs about $10. Compare that to the cost of manual data entry and the ROI becomes obvious.

    Next steps

    1. Open Document Intelligence Studio and upload a real document to see extraction results instantly.
    2. Start with a prebuilt model — invoices and receipts cover the most common automation scenarios.
    3. Train a custom model if your document type isn’t covered — 5 samples is all you need to start.
    4. Read the official docs: learn.microsoft.com/azure/ai-services/document-intelligence

    Conclusion

    Azure AI Document Intelligence eliminates the tedious work of reading and typing data from documents. Whether you’re processing 10 invoices a week or 10,000, the service scales to match your workload. Combined with Azure OpenAI, it turns raw documents into structured, actionable data — the kind of automation that delivers measurable ROI from day one.

    Next up, we’ll explore Copilot Studio, Microsoft’s platform for building custom AI assistants without writing code.

    What documents are slowing your team down? Share your document processing challenge in the comments and let’s figure out the right approach together.