Skip to content

Instantly share code, notes, and snippets.

@ChrisMcKee1
Created November 6, 2025 20:05
Show Gist options
  • Select an option

  • Save ChrisMcKee1/41469945fcd21fdcfa4c1d94cf7bfb10 to your computer and use it in GitHub Desktop.

Select an option

Save ChrisMcKee1/41469945fcd21fdcfa4c1d94cf7bfb10 to your computer and use it in GitHub Desktop.
Salesforce Agentforce and Azure AI Foundry Agent Integration Guide - Four integration patterns with validated C# SDK examples (Nov 2025)

Salesforce Agentforce and Azure AI Foundry Agent Integration

Overview

This document explores integration patterns between Salesforce Agentforce and Azure AI Foundry Agent Service using the Microsoft Agent Framework and Agent-to-Agent (A2A) protocol.

Research Date: November 2025
Key Technologies:

  • Microsoft Agent Framework (Released October 2025)
  • Azure AI Foundry Agent Service (GA May 2025)
  • Salesforce Agentforce Platform (2025)
  • A2A (Agent-to-Agent) Protocol

Executive Summary

While both platforms provide robust agent capabilities, Salesforce Agentforce does not currently support the A2A protocol natively. There are four viable integration approaches, but understanding the distinction between Azure AI Foundry's managed service and Microsoft Agent Framework SDK is critical:

Critical Distinction

Azure AI Foundry Connected Agents (Managed Service):

  • ✅ Multi-agent orchestration within Azure AI Foundry only
  • ✅ Natural language routing between Azure agents
  • NOT A2A protocol compatible
  • Cannot connect to external agents (like Salesforce)

Microsoft Agent Framework (Separate SDK):

  • ✅ Open-source SDK (C#, Python, TypeScript)
  • A2A protocol support for external agents
  • ✅ Can connect to remote agents via A2A
  • ⚠️ Separate from Azure AI Foundry Agent Service
  • ⚠️ Requires custom development and orchestration code

For Salesforce A2A integration, you MUST use Microsoft Agent Framework SDK, not Azure AI Foundry's Connected Agents feature.


Background: Key Technologies

Microsoft Agent Framework

The Microsoft Agent Framework provides a unified approach to building multi-agent systems with:

  • A2A Protocol Support: Connect to remote agents using open standards
  • Unified AIAgent Interface: Common abstraction for all agent types
  • Multi-Agent Orchestration: Built-in patterns for agent collaboration
  • Language Support: C#, Python, TypeScript

A2A Protocol Features:

  • Standard discovery via /.well-known/agent-card.json
  • Agent Cards describing capabilities and endpoints
  • Remote agent proxy pattern
  • OAuth 2.0, Service Principal authentication

Documentation: Microsoft Agent Framework


Azure AI Foundry Agent Service

Connected Agents (GA May 2025):

  • Native multi-agent coordination
  • Primary agent delegates to specialized sub-agents
  • No custom orchestrator required
  • Natural language routing

Agent Framework Integration:

  • Works with Microsoft Agent Framework
  • Can connect to remote A2A agents
  • Full thread visibility for agent-to-agent messages

Documentation: Connected Agents


Salesforce Agentforce Platform

Core Components:

  • Atlas Reasoning Engine: Autonomous decision-making
  • Agent Builder: Low-code/no-code configuration
  • Agent Script: Hybrid reasoning (deterministic + LLM)
  • Data Cloud Integration: Customer 360 data access
  • Multi-Channel Deployment: Voice, Web, Mobile

Integration Capabilities:

  • REST APIs for programmatic access
  • OAuth 2.0 authentication
  • Apex and Flow Builder for business logic
  • AgentExchange marketplace
  • MCP (Model Context Protocol) partners

⚠️ Current Limitation: Agentforce does not expose A2A-compliant endpoints

Documentation: Salesforce Agentforce


Integration Architecture Options

Option 1: Direct API Integration (OpenAPI Tool Pattern)

Description: Azure AI Foundry agent directly calls Salesforce REST APIs using the OpenAPI tool.

graph LR
    A[Azure AI Foundry Agent] -->|OpenAPI Tool| B[Salesforce REST API]
    B --> C[Salesforce Data Cloud]
    B --> D[Agentforce Actions]
    E[Microsoft Entra ID] -->|OAuth 2.0| B
    
    style A fill:#0078D4,color:#fff
    style B fill:#00A1E0,color:#fff
    style C fill:#00A1E0,color:#fff
    style D fill:#00A1E0,color:#fff
Loading

Implementation Steps:

  1. Create OpenAPI 3.0 Specification

    openapi: 3.0.0
    info:
      title: Salesforce CRM API
      version: v60.0
    servers:
      - url: https://your-instance.salesforce.com/services/data/v60.0
    paths:
      /sobjects/Account/{id}:
        get:
          summary: Get Account Details
          parameters:
            - name: id
              in: path
              required: true
              schema:
                type: string
  2. Configure Azure AI Foundry Agent

    using Azure;
    using Azure.AI.Agents.Persistent;
    using Azure.Identity;
    
    var credential = new DefaultAzureCredential();
    var client = new PersistentAgentsClient(
        "https://YOUR-RESOURCE.services.ai.azure.com/api/projects/YOUR-PROJECT",
        credential
    );
    
    // Load OpenAPI specification
    BinaryData spec = BinaryData.FromBytes(File.ReadAllBytes("salesforce-api-spec.json"));
    
    // Configure authentication (using managed identity - recommended)
    OpenApiManagedAuthDetails managedAuth = new()
    {
        Audience = "https://your-instance.salesforce.com"
    };
    
    // OR use anonymous auth for development
    // OpenApiAnonymousAuthDetails anonAuth = new();
    
    // Create OpenAPI tool definition
    OpenApiToolDefinition openApiTool = new(
        name: "salesforce_api",
        description: "Access Salesforce CRM data via REST API",
        spec: spec,
        openApiAuthentication: managedAuth
    );
    
    // Create agent with OpenAPI tool
    PersistentAgent agent = client.Administration.CreateAgent(
        model: "gpt-4o",
        name: "SalesforceIntegrationAgent",
        instructions: "You help users access and analyze Salesforce CRM data using the Salesforce API.",
        tools: [openApiTool]
    );
    
    Console.WriteLine($"Created agent: {agent.Id}");

Pros:

  • ✅ Real-time data access
  • ✅ No data duplication
  • ✅ Straightforward implementation
  • ✅ Uses existing Salesforce APIs

Cons:

  • ❌ API rate limits
  • ❌ Latency for each API call
  • ❌ No A2A protocol benefits
  • ❌ Agentforce reasoning not leveraged

Best For: Simple CRUD operations, data queries, triggering Salesforce actions


Option 2: Connected Agents Pattern (Azure-Only Multi-Agent)

Description: Build specialized Azure AI Foundry agents for different Salesforce operations, orchestrated by a main agent using Azure's native Connected Agents feature. Important: Connected Agents only coordinates between Azure agents within the same Azure AI Foundry project - it does NOT support A2A protocol or external agent communication.

graph TD
    A[Main Azure Agent<br/>Orchestrator] -->|Connected Agent<br/>Azure-Internal Only| B[Salesforce Data Agent<br/>Azure]
    A -->|Connected Agent<br/>Azure-Internal Only| C[Salesforce Analytics Agent<br/>Azure]
    A -->|Connected Agent<br/>Azure-Internal Only| D[CRM Update Agent<br/>Azure]
    
    B -->|Azure Functions Tool| E[Salesforce Query APIs]
    C -->|Azure Functions Tool| F[Salesforce Reports API]
    D -->|Azure Functions Tool| G[Salesforce Update APIs]
    
    E --> H[Salesforce Data Cloud]
    F --> H
    G --> H
    
    I[User Request] --> A
    A --> J[Unified Response]
    
    style A fill:#0078D4,color:#fff
    style B fill:#50E6FF,color:#000
    style C fill:#50E6FF,color:#000
    style D fill:#50E6FF,color:#000
    style H fill:#00A1E0,color:#fff
Loading

Implementation Steps:

  1. Create Specialized Sub-Agents

    using Azure;
    using Azure.AI.Agents.Persistent;
    using Azure.Identity;
    
    var credential = new DefaultAzureCredential();
    var client = new PersistentAgentsClient(
        "https://YOUR-RESOURCE.services.ai.azure.com/api/projects/YOUR-PROJECT",
        credential
    );
    
    // Assume azureFunctionsTool is already defined (Azure Functions tool definition)
    
    // Create Salesforce Data Agent
    PersistentAgent dataAgent = client.Administration.CreateAgent(
        model: "gpt-4o-mini",
        name: "SalesforceDataAgent",
        instructions: @"You retrieve customer data from Salesforce. 
                       Query accounts, contacts, opportunities, and cases.
                       Use the Azure Functions tool to call Salesforce APIs.",
        tools: [azureFunctionsTool]
    );
    
    // Create Salesforce Analytics Agent
    PersistentAgent analyticsAgent = client.Administration.CreateAgent(
        model: "gpt-4o-mini",
        name: "SalesforceAnalyticsAgent",
        instructions: @"You analyze Salesforce data and generate insights.
                       Run reports, calculate metrics, identify trends.",
        tools: [azureFunctionsTool]
    );
    
    // Create CRM Update Agent
    PersistentAgent updateAgent = client.Administration.CreateAgent(
        model: "gpt-4o-mini",
        name: "CRMUpdateAgent",
        instructions: @"You update Salesforce records safely.
                       Validate data before updates. Log all changes.",
        tools: [azureFunctionsTool]
    );
  2. Configure Main Orchestrator Agent

    // Create connected agent tool definitions
    ConnectedAgentToolDefinition dataAgentTool = new(
        new ConnectedAgentDetails(
            dataAgent.Id,
            "SalesforceDataAgent",
            "Retrieves customer data from Salesforce CRM"
        )
    );
    
    ConnectedAgentToolDefinition analyticsAgentTool = new(
        new ConnectedAgentDetails(
            analyticsAgent.Id,
            "SalesforceAnalyticsAgent",
            "Analyzes Salesforce data and generates insights"
        )
    );
    
    ConnectedAgentToolDefinition updateAgentTool = new(
        new ConnectedAgentDetails(
            updateAgent.Id,
            "CRMUpdateAgent",
            "Updates Salesforce CRM records safely"
        )
    );
    
    // Create main orchestrator with connected agents
    PersistentAgent mainAgent = client.Administration.CreateAgent(
        model: "gpt-4o",
        name: "SalesforceOrchestrator",
        instructions: @"You help users with Salesforce CRM operations.
                       Delegate data retrieval to SalesforceDataAgent.
                       Delegate analysis to SalesforceAnalyticsAgent.
                       Delegate updates to CRMUpdateAgent.
                       Coordinate responses from multiple agents.",
        tools: [dataAgentTool, analyticsAgentTool, updateAgentTool]
    );
    
    Console.WriteLine($"Created main agent: {mainAgent.Id}");
  3. Create Azure Function for Salesforce API Calls

    [FunctionName("SalesforceQuery")]
    public async Task<IActionResult> QuerySalesforce(
        [HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req)
    {
        // Parse request
        var requestBody = await new StreamReader(req.Body).ReadToEndAsync();
        var query = JsonSerializer.Deserialize<SalesforceQueryRequest>(requestBody);
        
        // Call Salesforce API
        var salesforceClient = new SalesforceClient(
            instanceUrl: Environment.GetEnvironmentVariable("SALESFORCE_INSTANCE_URL"),
            accessToken: await GetSalesforceToken()
        );
        
        var result = await salesforceClient.QueryAsync(query.SoqlQuery);
        
        return new OkObjectResult(result);
    }

Pros:

  • ✅ Built-in orchestration (no custom code)
  • ✅ Specialized agents for different tasks
  • ✅ Full Azure observability and tracing
  • ✅ Scalable architecture
  • ✅ Easy to extend with new agents
  • ✅ Native Azure AI Foundry managed service

Cons:

  • ❌ All agents must be Azure AI Foundry agents (no external agents)
  • ❌ NOT A2A protocol compatible
  • ❌ Cannot connect to external Salesforce agents
  • ❌ Agentforce reasoning capabilities not directly used
  • ❌ More complex setup than Option 1

Best For: Complex workflows with multiple specialized Azure agents, when all logic stays within Azure AI Foundry ecosystem

⚠️ Important Limitation: This pattern uses Azure AI Foundry's Connected Agents feature, which only supports coordination between agents within the same Azure AI Foundry project. It does NOT support A2A protocol or connecting to external agents like Salesforce Agentforce. For external agent communication, use Option 3 (Microsoft Agent Framework with A2A wrapper).


Option 3: Microsoft Agent Framework with Custom A2A Wrapper

Description: Use Microsoft Agent Framework (separate SDK, not Azure AI Foundry's Connected Agents) to build an A2A-compliant wrapper around Salesforce APIs. This enables true Agent-to-Agent communication using the A2A protocol. Note: This requires using Microsoft Agent Framework SDK, which is separate from Azure AI Foundry Agent Service.

graph LR
    A[Your Agent<br/>Microsoft Agent Framework SDK] -->|A2A Protocol| B[Custom A2A Wrapper<br/>Azure Container Instance]
    
    B -->|/.well-known/<br/>agent-card.json| A
    
    B -->|Salesforce REST API| C[Salesforce Platform]
    C --> D[Agentforce]
    C --> E[Data Cloud]
    C --> F[Einstein AI]
    
    G[Microsoft Agent<br/>Framework SDK<br/>NOT Azure Foundry] -.->|Required for A2A| A
    
    H[OAuth 2.0] -->|Authenticate| B
    
    style A fill:#0078D4,color:#fff
    style B fill:#FFA500,color:#fff
    style C fill:#00A1E0,color:#fff
    style D fill:#00A1E0,color:#fff
    style E fill:#00A1E0,color:#fff
    style F fill:#00A1E0,color:#fff
    style G fill:#FFA500,color:#fff
Loading

A2A Protocol Flow:

sequenceDiagram
    participant Azure as Azure AI Foundry Agent
    participant Framework as Microsoft Agent Framework
    participant Wrapper as A2A Wrapper
    participant SF as Salesforce API
    
    Azure->>Framework: Discover Salesforce agent
    Framework->>Wrapper: GET /.well-known/agent-card.json
    Wrapper-->>Framework: Agent Card (capabilities)
    Framework-->>Azure: Salesforce agent available
    
    Azure->>Framework: Send task to Salesforce agent
    Framework->>Wrapper: POST /a2a/task<br/>(A2A message)
    Wrapper->>SF: Translate to Salesforce API call
    SF-->>Wrapper: API response
    Wrapper-->>Framework: A2A response
    Framework-->>Azure: Task result
Loading

Implementation Steps:

  1. Create Agent Card for Salesforce Capabilities

    {
      "name": "Salesforce Agentforce",
      "description": "Access Salesforce CRM data and Agentforce capabilities",
      "version": "1.0.0",
      "capabilities": [
        {
          "name": "query_accounts",
          "description": "Query Salesforce accounts",
          "input_schema": {
            "type": "object",
            "properties": {
              "filters": { "type": "object" },
              "fields": { "type": "array" }
            }
          }
        },
        {
          "name": "create_opportunity",
          "description": "Create a sales opportunity",
          "input_schema": {
            "type": "object",
            "properties": {
              "account_id": { "type": "string" },
              "amount": { "type": "number" },
              "close_date": { "type": "string" }
            }
          }
        },
        {
          "name": "agentforce_analyze",
          "description": "Use Agentforce to analyze customer data",
          "input_schema": {
            "type": "object",
            "properties": {
              "query": { "type": "string" },
              "context": { "type": "object" }
            }
          }
        }
      ],
      "endpoints": {
        "task": "https://your-wrapper.azurewebsites.net/a2a/task"
      },
      "authentication": {
        "type": "oauth2",
        "authorization_url": "https://login.salesforce.com/services/oauth2/authorize",
        "token_url": "https://login.salesforce.com/services/oauth2/token"
      }
    }
  2. Build A2A Wrapper Server (C#)

    using Microsoft.AspNetCore.Mvc;
    using A2A;
    
    [ApiController]
    [Route("a2a")]
    public class SalesforceA2AController : ControllerBase
    {
        private readonly ISalesforceClient _salesforceClient;
        
        // Expose agent card at well-known location
        [HttpGet(".well-known/agent-card.json")]
        public IActionResult GetAgentCard()
        {
            var agentCard = LoadAgentCardFromConfig();
            return Ok(agentCard);
        }
        
        // Handle A2A task requests
        [HttpPost("task")]
        public async Task<IActionResult> HandleTask([FromBody] A2ATaskRequest request)
        {
            try
            {
                // Translate A2A message to Salesforce API call
                var salesforceResult = request.Capability switch
                {
                    "query_accounts" => await _salesforceClient.QueryAccountsAsync(
                        request.Input["filters"],
                        request.Input["fields"]
                    ),
                    "create_opportunity" => await _salesforceClient.CreateOpportunityAsync(
                        request.Input
                    ),
                    "agentforce_analyze" => await _salesforceClient.InvokeAgentforceAsync(
                        request.Input["query"],
                        request.Input["context"]
                    ),
                    _ => throw new NotSupportedException($"Capability {request.Capability} not supported")
                };
                
                // Return A2A response
                return Ok(new A2ATaskResponse
                {
                    Status = "completed",
                    Result = salesforceResult
                });
            }
            catch (Exception ex)
            {
                return Ok(new A2ATaskResponse
                {
                    Status = "failed",
                    Error = ex.Message
                });
            }
        }
    }
  3. Connect Using Microsoft Agent Framework with A2A

    Important: This uses Microsoft Agent Framework SDK (separate from Azure AI Foundry), not Azure AI Foundry's Connected Agents feature. The Agent Framework returns AIAgent interface which is NOT compatible with Azure AI Foundry's PersistentAgent.

    using System;
    using A2A;
    using Microsoft.Agents.AI;
    using Microsoft.Agents.AI.A2A;
    
    // Option 1: Well-known discovery (recommended for production)
    A2ACardResolver agentCardResolver = new(new Uri("https://your-wrapper.azurewebsites.net"));
    
    // Discover Salesforce agent via A2A protocol (looks for /.well-known/agent-card.json)
    AIAgent salesforceAgent = await agentCardResolver.GetAIAgentAsync();
    
    // Option 2: Direct configuration (for development/private discovery)
    // A2AClient a2aClient = new(new Uri("https://your-wrapper.azurewebsites.net/salesforce"));
    // AIAgent salesforceAgent = a2aClient.GetAIAgent();
    
    // Now you can interact with the salesforceAgent using standard AIAgent operations
    // Note: This is Microsoft Agent Framework, NOT Azure AI Foundry
    // You would need to use Agent Framework's orchestration patterns
    // See: https://learn.microsoft.com/agent-framework/tutorials/overview
    
    // Example interaction (Agent Framework pattern):
    var thread = salesforceAgent.GetNewThread();
    await foreach (var message in salesforceAgent.InvokeAsync("Get account details for Contoso", thread))
    {
        Console.WriteLine(message.Content);
    }

    Note: Microsoft Agent Framework A2A agents return AIAgent interface and use Agent Framework orchestration. This is fundamentally different from Azure AI Foundry's PersistentAgentsClient which returns PersistentAgent. You cannot mix the two SDKs.

Pros:

  • ✅ True A2A protocol compliance
  • ✅ Future-proof if Salesforce adds native A2A
  • ✅ Extensible architecture
  • ✅ Can expose Agentforce reasoning capabilities
  • ✅ Standard discovery and capability negotiation
  • ✅ Works with Microsoft Agent Framework SDK

Cons:

  • Requires Microsoft Agent Framework SDK (separate from Azure AI Foundry)
  • ❌ Custom development and maintenance for wrapper
  • ❌ Additional infrastructure (wrapper service hosting)
  • ❌ Salesforce doesn't natively support A2A
  • ❌ More complex than direct API integration
  • Cannot use Azure AI Foundry's Connected Agents (different architecture)
  • ❌ Custom orchestration code required

Best For: Organizations using Microsoft Agent Framework for multi-platform agent orchestration, future-proofing for A2A ecosystem

⚠️ Important: This approach uses Microsoft Agent Framework SDK (open-source), NOT Azure AI Foundry's managed Connected Agents feature. Agent Framework provides A2A protocol support through Microsoft.Agents.AI.A2A NuGet package. Azure AI Foundry Connected Agents does NOT support A2A or external agents.


Option 4: Knowledge Integration via Azure AI Search

Description: Extract Salesforce knowledge into Azure AI Search for semantic search capabilities, while maintaining bidirectional communication for actions.

graph TD
    A[Salesforce Data Cloud] -->|ETL Pipeline<br/>Nightly Sync| B[Azure Data Factory]
    B --> C[Azure AI Search<br/>Vector Index]
    
    D[Azure AI Foundry Agent] -->|Azure AI Search Tool| C
    D -->|Query Embeddings| C
    C -->|Semantic Results| D
    
    E[Agentforce] -->|Webhook Events| F[Azure Functions]
    F -->|Trigger| D
    
    D -->|REST API<br/>Update Actions| G[Salesforce APIs]
    G --> A
    
    H[User Query] --> D
    D --> I[AI Response with<br/>Salesforce Context]
    
    style A fill:#00A1E0,color:#fff
    style B fill:#0078D4,color:#fff
    style C fill:#0078D4,color:#fff
    style D fill:#0078D4,color:#fff
    style E fill:#00A1E0,color:#fff
Loading

Data Flow:

sequenceDiagram
    participant SF as Salesforce
    participant ADF as Azure Data Factory
    participant Search as Azure AI Search
    participant Agent as Azure AI Foundry Agent
    participant User as User
    
    Note over SF,Search: Nightly Knowledge Sync
    SF->>ADF: Extract data (Accounts, Contacts, Cases)
    ADF->>ADF: Transform to JSON + Generate embeddings
    ADF->>Search: Index documents with vectors
    
    Note over Agent,User: User Query
    User->>Agent: "Find high-value customers in tech sector"
    Agent->>Search: Semantic search query
    Search-->>Agent: Ranked results with context
    Agent->>Agent: Reason about results
    Agent-->>User: "Here are 5 enterprise tech customers..."
    
    Note over SF,Agent: Real-time Action
    SF->>Azure Functions: Webhook: New high-value opportunity
    Azure Functions->>Agent: Trigger analysis
    Agent->>SF: Update opportunity score via API
Loading

Implementation Steps:

  1. Set Up ETL Pipeline (Azure Data Factory)

    {
      "name": "Salesforce-to-AzureSearch-Pipeline",
      "properties": {
        "activities": [
          {
            "name": "ExtractSalesforceData",
            "type": "Copy",
            "source": {
              "type": "SalesforceSource",
              "query": "SELECT Id, Name, Industry, AnnualRevenue, Description FROM Account WHERE IsDeleted = false"
            },
            "sink": {
              "type": "JsonSink"
            }
          },
          {
            "name": "GenerateEmbeddings",
            "type": "AzureFunction",
            "functionName": "GenerateEmbeddings"
          },
          {
            "name": "IndexToAzureSearch",
            "type": "Copy",
            "source": {
              "type": "JsonSource"
            },
            "sink": {
              "type": "AzureSearchIndexSink"
            }
          }
        ],
        "triggers": [
          {
            "name": "NightlySync",
            "type": "ScheduleTrigger",
            "recurrence": {
              "frequency": "Day",
              "interval": 1,
              "startTime": "2025-01-01T02:00:00Z"
            }
          }
        ]
      }
    }
  2. Create Azure AI Search Index with Vector Fields

    using Azure.Search.Documents.Indexes;
    using Azure.Search.Documents.Indexes.Models;
    
    var indexDefinition = new SearchIndex("salesforce-knowledge")
    {
        Fields = new[]
        {
            new SearchField("id", SearchFieldDataType.String) { IsKey = true },
            new SearchField("name", SearchFieldDataType.String) { IsSearchable = true },
            new SearchField("industry", SearchFieldDataType.String) { IsFacetable = true },
            new SearchField("description", SearchFieldDataType.String) { IsSearchable = true },
            new SearchField("annualRevenue", SearchFieldDataType.Double) { IsSortable = true },
            new SearchField("descriptionVector", SearchFieldDataType.Collection(SearchFieldDataType.Single))
            {
                VectorSearchDimensions = 1536,
                VectorSearchProfileName = "vector-profile"
            }
        },
        VectorSearch = new VectorSearch
        {
            Profiles = 
            {
                new VectorSearchProfile("vector-profile", "vector-config")
            },
            Algorithms = 
            {
                new HnswAlgorithmConfiguration("vector-config")
            }
        }
    };
    
    await searchIndexClient.CreateIndexAsync(indexDefinition);
  3. Configure Azure Agent with AI Search Tool

    // Create Azure AI Search tool
    var azureSearchTool = new AzureAISearchToolDefinition(
        searchResourceName: "your-search-service",
        indexName: "salesforce-knowledge",
        authentication: new AzureAISearchAuthConfig
        {
            Type = AzureAISearchAuthType.ManagedIdentity
        }
    );
    
    // Create agent with AI Search tool
    var agent = await client.Administration.CreateAgentAsync(
        model: "gpt-4o",
        name: "SalesforceKnowledgeAgent",
        instructions: @"You help users find and analyze Salesforce customer data.
                       Use Azure AI Search to find relevant customers, accounts, and opportunities.
                       Provide insights based on semantic similarity and business context.
                       When users request updates, use the OpenAPI tool to call Salesforce APIs.",
        tools: new ToolDefinition[] 
        { 
            azureSearchTool,
            salesforceOpenApiTool 
        }
    );
  4. Set Up Salesforce Webhooks for Real-Time Events

    // Salesforce Apex Trigger
    trigger OpportunityWebhook on Opportunity (after insert, after update) {
        if (Trigger.isAfter) {
            for (Opportunity opp : Trigger.new) {
                if (opp.Amount > 100000 && opp.StageName == 'Prospecting') {
                    // Send webhook to Azure Functions
                    HttpRequest req = new HttpRequest();
                    req.setEndpoint('https://your-function-app.azurewebsites.net/api/opportunity-event');
                    req.setMethod('POST');
                    req.setHeader('Content-Type', 'application/json');
                    req.setBody(JSON.serialize(opp));
                    
                    Http http = new Http();
                    HttpResponse res = http.send(req);
                }
            }
        }
    }

Pros:

  • ✅ Semantic search capabilities
  • ✅ Vector similarity for finding relevant data
  • ✅ Hybrid search (keyword + vector)
  • ✅ Fast query performance
  • ✅ Bidirectional integration (read + write)

Cons:

  • ❌ Data duplication
  • ❌ Eventual consistency (sync lag)
  • ❌ ETL pipeline complexity
  • ❌ Storage costs for indexed data

Best For: Knowledge-intensive scenarios, semantic search requirements, large-scale data analysis


Comparison Matrix

Feature Option 1:
Direct API
Option 2:
Connected Agents
Option 3:
A2A Wrapper
Option 4:
AI Search
Complexity Low Medium High High
Real-time Data ✅ Yes ✅ Yes ✅ Yes ❌ Eventual
Semantic Search ❌ No ❌ No ❌ No ✅ Yes
A2A Protocol ❌ No No ✅ Yes ❌ No
Azure Managed ✅ Yes ✅ Yes No ✅ Yes
External Agents ❌ No No ✅ Yes ❌ No
Requires Custom SDK ❌ No ❌ No Agent Framework ❌ No
Agentforce Reasoning ⚠️ Limited ⚠️ Limited ✅ Possible ❌ No
Setup Time 1-2 days 3-5 days 2-3 weeks 1-2 weeks
Maintenance Low Low Medium-High Medium
Scalability Medium High High Very High
Cost Low Medium Medium-High Medium-High
Future-Proof Medium Medium Very High High

Recommended Implementation Path

For an educational research repository, document all four options in this sequence:

Phase 1: Foundation (Week 1-2)

Start with Option 1 - Direct API Integration

  • Simple to understand and implement
  • Teaches basic agent-to-external-system patterns
  • Quick wins for students
  • Code Example: OpenAPI tool configuration

Phase 2: Orchestration (Week 3-4)

Progress to Option 2 - Connected Agents

  • Shows Azure's native multi-agent capabilities
  • Teaches enterprise orchestration patterns
  • Prepares for complex scenarios
  • Code Example: Multi-agent coordination

Phase 3: Advanced Protocol (Week 5-6)

Explore Option 3 - A2A Wrapper

  • Advanced topic for protocol implementation
  • Future-proofs knowledge base
  • Teaches standards-based integration
  • Code Example: Custom A2A server

Phase 4: Knowledge Integration (Week 7-8)

Implement Option 4 - Azure AI Search

  • Shows RAG patterns with external systems
  • Teaches vector search and embeddings
  • Best for knowledge-heavy scenarios
  • Code Example: ETL pipeline + semantic search

Code Examples

Example 1: OpenAPI Tool Configuration

using Azure;
using Azure.AI.Agents.Persistent;
using Azure.Identity;

var credential = new DefaultAzureCredential();
var client = new PersistentAgentsClient(
    "https://YOUR-RESOURCE.services.ai.azure.com/api/projects/YOUR-PROJECT",
    credential
);

// Load OpenAPI spec from file
BinaryData spec = BinaryData.FromBytes(File.ReadAllBytes("salesforce-api-spec.json"));

// Configure authentication - using managed identity (recommended)
OpenApiManagedAuthDetails managedAuth = new()
{
    Audience = "https://your-instance.salesforce.com"
};

// Create OpenAPI tool definition
OpenApiToolDefinition openApiTool = new(
    name: "salesforce",
    description: "Access Salesforce CRM data via REST API",
    spec: spec,
    openApiAuthentication: managedAuth
);

// Create agent with tool
PersistentAgent agent = client.Administration.CreateAgent(
    model: "gpt-4o",
    name: "SalesforceAgent",
    instructions: "You are a helpful assistant that provides Salesforce CRM data access.",
    tools: [openApiTool]
);

Console.WriteLine($"Created agent: {agent.Id}");

Example 2: Connected Agents Setup

using Azure;
using Azure.AI.Agents.Persistent;
using Azure.Identity;

var credential = new DefaultAzureCredential();
var client = new PersistentAgentsClient(
    "https://YOUR-RESOURCE.services.ai.azure.com/api/projects/YOUR-PROJECT",
    credential
);

// Create specialized agents (assume tools are defined)
PersistentAgent dataAgent = client.Administration.CreateAgent(
    model: "gpt-4o-mini",
    name: "DataAgent",
    instructions: "You retrieve Salesforce data using Azure Functions.",
    tools: [azureFunctionsTool]
);

PersistentAgent analyticsAgent = client.Administration.CreateAgent(
    model: "gpt-4o-mini",
    name: "AnalyticsAgent",
    instructions: "You analyze data and provide insights.",
    tools: [azureFunctionsTool]
);

// Create connected agent tool definitions
ConnectedAgentToolDefinition dataAgentTool = new(
    new ConnectedAgentDetails(dataAgent.Id, "DataAgent", "Retrieves data")
);

ConnectedAgentToolDefinition analyticsAgentTool = new(
    new ConnectedAgentDetails(analyticsAgent.Id, "AnalyticsAgent", "Analyzes data")
);

// Create main orchestrator
PersistentAgent mainAgent = client.Administration.CreateAgent(
    model: "gpt-4o",
    name: "Orchestrator",
    instructions: "Coordinate between data retrieval and analysis agents.",
    tools: [dataAgentTool, analyticsAgentTool]
);

// Create thread and send message
PersistentAgentThread thread = client.Threads.CreateThread();
client.Messages.CreateMessage(
    thread.Id,
    MessageRole.User,
    "Find the top 10 accounts by revenue and analyze trends"
);

ThreadRun run = client.Runs.CreateRun(thread.Id, mainAgent.Id);

Example 3: A2A Client Connection

Important: This example uses Microsoft Agent Framework SDK, NOT Azure AI Foundry SDK.

using System;
using A2A;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.A2A;

// Discover Salesforce agent via A2A protocol
A2ACardResolver resolver = new(new Uri("https://salesforce-a2a-wrapper.azurewebsites.net"));

// Get agent from well-known location (/.well-known/agent-card.json)
AIAgent salesforceAgent = await resolver.GetAIAgentAsync();

Console.WriteLine($"Connected to A2A agent: {salesforceAgent.Name}");

// Use the agent (Microsoft Agent Framework patterns)
var thread = salesforceAgent.GetNewThread();

await foreach (var message in salesforceAgent.InvokeAsync(
    "Get account details for Contoso Corporation", 
    thread))
{
    Console.WriteLine($"Response: {message.Content}");
}

Note: AIAgent from Agent Framework is NOT compatible with Azure AI Foundry's PersistentAgent. These are two separate SDK architectures.


Authentication Patterns

Pattern 1: OAuth 2.0 with Microsoft Entra ID

// Configure Salesforce connected app in Entra ID
var authConfig = new OpenApiAuthConfig
{
    Type = OpenApiAuthType.OAuth,
    ClientId = "YOUR_ENTRA_APP_ID",
    ClientSecret = "YOUR_ENTRA_APP_SECRET",
    AuthorizationUrl = "https://login.microsoftonline.com/YOUR_TENANT/oauth2/v2.0/authorize",
    TokenUrl = "https://login.microsoftonline.com/YOUR_TENANT/oauth2/v2.0/token",
    Scopes = new[] { "https://your-instance.salesforce.com/.default" }
};

Pattern 2: Service Principal with Managed Identity

using Azure.Identity;

// Use Managed Identity for authentication
var credential = new DefaultAzureCredential();

// Azure automatically handles token acquisition and refresh
var client = new PersistentAgentsClient(endpoint, credential);

Best Practices

Security

  1. Never hardcode credentials - Use Azure Key Vault or environment variables
  2. Implement least privilege - Grant only necessary Salesforce API permissions
  3. Use managed identities - Leverage Azure Managed Identity when possible
  4. Audit all actions - Log agent-to-Salesforce communications
  5. Implement rate limiting - Respect Salesforce API limits

Performance

  1. Cache frequently accessed data - Reduce API calls
  2. Use batch operations - Combine multiple Salesforce operations
  3. Implement connection pooling - Reuse HTTP connections
  4. Monitor latency - Track response times for optimization
  5. Use async/await - Non-blocking operations for better throughput

Reliability

  1. Implement retry logic - Handle transient failures
  2. Use circuit breakers - Prevent cascading failures
  3. Monitor API quotas - Track Salesforce API usage
  4. Implement fallback strategies - Graceful degradation
  5. Test error scenarios - Validate error handling

Future Considerations

If Salesforce Adds Native A2A Support

When Salesforce potentially adds native A2A protocol support:

  1. Option 3 becomes preferred - Direct A2A connection without wrapper
  2. Simplified architecture - Remove custom wrapper layer
  3. Agentforce reasoning - Direct access to Agentforce capabilities
  4. Standard discovery - Use Salesforce's official agent card

Multi-Agent Ecosystem

As the agent ecosystem evolves:

  1. Multiple A2A agents - Connect to various SaaS platforms
  2. Agent marketplaces - Discover and integrate pre-built agents
  3. Standard protocols - Industry-wide agent communication standards
  4. Enterprise agent networks - Internal agent collaboration

Frequently Asked Questions

Q: Can Azure AI Foundry's Connected Agents connect to Salesforce agents via A2A?

A: No. Azure AI Foundry's Connected Agents feature is for coordinating agents within the same Azure AI Foundry project only. It does NOT support:

  • A2A (Agent-to-Agent) protocol
  • External agent connections
  • Remote agent proxies
  • Salesforce or any non-Azure agents

Connected Agents uses natural language routing between Azure-managed agents in your project. It's a managed service feature, not an A2A client.

Q: What DO I need to connect to Salesforce agents via A2A?

A: Microsoft Agent Framework SDK (separate open-source project). This SDK provides:

  • Microsoft.Agents.AI.A2A NuGet package
  • A2ACardResolver and A2AClient classes
  • A2A protocol implementation
  • Remote agent proxy capabilities

You would need to:

  1. Use Microsoft Agent Framework SDK (NOT Azure AI Foundry Agent Service)
  2. Build a custom A2A wrapper around Salesforce APIs
  3. Write custom orchestration code
  4. Host your own infrastructure

Q: Is Semantic Kernel being deprecated?

A: No. Based on official Microsoft documentation (as of November 2025):

  • Semantic Kernel is actively maintained
  • Agent orchestration features are marked "experimental" but under active development
  • Microsoft Agent Framework is described as a "progression" of Semantic Kernel + AutoGen
  • Both SDKs coexist; Agent Framework combines patterns from both

Clarification: Microsoft Agent Framework represents the evolution of multi-agent orchestration, combining best practices from Semantic Kernel and AutoGen into a unified SDK. Semantic Kernel continues as an enterprise AI SDK.

Q: Can I use Microsoft Agent Framework with Azure AI Foundry Agent Service?

A: It's separate. They serve different purposes:

Azure AI Foundry Agent Service (Managed PaaS):

  • Managed agent runtime
  • Built-in tools (Azure AI Search, Bing, Functions, etc.)
  • Thread management, observability, content filters
  • Enterprise features (RBAC, VNet, BYOS)
  • Connected Agents for internal multi-agent

Microsoft Agent Framework (SDK):

  • Open-source development kit
  • Custom orchestration patterns
  • A2A protocol support
  • Requires custom hosting and infrastructure
  • Flexibility for multi-platform agent systems

You could potentially use Agent Framework SDK to build agents that call Azure AI Foundry agents via APIs, but they are architecturally distinct approaches.

Q: Which option should I choose for Salesforce integration?

Decision Tree:

  1. Simple API calls to SalesforceOption 1 (OpenAPI Tool)

    • Real-time data access
    • Easiest to implement
    • No custom orchestration
  2. Complex workflows within Azure onlyOption 2 (Connected Agents)

    • Multiple specialized Azure agents
    • Natural language routing
    • Fully managed by Azure
  3. True A2A protocol with external agentsOption 3 (Agent Framework + A2A Wrapper)

    • Requires Microsoft Agent Framework SDK
    • Custom development
    • Future-proof for A2A ecosystem
    • Most complex
  4. Knowledge-intensive scenariosOption 4 (Azure AI Search)

    • Semantic search capabilities
    • Vector similarity
    • Eventual consistency acceptable

Additional Resources

Microsoft Documentation

Salesforce Documentation

Community Resources


Conclusion

While Salesforce Agentforce and Azure AI Foundry Agent Service don't currently support direct A2A protocol integration, there are four viable approaches for enabling agent collaboration. However, it's critical to understand the architectural distinctions:

Key Takeaways

  1. Azure AI Foundry Connected Agents ≠ A2A Protocol

    • Connected Agents is for internal Azure agent coordination only
    • Does NOT connect to external agents
    • Does NOT support A2A protocol
    • Managed service with natural language routing
  2. For True A2A Integration: Use Microsoft Agent Framework

    • Separate open-source SDK (not Azure AI Foundry managed service)
    • Provides A2A protocol support
    • Requires custom development and hosting
    • Can connect to remote agents via A2A
  3. Semantic Kernel Status

    • NOT deprecated - actively maintained
    • Agent orchestration features are experimental
    • Microsoft Agent Framework is a progression (combining SK + AutoGen)
    • Both SDKs coexist for different use cases

Integration Options Summary

  1. Direct API Integration (Option 1) - Simplest approach using OpenAPI tools, no A2A
  2. Connected Agents (Option 2) - Azure's native multi-agent for internal agents only
  3. Agent Framework + A2A Wrapper (Option 3) - True A2A protocol (requires separate SDK)
  4. Knowledge Integration (Option 4) - Semantic search with Azure AI Search

Each approach has trade-offs in complexity, capabilities, and maintenance requirements. For educational purposes, documenting all four patterns provides comprehensive coverage of modern agent integration techniques.

Recommendation:

  • Start with Option 1 for quick wins and learning basic patterns
  • Progress to Option 2 to understand Azure's managed multi-agent capabilities
  • Explore Option 3 only if you need true A2A protocol and are willing to use Agent Framework SDK
  • Implement Option 4 for knowledge-intensive scenarios with semantic search

Document Version: 1.1 (Corrected)
Last Updated: November 6, 2025
Corrections: Clarified distinction between Azure AI Foundry Connected Agents (managed, Azure-only) and Microsoft Agent Framework (SDK, A2A support). Corrected Semantic Kernel deprecation status (NOT deprecated).
Authors: Azure AI Foundry Agent Service Research Team

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment