DoublewordDoubleword
Get started

Microsoft Agent Framework

The Microsoft Agent Framework is Microsoft's SDK for building AI agents and multi-agent systems. It supports custom OpenAI-compatible endpoints natively.

Install

pip install agent-framework-openai agent-framework-core

Configure

from agent_framework import Message
from agent_framework_openai import OpenAIChatCompletionClient
import asyncio

client = OpenAIChatCompletionClient(
    model="{{selectedModel.id}}",
    base_url="https://api.doubleword.ai/v1",
    api_key="{{apiKey}}",
)

async def main():
    messages = [Message(role="user", contents=["Say hello."])]
    response = await client.get_response(messages)
    for content in response.messages[0].contents:
        if hasattr(content, "text") and content.text:
            print(content.text)

asyncio.run(main())

Prompt caching

Agent Framework flattens system messages to a string. The client's message_preparer hook turns them back into a marked block:

from agent_framework_openai import OpenAIChatCompletionClient
import asyncio

def stamp(message, dicts):
    for d in dicts:
        if d.get("role") in ("system", "developer"):
            content = d["content"]
            if isinstance(content, str):
                content = [{"type": "text", "text": content}]
            content[-1]["cache_control"] = {"type": "ephemeral", "ttl": "1h"}
            d["content"] = content
    return dicts

client = OpenAIChatCompletionClient(
    model="{{selectedModel.id}}",
    base_url="https://api.doubleword.ai/v1",
    api_key="{{apiKey}}",
    message_preparer=stamp,
)

agent = client.as_agent(instructions="…large, stable instructions (~1024-token floor)…")

async def main():
    response = await agent.run("What is 2 + 2?")
    print(response.usage_details["cache_read_input_token_count"])

asyncio.run(main())

Use OpenAIChatCompletionClient. OpenAIChatClient targets the Responses API, which does not cache. usage_details reports cache reads but not writes. See the prompt caching guide.

Batch pricing with Autobatcher

For background tasks where latency is not critical, use Autobatcher to transparently route requests through the Batch API at reduced cost:

pip install agent-framework-openai agent-framework-core autobatcher
from autobatcher import BatchOpenAI
from agent_framework import Message
from agent_framework_openai import OpenAIChatCompletionClient
import asyncio

batch_client = BatchOpenAI(
    api_key="{{apiKey}}",
    base_url="https://api.doubleword.ai/v1",
)

client = OpenAIChatCompletionClient(
    model="{{selectedModel.id}}",
    async_client=batch_client,
)

async def main():
    messages = [Message(role="user", contents=["Say hello."])]
    response = await client.get_response(messages)
    for content in response.messages[0].contents:
        if hasattr(content, "text") and content.text:
            print(content.text)
    await batch_client.close()

asyncio.run(main())

BatchOpenAI is a drop-in AsyncOpenAI subclass that collects requests and submits them as batch jobs automatically, cutting inference costs by up to 90%.

Available clients

The framework provides three client types, all of which accept base_url and api_key:

ClientEndpoint
OpenAIChatCompletionClient/chat/completions
OpenAIChatClient/responses (Responses API)
OpenAIEmbeddingClient/embeddings

The Doubleword API supports all three endpoints.