The Microsoft 365 Agent SDK Is Not Optional
Update: 2025-11-20
Description
Why DIY Agents Fail in M365 Ecosystems
Become a supporter of this podcast: https://www.spreaker.com/podcast/m365-show-podcast--6704921/support.
Follow us on:
LInkedIn
Substack
- Identity ≠ checkbox. “App-only” where you need act-as-user breaks permission fidelity, nukes audit trails, and fails review. M365 access is identity-bound (files, chats, calendars, mail).
- State is not optional. Scaling from a laptop to multiple nodes without shared conversation + turn state causes amnesia: lost clarifications, tool drift, repeated answers.
- Channel chaos. Teams, web, Slack, Outlook all differ (typing, cards, attachments, streaming). Hand-rolled adapters miss protocol semantics → broken UX and support pain.
- Governance cliff. Ignoring Purview/DLP/eDiscovery = automatic “no.” Labels, retention, legal hold must apply to prompts + outputs.
- Orchestrator sprawl. LangChain here, SK there—no standard execution plan, no retries, no observability → fragile systems.
- Compliance gap. Residency, RBAC, tenant boundaries, cross-tenant routing—DIY rarely inherits org posture.
- Debugging despair. No consistent dev tunnel, no end-to-end traces, no channel-aware streaming → ghost bugs and user distrust.
- Auth + Authorization done right
- Built-in sign-in handlers, consent surfaces, token exchange.
- Act-as-user when needed; fall back to app creds when safe.
- Least-privilege, real audit trails, permission fidelity across Graph/SharePoint/Outlook.
- Durable conversation management
- Thread + turn state that survives clusters/load balancers.
- Correlation IDs, shared storage patterns—multi-turn that actually works.
- Activity protocol + real adapters
- Standard message/event/typing/attachment/card types.
- Adapters for Teams, web chat, Slack, Copilot Studio—native behavior without bespoke glue.
- Orchestrator neutrality
- Plug Semantic Kernel, Azure AI Foundry planners, OpenAI, your own stack.
- Prompts/tools as modular units. Swap models/planners without rewrites.
- Streaming awareness
- Auto-detect channel capability → stream tokens where supported, fall back to typing/chunking where not.
- Dev productivity + diagnostics
- VS/VS Code scaffolds, secure dev tunnels, multi-channel playground.
- End-to-end traces, telemetry hooks, correlation IDs for model/tool/channel latency.
- Open-source, free core
- Pay only for your chosen models/search/storage. Python and C# supported.
- Scaffold the agent
- Create an M365 Agent project with the Echo template.
- Run locally → validate activity flow in the playground. Fix env vars/ports/creds first.
- Wire core handlers
- onMembersAdded (greeting), onMessage (routing), onInvoke (cards/actions).
- Add sign-in handler → consent, code exchange, user-scoped token on the turn.
- Register your orchestrator
- Add SK / Azure AI Foundry / OpenAI via DI.
- Keep prompts in files, tools as functions (typed inputs/outputs). Interface-wrap model calls.
- Persist state
- Use turn/conversation state for chat history, tool outputs, correlation IDs.
- Store state outside process for cross-node continuity.
- Register channels via Azure Bot Service
- ABS as broker → one HTTP endpoint, many channels (Teams, web, Copilot Studio).
- Stop doing bespoke sockets.
- Enable streaming
- Flip SDK streaming on; let adapters auto-negotiate. Stream partials where supported; typing/chunks elsewhere.
- Diagnostics
- Playground to simulate channels, inspect headers/tokens.
- Telemetry with correlation IDs across message → model → tools → response.
- Ship a thin slice
- One prompt + one tool. Use act-as-user for Graph, app creds for external.
- Persist tool results; render final Adaptive Card; verify streaming + audit entries.
- Guardrails
- Tool registry with scopes/roles/labels.
- Planner proposes; policy authorizes. Confirmation for risky actions (send mail, post to Teams).
- Enforce DLP/labels before/after tool calls.
- Automate provisioning
- Scripts for ABS, channel registration, app IDs/secrets, env config.
- Commit prompt files, state schema, tool interfaces.
- Entra identity for agents: real principals, act-as-user, auditable actions.
- Purview everywhere: labels/DLP on prompts + outputs; eDiscovery/retention/holds aligned with mail/docs.
- Defender signals: posture + runtime alerts for agentic systems (prompt injection, exfil, anomalous tools).
- Zero-Trust by design: scoped tokens per turn, policy-gated tools, task-adherence checks.
- Compliance automation: retention on conversations, audit logs per channel, legal hold compatible.
- ❌ Hand-rolled adapters → ✅ SDK adapters (Teams/web/Slack/Copilot Studio).
- ❌ Stateless turns → ✅ Persist conversation/turn state (survive failover).
- ❌ Model logic in handlers → ✅ Abstract cognition (swap planners/models freely).
- ❌ App-only everywhere → ✅ Sign-in + act-as-user for Graph-bound actions.
- ❌ Fake streaming → ✅ SDK streaming with graceful fallbacks.
- ❌ Direct sockets per channel → ✅ Azure Bot Service as broker.
- ❌ No governance story → ✅ Register identity, apply Purview/DLP, enable audit day one.
- SDK adapters
- Persistent state
- Orchestrator abstraction
- Sign-in (act-as-user)
- Streaming enabled
- ABS registered
- Purview/DLP wired
- Tool catalogs with policy: scopes/roles/labels; confirmations for risky actions; admins gate exports.
- Planner-led skills with resilience: retries, circuit breakers, idempotent tools; keep CoT private; return
Become a supporter of this podcast: https://www.spreaker.com/podcast/m365-show-podcast--6704921/support.
Follow us on:
Substack
Comments
In Channel











