Deep Research Solution with Microsoft Agent Framework

Building a Deep Research Solution with Microsoft Agent Framework

The problem this solves

Cloud LLMs are capable but carry real constraints — data privacy, network latency, and per-call cost — that rule them out of many scenarios. Local small models sidestep those constraints but historically lacked the development, evaluation, and orchestration tooling to build anything serious.

Microsoft Foundry Local paired with the Agent Framework (MAF) closes that gap. This guide builds a complete Deep Research agent that runs locally, walking the full pipeline: safety evaluation, workflow orchestration, interactive debugging, and observability.

Why Foundry Local

Foundry Local is a local model runtime that carries Microsoft’s AI ecosystem to the edge. Its advantages are the ones that matter when the cloud is off the table:

  • Privacy — data and inference stay local, which helps with strict compliance requirements.
  • Latency — no network round trips, so it suits real-time interaction.
  • Cost — no per-call API fees, which matters for high-frequency workloads.
  • Iteration speed — local development and debugging shortens the feedback loop.

The agent surface mirrors what you’d write against a cloud model:

agent = FoundryLocalClient(model_id="qwen2.5-1.5b-instruct-generic-cpu:4").as_agent(
    name="LocalAgent",
    instructions="""You are an assistant.

Your responsibilities:
- Answering questions and providing professional advice
- Helping users understand concepts
- Offering users different suggestions
""",
)

Three ways to evaluate the agent

The Agent Framework samples cover three complementary evaluation methods:

  1. Red Teaming (safety and robustness). Run systematic adversarial prompts across high-risk categories to test the agent’s safety boundaries.
  2. Self-reflection (quality). Add a reflection round after output, where the agent reviews its own answer for factual consistency, coverage, citation completeness, and structure, then produces a revised version.
  3. Observability (performance). Measure end-to-end latency, per-stage timing, and tool-call overhead through metrics and distributed tracing.

Step 1: Red Team evaluation

Establish the safety baseline before anything ships. MAF provides Red Teaming out of the box, driven by Microsoft Foundry:

# 01.foundrylocal_maf_evaluation.py
from azure.ai.evaluation.red_team import AttackStrategy, RedTeam, RiskCategory
from azure.identity import AzureCliCredential
from agent_framework_foundry_local import FoundryLocalClient

credential = AzureCliCredential()
agent = FoundryLocalClient(model_id="qwen2.5-1.5b-instruct-generic-cpu:4").as_agent(
    name="LocalAgent",
    instructions="""You are an assistant...""",
)

def agent_callback(query: str) -> str:
    async def _run():
        return await agent.run(query)
    response = asyncio.get_event_loop().run_until_complete(_run())
    return response.text

red_team = RedTeam(
    azure_ai_project=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
    credential=credential,
    risk_categories=[
        RiskCategory.Violence,
        RiskCategory.HateUnfairness,
        RiskCategory.Sexual,
        RiskCategory.SelfHarm,
    ],
    num_objectives=2,
)

results = await red_team.scan(
    target=agent_callback,
    scan_name="Qwen2.5-1.5B-Agent",
    attack_strategies=[
        AttackStrategy.EASY,
        AttackStrategy.MODERATE,
        AttackStrategy.CharacterSpace,
        AttackStrategy.ROT13,
        # ... other strategies
    ],
    output_path="Qwen2.5-1.5B-Redteam-Results.json",
)

The scan combines risk categories (violence, hate/unfairness, sexual content, self-harm) with attack strategies (encoding obfuscation, character substitution, prompt injection, and more), and produces risk scorecards with response samples.

Step 2: the Deep Research workflow

The core of Deep Research is a research-judge-research loop, expressed as an MAF workflow with three components:

  1. Research agent — carries a search_web tool for live retrieval; summarizes each round, flags knowledge gaps, and accumulates context to avoid repeat searches.
  2. Iteration controller — judges whether the information is complete enough, decides continue-vs-report, and caps the round count to prevent infinite loops.
  3. Final reporter — integrates every iteration into a structured, cited report.
from agent_framework import WorkflowBuilder
from agent_framework_foundry_local import FoundryLocalClient

workflow_builder = WorkflowBuilder(
    name="Deep Research Workflow",
    description="Multi-agent deep research workflow with iterative web search"
)

workflow_builder.register_executor(lambda: StartExecutor(state=state), name="start_executor")
workflow_builder.register_executor(lambda: ResearchAgentExecutor(), name="research_executor")
workflow_builder.register_executor(lambda: iteration_control, name="iteration_control")
workflow_builder.register_executor(lambda: FinalReportExecutor(), name="final_report")
workflow_builder.register_executor(lambda: OutputExecutor(), name="output_executor")

# ... Register agents and add edges ...

workflow_builder.add_edge(
    "iteration_control",
    "research_executor",
    condition=lambda decision: decision.signal == ResearchSignal.CONTINUE,
)
workflow_builder.add_edge(
    "iteration_control",
    "final_report",
    condition=lambda decision: decision.signal == ResearchSignal.COMPLETE,
)

The edges make the loop explicit: CONTINUE routes back to research, COMPLETE routes to the report.

Step 3: DevUI for debugging

Agent debugging is usually a black box. MAF DevUI visualizes the whole run:

python 02.foundrylocal_maf_workflow_deep_research_devui.py
# DevUI starts at http://localhost:8093

It shows the workflow topology (nodes and edges), step-by-step execution with each node’s input, output, and status, real-time parameter injection for testing scenarios, and aggregated logs across all agents and tool calls.

Step 4: telemetry and optimization

For production, wire up observability. MAF integrates with OpenTelemetry and .NET Aspire:

# Configure OpenTelemetry
export OTLP_ENDPOINT="http://localhost:4317"

Track the metrics that drive optimization: end-to-end latency, local model inference time, tool-call overhead (external search, for instance), and memory usage as context accumulates across iterations.

Takeaways

Local small models can back production-grade agent workflows. This build demonstrates the four pieces that make that true: Red Team evaluation to hold the safety line, workflows to keep multi-step logic clear, DevUI for immediate feedback, and Aspire telemetry to make optimization evidence-based.

This entry was posted in . Bookmark the permalink.