Skip to content

acascell/azure-langchain

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

azure-langchain

Creating langchain specialized agents and deploy using Azure Agent Framework

LangChain Multi-Agent Systems with Microsoft Agent Framework

A production-ready multi-agent incident triage copilot that combines LangChain for local chain composition with the Microsoft Agent Framework (azure-ai-agents) for cloud-hosted orchestration — deployable as a Microsoft Foundry Hosted Agent.


Overview

LangChain provides excellent abstractions for building agents locally — @tool decorators, RunnableLambda chains, and composable pipelines. The Microsoft Agent Framework fills the production gaps:

Challenge Solution
Where do agents run? Microsoft Foundry Hosted Agents (managed containers)
Live web search Built-in BingGroundingTool
Code execution Built-in CodeInterpreterTool
Authentication Managed Identity — zero secrets in code
Observability OpenTelemetry + Application Insights
One-command deploy azd up

Key insight: LangChain handles local logic and chain composition; the Microsoft Agent Framework handles cloud-hosted orchestration and tooling.


Architecture

The copilot uses a coordinator pattern with three specialist agents:

User Query
    │
    ▼
Coordinator Agent
    ├── LangChain Triage Chain      (routing decision)
    └── LangChain Synthesis Chain   (combine results)
         │
         ├──────────────────┬──────────────────┐
         ▼                  ▼                  ▼
    Research Agent    Diagnostics Agent   Remediation Agent

Each specialist agent supports dual-mode execution:

Mode LangChain Role Microsoft Agent Framework Role
Local @tool functions with heuristic analysis Not used
Foundry Handles routing and synthesis AgentsClient with BingGroundingTool, CodeInterpreterTool

This means you can develop and test locally with zero cloud dependencies, then deploy to Foundry for full production capabilities.


Getting Started

Prerequisites

  • Python 3.10+
  • Azure CLI + Azure Developer CLI (azd)
  • Microsoft Foundry access (for cloud deployment)

Local Development

git clone https://github.com/leestott/hosted-agents-langchain-samples
cd hosted-agents-langchain-samples

python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate

pip install -r requirements.txt
python -m src

Open http://localhost:8080 to interact with the copilot via the built-in web UI.

Test via API

curl -X POST http://localhost:8080/triage \
  -H "Content-Type: application/json" \
  -d '{"message": "Getting 503 errors on /api/orders since 2pm"}'

The response includes a coordinator summary, specialist results with confidence scores, and the tools each agent invoked.

Run Tests

pytest

Tests run entirely in local mode — no cloud credentials required.


Implementation Guide

Step 1 — Define LangChain Tools

Use the @tool decorator for typed, documented tool functions. These work identically in local mode and serve as fallbacks when Foundry is unavailable:

from langchain_core.tools import tool

@tool
def classify_incident_severity(query: str) -> str:
    """Classify the severity and priority of an incident based on keywords."""
    query_lower = query.lower()
    critical_keywords = ["production down", "all users", "outage", "breach"]
    high_keywords = ["503", "500", "timeout", "latency", "slow"]

    if any(kw in query_lower for kw in critical_keywords):
        return "severity=critical, priority=P1"
    if any(kw in query_lower for kw in high_keywords):
        return "severity=high, priority=P2"
    return "severity=low, priority=P4"

Step 2 — Build Routing with LangChain Chains

Use RunnableLambda to classify incidents and select which specialists to invoke:

from langchain_core.runnables import RunnableLambda
from enum import Enum

class AgentRole(str, Enum):
    RESEARCH = "research"
    DIAGNOSTICS = "diagnostics"
    REMEDIATION = "remediation"

DIAGNOSTICS_KEYWORDS = {"log", "error", "exception", "timeout", "500", "503", "crash", "root cause"}
REMEDIATION_KEYWORDS = {"fix", "remediate", "runbook", "rollback", "hotfix", "patch", "resolve"}

def _route(inputs: dict) -> dict:
    query = inputs["query"].lower()
    specialists = [AgentRole.RESEARCH]  # always included

    if any(kw in query for kw in DIAGNOSTICS_KEYWORDS):
        specialists.append(AgentRole.DIAGNOSTICS)
    if any(kw in query for kw in REMEDIATION_KEYWORDS):
        specialists.append(AgentRole.REMEDIATION)

    return {**inputs, "specialists": specialists}

triage_routing_chain = RunnableLambda(_route)

Step 3 — Dual-Mode Specialist Agents

Each specialist extends a base class. Same interface, different backends:

class BaseSpecialistAgent(ABC):
    async def run(self, query, shared_context, correlation_id, client=None):
        if client is not None:
            return await self._run_on_foundry(query, shared_context, correlation_id, client)
        return await self._run_locally(query, shared_context, correlation_id)

    async def _run_on_foundry(self, query, shared_context, correlation_id, client):
        agent = await client.agents.create_agent(
            model=shared_context.get("model_deployment", "gpt-4o"),
            name=f"{self.role.value}-{correlation_id}",
            instructions=self.system_prompt,
            tools=self._get_foundry_tools(shared_context),
        )
        thread = await client.agents.threads.create()
        await client.agents.messages.create(
            thread_id=thread.id,
            role="user",
            content=self._build_prompt(query, shared_context),
        )
        run = await client.agents.runs.create_and_process(
            thread_id=thread.id,
            agent_id=agent.id,
        )
        # extract and return response...

    async def _run_locally(self, query, shared_context, correlation_id):
        # subclass implements with LangChain tools
        ...

Step 4 — FastAPI Endpoint

from fastapi import FastAPI
from azure.coordinator import Coordinator
from models import TriageRequest

app = FastAPI(title="Incident Triage Copilot")
coordinator = Coordinator()


@app.post("/triage")
async def triage(request: TriageRequest):
    return await coordinator.triage(
        request=request,
        client=app.state.foundry_client,
        max_turns=10,
    )

The app also implements /responses, which follows the OpenAI Responses API protocol — the interface Microsoft Foundry Hosted Agents expects when routing traffic to your container.


Deploying to Microsoft Foundry

# Install the azd AI agent extension
azd extension install azure.ai.agents

# Provision infrastructure and deploy
azd up

azd up provisions:

  • Azure Container Registry for your Docker image
  • Container App with health probes and auto-scaling
  • User-Assigned Managed Identity (no API keys in your code)
  • Microsoft Foundry Hub and Project with model deployments
  • Application Insights for distributed tracing

Agent Configuration (agent.yaml)

name: incident-triage-copilot-langchain
kind: hosted
model:
  deployment: gpt-4o
identity:
  type: managed
tools:
  - type: bing_grounding
    enabled: true
  - type: code_interpreter
    enabled: true

Feature Comparison

Capability LangChain Only LangChain + Microsoft Agent Framework
Local development ✅ Identical experience
Live web search Custom integration required ✅ Built-in BingGroundingTool
Code execution Custom sandboxing required ✅ Built-in CodeInterpreterTool
Managed hosting DIY containers ✅ Foundry Hosted Agents
Authentication DIY ✅ Managed Identity
Observability DIY ✅ OpenTelemetry + App Insights
One-command deploy azd up

Resources


Contributing

Pull requests are welcome. For major changes please open an issue first to discuss what you would like to change. Ensure tests pass in local mode before submitting.

License

See LICENSE for details.

About

Creating langchain specialized agents and deploy using Azure Agent Framework

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages