n4nAI

Getting started with Semantic Kernel and n4n.ai

Step-by-step setup for getting started with Semantic Kernel and n4n.ai, including Python code, configuration pitfalls, token metering, and routing across 240+ models.

n4n Team4 min read772 words

Audio narration

Coming soon — every post will get a voice note here.

If you’re building orchestration logic around LLMs, Microsoft Semantic Kernel gives you plugins, planners, and a clean abstraction over chat completions. This guide covers getting started semantic kernel n4n.ai by wiring Semantic Kernel’s OpenAI-compatible connector to a gateway that fronts many providers. You’ll leave with a runnable Python setup and a clear list of tradeoffs.

1. Install and pin dependencies

Semantic Kernel ships as a Python package but moves fast. Pin every dependency in production to avoid silent connector breakage.

python -m venv .venv
source .venv/bin/activate
pip install semantic-kernel==1.10.0 openai==1.40.0 python-dotenv==1.0.1

The connector we use lives in semantic_kernel.connectors.ai.open_ai and wraps the official OpenAI client. If you later need Java or .NET, the same patterns apply, but the class names differ. Keep your kernel construction behind a factory so you can swap implementations during testing.

2. Configure the OpenAI-compatible client

Semantic Kernel’s OpenAIChatCompletion accepts base_url and api_key. Point it at the gateway. n4n.ai exposes one OpenAI-compatible endpoint that addresses 240+ models and applies automatic fallback when a provider is rate-limited or degraded, so a single credential and model string covers most experiments.

import os
from semantic_kernel import Kernel
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion

kernel = Kernel()
chat_service = OpenAIChatCompletion(
    ai_model_id="anthropic/claude-3-haiku",  # gateway-routed model id
    api_key=os.getenv("N4N_API_KEY"),
    base_url="https://api.n4n.ai/v1",
)
kernel.add_chat_service("default", chat_service)

Model IDs are not raw OpenAI names. The gateway uses a catalog that prefixes providers. Fetch the live list during startup or cache it with a TTL. Hardcoding a model that gets renamed will surface as a 404 from the gateway, not a local validation error.

3. Define a native function

Semantic Kernel plugins are Python classes with @kernel_function methods. Type hints become part of the JSON schema sent to the model, so they must be precise.

from semantic_kernel.functions import kernel_function

class MathPlugin:
    @kernel_function(name="add", description="Add two integers")
    def add(self, a: int, b: int) -> int:
        return a + b

kernel.add_plugin(MathPlugin(), "math")

A missing description causes the planner to silently ignore the function. Optional parameters and defaults are not always serialized reliably across connector versions—test each function with a real invocation before trusting it in a planner.

4. Invoke a chat with function calling

Build a ChatHistory and let the model decide whether to call your plugin.

from semantic_kernel.contents import ChatHistory

history = ChatHistory()
history.add_user_message("What is 12 + 30?")
result = await kernel.invoke_chat_completion("default", history)
print(result)

For production, use kernel.invoke with an explicit function or a FunctionCallingStepwisePlanner. The minimal path above skips planning and forces a direct completion. If you expect tool use, set tool_choice via the service’s settings object; otherwise the model may answer from parametric memory and skip your plugin.

5. Model routing and client directives

The gateway honors client routing directives and forwards provider cache-control hints, but Semantic Kernel’s OpenAI connector does not expose arbitrary headers. If you need sticky routing—for example, forcing a specific provider region or avoiding fallback—you must subclass the connector or use a raw OpenAI client for those calls.

Tradeoff: staying inside Semantic Kernel keeps code portable but hides low-level controls. Drop to the raw client only for the 5% of calls that need it, and isolate that code behind an interface so the rest of your app stays agnostic.

6. Streaming and retry policy

Streaming works through the same service object:

stream = kernel.get_chat_service("default").complete_chat_stream(history)
async for chunk in stream:
    print(chunk)

Semantic Kernel passes None for max_retries to the underlying OpenAI client, which means two retries on connection errors but no backoff on HTTP 429 from the gateway. Wrap the service with a custom AsyncOpenAI client configured with max_retries=5 and an exponential backoff. Cancellation tokens are not propagated automatically; if your user closes the tab, you must abort the generator yourself to avoid wasted tokens.

7. Token metering

The gateway provides per-token usage metering. Semantic Kernel surfaces usage only when you call the service directly, not through the high-level invoke helpers:

response = await kernel.get_chat_service("default").complete_chat(history)
print(response.usage)  # prompt_tokens, completion_tokens

Capture response.usage at the service boundary and ship it to your metrics pipeline tagged with the resolved model ID. Don’t trust the requested model name for billing—the gateway may have fallen back to a different provider, and the usage reflects the actual completion.

8. Common pitfalls

Model ID drift. Gateway catalogs change. Validate at startup by fetching the model list, or you’ll discover breaks in production.

Temperature clamping. Some providers reject temperatures outside [0, 1]. Semantic Kernel won’t warn you; the gateway returns an error that looks like a model failure.

Plugin schema strictness. Complex Pydantic models as arguments often serialize incorrectly. Keep plugin inputs flat and primitive.

Cache-control loss. Because the connector doesn’t forward cache hints, you lose semantic cache discounts unless you patch the HTTP layer.

Streaming partial failures. If the gateway switches providers mid-stream, the client may raise after the first token. Handle exceptions inside the async for loop, not just around it.

9. Beyond initial setup

After getting started semantic kernel n4n.ai, add a planner and write evaluation harnesses before shipping. The abstraction is solid, but the moment you need fine-grained provider features—cached prompts, JSON mode variations, or custom stop sequences—you’ll patch the connector. Keep those patches in a single module.

Ship the kernel behind a factory that reads base_url and api_key from environment. That’s the only way to keep staging and prod aligned when the gateway adds new models or changes fallback behavior. Treat the model string as configuration, not code.

Tagssemantic-kerneln4n-aisetupgetting-started

Written by

n4n Team

The team building n4n — a single OpenAI-compatible API in front of 240+ models, with automatic fallback, load balancing and pay-per-token metering.

More from n4n Team →

All semantic kernel getting started with n4n.ai posts →