Creating langchain specialized agents and deploy using Azure 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.
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.
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.
- Python 3.10+
- Azure CLI + Azure Developer CLI (
azd) - Microsoft Foundry access (for cloud deployment)
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 srcOpen http://localhost:8080 to interact with the copilot via the built-in web UI.
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.
pytestTests run entirely in local mode — no cloud credentials required.
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"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)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
...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.
# Install the azd AI agent extension
azd extension install azure.ai.agents
# Provision infrastructure and deploy
azd upazd 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
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| 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 |
- Microsoft Agent Framework (
azure-ai-agents) - Microsoft Foundry Hosted Agents
- Azure Developer CLI (
azd) - LangChain Documentation
- Sample Repository
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.
See LICENSE for details.