Dev.to AI 🤖 Ai 👁 0 📖 20 min read

Inside the Microsoft Foundry Agent Endpoint: Versions, Canary Rollouts, and Publishing to Teams & Copilot

Inside the Microsoft Foundry Agent Endpoint: Versions, Canary Rollouts, and Publishing to Teams & Copilot The problem: your agent works great in the playground, then production asks a harder question You bui

Inside the Microsoft Foundry Agent Endpoint: Versions, Canary Rollouts, and Publishing to Teams & Copilot

Inside the Microsoft Foundry Agent Endpoint: Versions, Canary Rollouts, and Publishing to Teams & Copilot

The problem: your agent works great in the playground, then production asks a harder question

You built a prompt agent in Microsoft Foundry. It works. You've iterated on the instructions a dozen times, bolted on a file search tool, tightened the system prompt, and the playground conversation looks great. Now someone from the Teams platform team asks the question that actually matters:

"When we ship v2 of this agent next sprint, how do we roll it out without breaking the 400 people already using it in Teams? And who's allowed to call it — can a random intern in another department invoke our internal compliance agent through the Copilot store?"

If your mental model of "deploying an agent" stops at "I hit publish in the portal," you don't have good answers to either question. Microsoft Foundry's agent runtime solves this with a surprisingly rich object model: every agent has a stable endpoint, every change to instructions/tools/model creates an immutable version, and a configurable version selector decides which version actually answers a given request — including canary-style traffic splits. Layered on top of that is a multi-protocol endpoint that can speak four or five different wire formats simultaneously, and a publish pipeline that turns an agent into a first-class citizen inside Microsoft Teams and Microsoft 365 Copilot, complete with admin approval workflows and tenant-wide authorization.

This article is a deep technical walkthrough of that object model — the part of Foundry Agent Service that nobody notices until they try to ship an agent to real users and roll out version 2 without an incident.

Why this matters

Most Foundry content focuses on what an agent does — tools, instructions, RAG, voice, evaluation. That's necessary but insufficient. The thing that separates a demo from a production system is the lifecycle plumbing around the agent: how you version it, how you roll out a change safely, how callers authenticate, and how you expose the same logical agent across multiple surfaces (a REST client, an A2A peer agent, an MCP tool consumer, and a human in Microsoft Teams) without maintaining four separate deployments.

Foundry's answer is architecturally interesting because it decouples identity (the agent and its stable endpoint) from content (a specific version's instructions, model, and tools) from transport (which protocol a caller uses) from authorization (who's allowed to call it). Understanding how those four axes compose is the difference between confidently shipping agent updates on a Tuesday afternoon and being afraid to touch a "working" agent ever again.

Table of contents

  • Core concepts: the agent object model
  • Architecture: how a request actually reaches a version
  • Version routing: always-latest vs. pinned vs. canary
  • The protocol surface: five doors into the same agent
  • Authorization schemes: who gets to knock
  • Implementation walkthrough: configuring the endpoint
  • Publishing to Microsoft Teams and Copilot
  • What happens at runtime when a Teams message arrives
  • Production scenario: a phased rollout for a support agent
  • Production considerations
  • Security considerations
  • Performance and scalability considerations
  • Cost considerations
  • Common mistakes and pitfalls
  • Alternatives and trade-offs
  • Practical recommendations
  • Conclusion
  • References

Core concepts: the agent object model

Foundry's documentation describes four nested entities, and it's worth internalizing the hierarchy because almost every operational question about agents maps to one of these layers.

Foundry project — a logical container that groups related resources: agents, files, connections, and tool configurations. Think of it as the unit of RBAC scoping and billing attribution.

Agent — the stable, consumer-facing identity. This is what gets a name, an icon, a description, and — critically — a URL that never changes. Consumers bind to the agent, not to a version.

Agent version — an immutable snapshot. Every time you touch the system prompt, swap the model, add a tool, or change a toolbox binding, Foundry doesn't mutate the existing agent — it mints a new version. Version 1 still exists, frozen, forever (or until you garbage-collect it). This is the same append-only mental model you'd use for container image tags or Lambda function versions, applied to agent configuration.

Agent endpoint — the thing a caller actually connects to. It has a URL pattern like:

https://{account}.services.ai.azure.com/api/projects/{project}/agents/{agent}/endpoint/protocols/{protocol}

The endpoint is live from the moment you create the agent — there is no separate "deploy" step the way there is with, say, an Azure Function slot swap. What does require configuration is which version answers requests on that endpoint, which protocols are enabled, and which authorization schemes gate access.

This separation matters because it lets you solve four independent problems independently:

  1. "Which config answers requests?" → version selector
  2. "What wire format does the caller speak?" → protocol configuration
  3. "Who's allowed to call it?" → authorization schemes
  4. "Where does my agent show up?" → publishing (Teams, Copilot, Agent 365, or just your own app calling the endpoint directly)

Below is the full picture end to end:

Microsoft Foundry agent endpoint object model showing projects, agents, versions, the version selector, and protocol fan-out to Teams, Copilot, and A2A/MCP clients

Architecture: how a request actually reaches a version

When a request lands on an agent endpoint, Foundry's runtime performs, conceptually, four sequential checks before any model inference happens:

  1. Protocol negotiation — the request path tells Foundry which protocol handler to invoke (responses, activityprotocol, invocations, a2a, or mcp). Each protocol has its own request/response shape, but they all terminate at the same underlying agent runtime.
  2. Authorization check — the configured scheme(s) for that protocol are evaluated. A single endpoint can have multiple authorization schemes active simultaneously (e.g., Entra for your internal app and BotServiceRbac for the Teams channel), and the runtime picks the scheme that matches the inbound credential type.
  3. Version resolution — the version_selector is evaluated against the resolved agent to determine which immutable version's instructions, model binding, and tool configuration will actually process this turn.
  4. Session/isolation key resolution — for protocols like Entra auth, the caller's identity (or a custom user_isolation_key / chat_isolation_key header) determines which conversation state partition this request reads and writes to.

Only after all four of these resolve does the request actually reach the model and tool-calling loop. This means you can change version routing or add a new authorization scheme without touching conversation state, and you can expose a new protocol without creating a new agent.

Version routing: always-latest vs. pinned vs. canary

The version_selector object supports a short but powerful set of routing rules. The default, when you create an agent, is Always use latest — 100% of traffic goes to whatever version was most recently created. This is fine for early development, actively dangerous in production: it means a teammate editing a system prompt in the portal at 4:58pm on a Friday immediately changes behavior for every live user, with no review gate.

The alternative is pinned routing, expressed as a FixedRatio rule:

{
  "agent_endpoint": {
    "version_selector": {
      "version_selection_rules": [
        {
          "type": "FixedRatio",
          "agent_version": "2",
          "traffic_percentage": 100
        }
      ]
    }
  }
}

The FixedRatio type name is a strong hint about where this is headed: because it's a ratio, not a boolean pin, you can define multiple rules whose traffic_percentage values sum to 100 and split traffic across versions — the same pattern you'd use for a canary deployment of a microservice, applied to agent configuration instead of container images. A conservative rollout for a new system prompt might look like 95% of traffic still pinned to version 4 (known-good) and 5% routed to version 5 (candidate), monitored through Foundry's tracing and continuous evaluation pipeline before promoting to 100%.

This is a meaningful architectural decision: Microsoft chose to model version rollout as a traffic-splitting problem rather than a blue-green swap problem. That buys you gradual exposure and statistical confidence before a full cutover, at the cost of needing to reason about two versions' worth of behavior being live concurrently — including handling the case where a multi-turn conversation starts on version 4 and a later turn gets routed to version 5 mid-conversation (in practice, conversation-level session affinity generally keeps a given thread on a consistent version, but you should verify this for your protocol and not assume it blindly for stateful tool-calling flows).

The protocol surface: five doors into the same agent

An agent endpoint isn't single-protocol. You can enable several simultaneously:

Protocol Purpose Typical caller
Responses OpenAI-Responses-API-compatible request/response Your own backend, SDKs
Activity Protocol Bot Framework activity schema Microsoft Teams, Microsoft 365 Copilot
Invocations Lightweight invocation-style calling convention Lightweight integrations, some hosted-agent-to-agent calls
A2A (v1.0 GA / v0.3 preview) Agent-to-Agent protocol Other agents (including non-Foundry agents) treating yours as a peer
MCP (preview) Model Context Protocol server surface MCP-compatible clients that want to call your agent as a tool

The practical implication: the same instructions, model binding, and tool configuration in a single agent version can be reached by a human typing in Teams (via Activity Protocol), your own web app (via Responses), a sibling agent orchestrating a multi-agent workflow (via A2A), and a completely different AI system treating your agent as an MCP tool — all without duplicating the agent or its logic. You're not building "a Teams bot" and "an API" and "an agent" as three separate projects; you're exposing one governed piece of agent logic through protocol adapters.

This is also why the earlier article in this series on Responses vs. Invocations protocols solved a narrower problem (which calling convention fits your app's request/response pattern) — this endpoint model is the superset: it's the governance and multi-surface layer that sits above protocol choice.

Authorization schemes: who gets to knock

Three authorization scheme types gate inbound calls, and you can run more than one simultaneously on the same endpoint:

Entra — Microsoft Entra ID token-based auth. The caller needs at least the Foundry Agent Consumer role (read: "can call agents") or Foundry User (can also create/manage) on the project or agent scope. Identity resolution can come from the Entra token itself, or from custom user_isolation_key / chat_isolation_key headers when you need to partition conversation state independently of the authenticated principal (useful for multi-tenant SaaS wrapping a single Foundry agent).

BotServiceRbac — layers Azure Bot Service channel authorization on top of Azure RBAC. Only identities with the right Azure permissions to call the agent can invoke it through the bot channel. This is configured automatically when you publish with Individual (formerly "Shared") scope.

BotServiceTenant — tenant-wide Bot Service authorization: anyone in your Entra tenant can invoke the agent once an M365 admin approves it. Configured automatically for Organization scope publishing.

Notably: API key authentication is not supported on agent endpoints. If you're coming from a world of static API keys for service-to-service calls, this is a deliberate hardening decision — every caller authenticates with Entra ID or goes through the Bot Service channel trust chain. There is no bearer secret to leak in a config file.

Implementation walkthrough: configuring the endpoint

Here's a realistic, production-oriented sequence: pin a known-good version, then enable multiple protocols with layered authorization, using the Python SDK.

from azure.ai.projects import AIProjectClient
from azure.identity import DefaultAzureCredential
from azure.ai.projects.models import (
    AgentEndpointConfig,
    FixedRatioVersionSelectionRule,
    VersionSelector,
    ProtocolConfiguration,
    ResponsesProtocolConfiguration,
    ActivityProtocolConfiguration,
    A2AProtocolConfiguration,
    EntraAuthorizationScheme,
    BotServiceRbacAuthorizationScheme,
)

PROJECT_ENDPOINT = "https://{account}.services.ai.azure.com/api/projects/{project}"
AGENT_NAME = "support-triage-agent"

project_client = AIProjectClient(
    endpoint=PROJECT_ENDPOINT,
    credential=DefaultAzureCredential(),  # Managed identity in prod, az login locally
)

with project_client:
    # Step 1: Canary rollout — 90% of traffic stays on the known-good v4,
    # 10% is routed to the new candidate v5 so we can watch evaluation
    # metrics and traces before promoting it fully.
    endpoint_config = AgentEndpointConfig(
        version_selector=VersionSelector(
            version_selection_rules=[
                FixedRatioVersionSelectionRule(agent_version="4", traffic_percentage=90),
                FixedRatioVersionSelectionRule(agent_version="5", traffic_percentage=10),
            ]
        ),
        # Step 2: Expose both a direct API surface (Responses) and the
        # Teams/Copilot surface (Activity) on the same endpoint.
        protocol_configuration=ProtocolConfiguration(
            responses=ResponsesProtocolConfiguration(),
            activity=ActivityProtocolConfiguration(),
            a2a=A2AProtocolConfiguration(),
        ),
        # Step 3: Internal callers use Entra; Teams/Copilot callers use
        # the Bot Service channel trust chain. Both are valid simultaneously.
        authorization_schemes=[
            EntraAuthorizationScheme(),
            BotServiceRbacAuthorizationScheme(),
        ],
    )

    patched_agent = project_client.agents.update_details(
        agent_name=AGENT_NAME,
        agent_endpoint=endpoint_config,
    )
    print(f"Endpoint configured for '{patched_agent.name}': "
          f"90/10 canary split, Responses + Activity + A2A enabled.")

A few things worth calling out about this snippet:

  • It's idempotent-ish: re-running it simply re-applies the same desired state, which is exactly the property you want if this lives in a CI/CD pipeline rather than being run by hand.
  • The canary split and the protocol/authorization configuration are set in a single PATCH — but conceptually they're independent concerns, and you'll often change one without the other (e.g., promoting the canary to 100% later touches only version_selector).
  • Because this is a few lines of SDK code, it belongs in version control next to your agent's instructions — not as a one-off portal click that nobody can reproduce.

The equivalent raw REST call, useful if you're wiring this into a pipeline that doesn't have Python available (e.g., a GitHub Actions step using curl + an Entra token):

curl -X PATCH \
  "https://{account}.services.ai.azure.com/api/projects/{project}/agents/support-triage-agent?api-version=v1" \
  -H "Authorization: Bearer $(az account get-access-token --resource https://ai.azure.com --query accessToken -o tsv)" \
  -H "Content-Type: application/merge-patch+json" \
  -d '{
        "agent_endpoint": {
          "version_selector": {
            "version_selection_rules": [
              { "type": "FixedRatio", "agent_version": "4", "traffic_percentage": 90 },
              { "type": "FixedRatio", "agent_version": "5", "traffic_percentage": 10 }
            ]
          }
        }
      }'

Publishing to Microsoft Teams and Copilot

Publishing is a distinct operation from endpoint configuration — it's the process that turns your agent into an installable app in the Microsoft 365/Teams agent store. Here's what Foundry actually does under the hood when you click Publish → Teams and Microsoft Copilot (or call the equivalent REST API):

  1. Validation of the metadata you supply — display name, version string (semantic: major.minor.patch), short/long descriptions, developer info, and optional terms-of-use/privacy URLs.
  2. Manifest compilation — Foundry generates a Teams app manifest (manifest.json + icon-color.png + icon-outline.png) packaged as a .zip, matching the Microsoft 365 app manifest schema.
  3. Azure Bot Service provisioning — a Bot Service resource (and its channel registration) is created or reused in your resource group. This requires Microsoft.BotService/botServices/write permission — the Azure Bot Service Contributor role grants exactly this.
  4. Protocol + auth activation — the activity protocol is enabled on the endpoint, and either BotServiceRbac (Individual scope) or BotServiceTenant (Organization scope) authorization is configured automatically.
  5. Catalog submission — the manifest is submitted to the Microsoft Copilot/Teams agent catalog.

Scope selection is the governance lever here:

  • Just you / Individual scope — live immediately, no admin approval, visible only to you under "Your agents" (shareable via link to specific users).
  • People in your organization / Organization scope — requires a Microsoft 365 admin to approve the request in the admin center before it appears under "Built by your org" for the whole tenant.

Here's the full flow visually:

Sequence diagram of publishing a Microsoft Foundry agent to Teams and Copilot, showing manifest compilation, Azure Bot Service provisioning, admin approval branch, and the runtime call path back through the Activity protocol

One operational detail that trips people up: publishing and version routing are decoupled. Once an agent is published, you do not need to republish to Teams/Copilot when you ship a new agent version — you only need to update the version_selector (or just create a new version while "Always use latest" is active). The stable endpoint URL baked into the Teams manifest never changes; only what answers behind it changes. The one time you do need to touch the publish flow again is when you update consumer-facing metadata (display name, description, icons) — that goes through "Update agent Teams and Microsoft Copilot display properties," which auto-increments the manifest version.

If your project disables public network access, the portal publish flow won't work — you instead enable a source-IP-filtered public Activity Protocol route via enable_m365_public_endpoint on the REST API, which restricts inbound Activity traffic to Azure Bot Service and Microsoft 365 source IP ranges while keeping the rest of your project's network perimeter locked down.

What happens at runtime when a Teams message arrives

It's worth tracing a single message end to end, because the layering explains several "why does it work this way" questions developers hit in practice.

  1. A user types a message to your agent inside Teams.
  2. Teams/M365 routes this through the Azure Bot Service channel associated with your agent.
  3. Bot Service delivers an Activity-shaped payload to your agent's endpoint at the .../protocols/activityprotocol path.
  4. The endpoint evaluates authorization — BotServiceRbac or BotServiceTenant depending on publish scope — which is a channel-level trust check, not a per-user Entra token the way a direct API caller would present.
  5. The version_selector resolves which agent version handles this turn (normally "Always use latest" for a Teams-published agent unless you've deliberately pinned it).
  6. The resolved version's instructions, model, and tools run the normal agent loop — tool calls, file search, code interpreter, whatever the version is configured with — identical to how it would behave if called via the Responses protocol.
  7. The response activity is translated back through the Bot Service channel into a Teams-rendered message.

The key insight: steps 5 and 6 are completely protocol-agnostic. The same version that answers a Teams message would answer a direct Responses API call identically, because the protocol layer is purely a transport/auth adapter sitting in front of one shared runtime. This is why you can develop and evaluate an agent entirely through the Responses API or the portal playground, then publish to Teams with confidence that you're not introducing a second, divergent code path.

Production scenario: a phased rollout for a support agent

Consider a concrete, realistic rollout for an internal IT-support agent already live in Teams for 2,000 employees, where you want to ship a new tool (a ticket-escalation function) without a big-bang cutover:

  1. Author the new instructions/tool configuration — Foundry mints version 7 automatically (version 6 is the current production version, serving via "Always use latest" or pinned explicitly — you should move to explicit pinning before this rollout if you haven't already).
  2. Patch the version_selector to a FixedRatio split: 95% v6, 5% v7.
  3. Let the 5% soak for a day. Foundry's observability pipeline (tracing + continuous evaluation, covered in Day 10 of this series) gives you tool-call accuracy and task-adherence scores per version — filter traces by agent_version to compare v6 vs. v7 side by side.
  4. If evaluation scores hold and no new error patterns show up in tracing, shift to 50/50 for another day, then 100% v7.
  5. If something regresses, you roll back by repatching version_selector to 100% v6 — a config change, not a redeploy, and nothing about the Teams manifest or Bot Service registration needs to be touched.

Note what you didn't have to do: no new Teams app submission, no new admin approval cycle, no changes to the authorization scheme, and zero downtime for the other 95% (then 50%, then 0%) of users on the stable version throughout.

Production considerations

  • Pin before you scale. "Always use latest" is a reasonable default while iterating solo, but the moment a second person can create a version — or the agent is published externally — switch to explicit pinning or ratio-based rollout. Treat an unreviewed prompt edit the same way you'd treat an unreviewed code push to main.
  • Separate the "who can edit" role from "who can route traffic" role. Prompt engineers creating versions don't necessarily need permission to re-point the version selector in production; consider scoping Foundry RBAC roles accordingly (Foundry User vs. Foundry Agent Consumer vs. Foundry Project Manager).
  • Watch session affinity assumptions. Multi-turn, stateful tool-calling conversations interacting with a mid-rollout canary split deserve explicit testing — confirm how your protocol and client handle a conversation thread if the ratio shifts mid-conversation, rather than assuming it.
  • Version sprawl. Every edit — including a one-character prompt typo fix — mints a new immutable version. Over months this can produce dozens of versions per agent; have a retention/cleanup policy and tag/document what each production-relevant version changed.

Security considerations

  • No API keys, by design. Every caller must present either an Entra token or go through the Bot Service channel trust chain. This closes off the most common agent-security failure mode in other platforms: a leaked static key with broad privileges.
  • Isolation keys need deliberate design. If you're using user_isolation_key/chat_isolation_key headers to partition conversation state for a multi-tenant wrapper app, that header is only as trustworthy as the system generating it — make sure it's derived from your own authenticated session, never from client-supplied, unvalidated input.
  • Organization-scope publishing is a real trust boundary, not a checkbox. Once approved, any user in the tenant can invoke the agent — including whatever tools and data access it has. Review what the agent's tools can reach (internal APIs, file stores, databases) with the same scrutiny you'd apply to approving a new enterprise app registration, because that's functionally what it is.
  • Data residency and M365 processing. Publishing to Teams/Copilot means Microsoft 365 services store and process agent metadata and conversation responses under M365's own compliance boundaries — factor this into data-residency and compliance review before publishing agents that handle regulated data.

Performance and scalability considerations

  • Canary analysis needs enough volume. A 5% traffic split on a low-traffic internal agent might mean single-digit requests per day hit your candidate version — too little signal to trust before promoting. Scale your canary percentage to your actual traffic volume, not a fixed convention.
  • Protocol fan-out doesn't multiply compute cost per request — a given request is handled by exactly one protocol adapter and one resolved version; enabling four protocols doesn't mean four times the inference cost, it means four possible entry doors into the same backend.
  • Bot Service channel latency is additive. Activity Protocol traffic hops through Azure Bot Service before reaching your agent endpoint; for latency-sensitive support scenarios, measure end-to-end (Teams client → Bot Service → Activity Protocol → agent runtime → back) rather than assuming Responses-API-measured latency transfers directly.

Cost considerations

  • Publishing itself (Bot Service resource + channel registration) has its own Azure Bot Service cost dimension, separate from Foundry model/token consumption — budget for it independently, especially if you provision one Bot Service resource per published agent.
  • Canary rollouts mean you're paying for inference against two versions concurrently during the soak period — typically negligible next to full-rollout cost, but worth noting if your candidate version uses a materially more expensive model than the baseline.
  • There's no separate charge for enabling additional protocols on an endpoint; cost is driven by request volume and model/tool usage per resolved version, not by how many protocol doors are open.

Common mistakes and pitfalls

  • Assuming "publish" means "deploy." The agent endpoint is live at creation; publishing to Teams is a distribution action layered on top, not the thing that makes your agent reachable at all.
  • Leaving "Always use latest" active on a tenant-published agent. This means any teammate's version edit instantly changes behavior for every employee in the org with zero review window.
  • Forgetting that Organization-scope publishing requires admin approval. Teams building this into a release pipeline are sometimes surprised the agent doesn't appear the moment the publish API call succeeds — it's pending in the M365 admin center until approved.
  • Treating isolation keys as free-form identity. Passing unvalidated client-supplied isolation headers defeats the purpose of per-user/per-chat state partitioning.
  • Manually editing the downloaded Teams manifest's generated identifiers (id, bots[0].botId, webApplicationInfo.id) — these are service-generated and changing them breaks the package validation Foundry already performed.

Alternatives and trade-offs

If you don't need multi-surface publishing at all — just a backend calling an agent from your own app — you can ignore the entire Teams/Copilot publish pipeline and the Activity Protocol entirely, using only the Responses protocol with Entra auth. That's a legitimate, simpler path and is what most of this series's earlier architecture articles (Responses vs. Invocations, networking, egress policy) implicitly assume.

If you need true peer-to-peer agent collaboration rather than a human-facing surface, the A2A protocol on the same endpoint is the more relevant door than Activity Protocol — worth a dedicated look if you're building multi-agent systems where other agents (potentially non-Foundry ones) need to call yours as a peer rather than a tool.

If your organization already has a mature Bot Framework/Teams app development practice outside Foundry, you could in principle hand-roll your own Bot Service registration and translation layer in front of the Responses API — Foundry's publish flow exists specifically to avoid you having to do that, automating manifest generation, channel registration, and auth wiring that would otherwise be manual Bot Framework SDK work.

Practical recommendations

  • Default new agents to explicit version pinning the moment more than one person can create versions, or the moment the agent is published anywhere outside your own testing.
  • Treat version_selector changes as deployments: put them behind the same review/approval process you'd apply to a production config change, ideally via CI/CD calling the REST API or SDK rather than ad hoc portal clicks.
  • Use ratio-based canary rollout as your default promotion strategy for any agent with real user traffic, sized to your actual request volume.
  • Enable only the protocols you actually need. Each enabled protocol is a surface you're responsible for securing and monitoring — don't turn on A2A or MCP "just in case" without a concrete consumer.
  • For anything beyond personal/pilot use, plan the Organization-scope admin approval step into your release timeline — it's a real dependency on another team, not an automatic step.

Conclusion

The headline features of Microsoft Foundry — tool calling, RAG, evaluation, voice — get most of the attention, but the agent endpoint object model is what makes those features operable by more than one person. Versions give you an audit trail and a rollback button. The version selector gives you canary rollouts for free instead of requiring you to build your own traffic-splitting proxy. Multi-protocol endpoints let one governed agent definition serve a REST client, a Teams user, and a peer agent without three separate deployments. And the publish pipeline turns "my agent" into "the org's supported Teams app" with an explicit, auditable approval gate rather than a shared link nobody tracks.

If you're past the demo stage with a Foundry agent, auditing these four things — version pinning strategy, enabled protocols, authorization schemes, and publish scope — is a higher-leverage exercise than tuning your system prompt one more time.

References

📰 Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.