If you’re running Semantic Kernel against Azure OpenAI and need to switch semantic kernel azure openai n4n.ai, the work is mostly a configuration swap. Semantic Kernel’s OpenAI connector speaks the standard OpenAI HTTP contract, so pointing it at an OpenAI-compatible gateway requires no changes to your plugins, prompt templates, or function-calling logic. This guide gives you ordered steps to cut over cleanly and verify the result.
Step 1: Audit your existing Azure OpenAI integration
Before changing anything, capture how your kernel is built. A typical Python setup looks like this:
import os
from semantic_kernel import Kernel
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
kernel = Kernel()
kernel.add_service(
AzureChatCompletion(
deployment_name="gpt-4o",
endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
api_key=os.environ["AZURE_OPENAI_API_KEY"],
)
)
Note three things: the deployment_name (Azure’s alias for a model), the endpoint host, and the auth key. Azure couples a deployment to a specific model version and region. You’ll replace all three. If you also use embeddings, find AzureTextEmbedding and record its deployment name.
Review any plugins that hard-code the deployment string. Semantic Kernel lets you pass service_id when registering; if your code references kernel.get_service("azure-gpt4o"), you’ll need to update those identifiers after the swap.
Step 2: Upgrade Semantic Kernel and OpenAI client
Make sure you’re on a recent release. The OpenAI connector stabilized in 1.x and properly supports custom base URLs via an injected client.
pip install --upgrade semantic-kernel openai
Check the version:
python -c "import semantic_kernel; print(semantic_kernel.__version__)"
Anything >= 1.10 handles async OpenAI clients and base-URL overrides without monkey-patching. If you’re still on 0.x, the class names differ and you should upgrade first—the migration below assumes 1.x APIs.
Step 3: Repoint the chat service to the OpenAI-compatible endpoint
Create an AsyncOpenAI client with the new base URL and hand it to OpenAIChatCompletion. This is the core of the switch semantic kernel azure openai n4n.ai move:
import os
from openai import AsyncOpenAI
from semantic_kernel import Kernel
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion
client = AsyncOpenAI(
api_key=os.environ["N4N_API_KEY"],
base_url="https://api.n4n.ai/v1",
)
kernel = Kernel()
kernel.add_service(
OpenAIChatCompletion(
ai_model_id="gpt-4o",
async_client=client,
)
)
The endpoint exposes a single OpenAI-compatible surface that addresses 240+ models, so ai_model_id is the raw model name rather than an Azure deployment alias. You can swap "gpt-4o" for "claude-3-5-sonnet" or any other supported ID without creating new resources. The auth header format is identical to OpenAI’s (Authorization: Bearer), so your key handling stays the same.
Step 4: Map model IDs and environment variables
Azure deployments obscure the underlying model. Build a small translation layer if you have multiple services or tests that reference old aliases:
MODEL_MAP = {
"azure-gpt4o": "gpt-4o",
"azure-gpt35": "gpt-3.5-turbo",
}
def build_kernel(model_alias: str) -> Kernel:
client = AsyncOpenAI(
api_key=os.environ["N4N_API_KEY"],
base_url="https://api.n4n.ai/v1",
)
kernel = Kernel()
kernel.add_service(
OpenAIChatCompletion(
ai_model_id=MODEL_MAP[model_alias],
async_client=client,
)
)
return kernel
Delete AZURE_OPENAI_ENDPOINT and AZURE_OPENAI_API_KEY from your environment files. If you use a .env file, replace those lines with N4N_API_KEY=.... For container deployments, update the secret references in your Helm chart or Terraform so no stale Azure creds linger.
Step 5: Preserve streaming and function calling
Semantic Kernel’s higher-level APIs (invoke, invoke_stream, function plugins) don’t care which backend serves the tokens. Existing code keeps working:
from semantic_kernel.connectors.ai.open_ai import OpenAIChatPromptExecutionSettings
settings = OpenAIChatPromptExecutionSettings(
temperature=0.2,
tool_choice="auto",
)
async def run():
result = await kernel.invoke(
prompt="Summarize the Q3 infra incident in 3 bullets.",
settings=settings,
)
print(result)
Streaming requires no extra flags:
async for chunk in kernel.invoke_stream(prompt="Draft a rollback plan"):
print(chunk, end="")
If you previously relied on Azure’s response_format for JSON mode, the OpenAI-compatible gateway passes it through. Test both streaming and non-streaming paths before declaring success. Function calling with @kernel_function decorators behaves identically because the wire format is the OpenAI schema.
Step 6: Verify the migration
Write a throwaway script that exercises the exact model ID and a known prompt:
import asyncio
import os
from semantic_kernel import Kernel
from openai import AsyncOpenAI
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion
async def main():
client = AsyncOpenAI(
api_key=os.environ["N4N_API_KEY"],
base_url="https://api.n4n.ai/v1",
)
kernel = Kernel()
kernel.add_service(
OpenAIChatCompletion(ai_model_id="gpt-4o", async_client=client)
)
resp = await kernel.invoke(prompt="Reply with the single word: OK")
assert "OK" in str(resp), f"Unexpected response: {resp}"
print("Verification passed")
asyncio.run(main())
Run it with a real key:
N4N_API_KEY=sk-... python verify_switch.py
A clean pass means tokens flowed end to end. Check your metering dashboard to confirm per-token usage is recorded against the expected model. If you see 401, your key is wrong; 404 means the model ID isn’t supported at that endpoint; 429 means upstream rate limits—handle with retry backoff.
Step 7: Remove Azure-only dependencies
Uninstall the Azure SDK if nothing else needs it:
pip uninstall azure-identity azure-ai-openai
Grep your codebase for AzureChatCompletion and AzureOpenAITextEmbedding. Replace embeddings similarly:
from semantic_kernel.connectors.ai.open_ai import OpenAITextEmbedding
kernel.add_service(
OpenAITextEmbedding(
ai_model_id="text-embedding-3-small",
async_client=client,
)
)
If you use Semantic Kernel’s planning libraries (e.g., FunctionCallingStepwisePlanner), they only depend on the service interface, so no changes are required there.
Step 8: .NET equivalent
For C# teams, the same swap applies. Replace AddAzureOpenAIChatCompletion with AddOpenAIChatCompletion and set BaseAddress:
using Microsoft.SemanticKernel;
var builder = Kernel.CreateBuilder();
builder.AddOpenAIChatCompletion(
modelId: "gpt-4o",
apiKey: Environment.GetEnvironmentVariable("N4N_API_KEY"),
httpClient: new HttpClient { BaseAddress = new Uri("https://api.n4n.ai/v1") }
);
var kernel = builder.Build();
The Microsoft.SemanticKernel.Connectors.OpenAI package already supports custom base addresses; no Azure package is needed post-migration.
Pitfalls and opinions
- Don’t keep both clients in production. Dual-write branches rot. Cut over atomically behind a config flag if you must canary, but delete the Azure path within a sprint.
- Model behavior differs across providers. Even with the same model ID, system prompt handling and tokenizers vary. Run your eval suite, not just a smoke test.
- Cache keys. If you used Azure’s
x-ms-useragentor regional pinning, those hints are meaningless at the new endpoint. The gateway forwards provider cache-control hints, so setcache_controlon messages as you would with OpenAI. - Rate limits. Azure limits are per-deployment; the gateway aggregates upstream quotas. Expect different 429 shapes. Configure
AsyncOpenAIwithmax_retriesand exponential backoff. - Logging. Azure SDK logs differ from OpenAI’s. Update your log filters so 4xx errors from the new endpoint aren’t swallowed by old Azure-specific handlers.
Final check
After the cutover is complete, your kernel construction should contain zero Azure* imports. Your prompts, plugins, and planners stay untouched. That’s the payoff of building against the OpenAI abstraction in Semantic Kernel rather than the cloud-specific one. Run your full integration test suite once more, then decommission the Azure resource to stop billing.