This program, Blog Writer, is designed to research and write blog posts. It was written with Microsoft Agent Framework and the principal actors are the BloggerAgent which works as the orchestrator, the ResearcherAgent which goes out to the Web (and to Microsoft Learn) to research the requested topic, the AuthorAgent which then writes the blog post, and the ReviewerAgent which reviews the proposed blog post, sending it back to the AuthorAgent if it is not approved.
Note: BlogWriter was written as a demonstration program and is not ready for production.
BlogWriter.Web provides an authenticated Interactive Server Blazor workspace over
the same workflow and Cosmos session store. It includes separate draft and reviewer
panes, prompt and revision inputs, numbered saved-session recall, bounded cancellation,
and responsive WCAG 2.2 AA-oriented controls. The compact Min and Max fields between
the prompts and content panes set the target word range for new drafts and revisions;
they default to 1000 and 2000 words. Workflow progresss below the buttons.
Reviewer feedback is displayed in the window when the draft is rejected.
It is cleared when starting New or loading another
session or modifying the current query.
In List mode, enter the one-based session number beside List to restore the
saved MainTask and optional CurrentSubTask and launch it immediately. For now, the ? command
shows and copies the HTTPS launch command. The query field is editable after
New, while Revise becomes available once a draft/session exists.
After configuring Microsoft Entra, Foundry, and Cosmos values from docs/configuration.md, start it with:
dotnet run --project BlogWriter.Web/BlogWriter.Web.csprojThe original console remains available with dotnet run --project BlogWriter.csproj.
The 4 agents are deployed as independent Azure AI Foundry Hosted Agents
(Foundry Agent Service), each with its own managed compute, dedicated
Microsoft Entra ID identity, and OpenAI-compatible /responses endpoint. The
console app does not build the agents in-process — it only
orchestrates them locally via the MAF Workflow in BlogWorkflow.cs,
calling each hosted agent as a remote IChatClient
using the Microsoft Agent Framework Foundry integration.
BlogWriter/ (console app — orchestration only, calls hosted agents remotely)
HostedAgents/
Blogger/ (Foundry Hosted Agent — orchestration decisions)
Researcher/ (Foundry Hosted Agent — owns hosted web search)
Author/ (Foundry Hosted Agent — drafts/revises the post)
Reviewer/ (Foundry Hosted Agent — approves or requests revisions)
Each HostedAgents/<Name> project is deployed independently via azd (see
its own README) and is pre-provisioned — the console app only references
already-deployed hosted agents by name, it never creates or updates them at
runtime.
Set via dotnet user-secrets (preferred for local dev) or environment
variables — Entra ID (AzureCliCredential) is used for local Foundry/model
auth, no API keys:
| Key | Required | Default | Notes |
|---|---|---|---|
FOUNDRY_PROJECT_ENDPOINT |
yes | — | e.g. https://<account>.services.ai.azure.com/api/projects/<project> |
AZURE_TENANT_ID |
yes | — | Microsoft Entra tenant hosting the Foundry project |
BLOGGER_AGENT_NAME |
no | Blogger |
Name of the deployed hosted agent |
RESEARCHER_AGENT_NAME |
no | Researcher |
|
AUTHOR_AGENT_NAME |
no | Author |
|
REVIEWER_AGENT_NAME |
no | Reviewer |
|
MAX_TOTAL_TOKENS |
no | 40000 |
Cumulative process-wide cap (TokenCapChatClient) |
COSMOS_ENDPOINT |
yes | cosmos endpoint |
|
COSMOS_DATABASE_NAME |
yes | blogWriter |
|
COSMOS_CONTAINER_NAME |
yes | container name |
- docs/architecture.md — full architecture, workflow graph, auth, and token-budget details.
- docs/deployment.md — the
azdflow for deploying/redeploying each hosted agent and running the console app locally. - docs/configuration.md — every environment variable/secret used by the console app and the four hosted agents.
- Web search runs inside the hosted Researcher agent through Foundry's hosted web-search tool.
- Foundry/model access uses Microsoft Entra ID exclusively; the console app authenticates with
AzureCliCredential. - The model deployment is chosen per hosted agent (via
AZURE_AI_MODEL_DEPLOYMENT_NAMEin eachHostedAgents/<Name>project), not hardcoded in the console app.
- Middleware is used to manage the tools.
- OpenTelemetry is used to manage logging and emits a GenAI span per model round-trip.
- ChatOptions sets the temperature to 0 for maximum consistency.