Key facts
| Plugsky endpoint | POST https://api.plugsky.com/v1/chat/completions |
| C# setup | AddOpenAIChatCompletion(modelId, apiKey, endpoint: new Uri(…)) |
| Python setup | OpenAIChatCompletion(ai_model_id=…, async_client=AsyncOpenAI(base_url=…)) |
| Function calling | Kernel functions are exposed through the OpenAI tools array |
| Structured output | JSON mode via response_format, or prompt with an explicit JSON schema |
| Models | 30+ models; plugsky-lite for plugins and plugsky-pro for planning and synthesis |
| Deployment | Run Semantic Kernel in your app tier; the API stays OpenAI-compatible |
| Product status | Live; assistants and responses endpoints are coming soon |
TL;DR
- One endpoint parameter connects Semantic Kernel to Plugsky.
- C# and Python both accept a custom OpenAI-compatible URL.
- Kernel functions, plugins and prompt templates are unchanged.
- Use JSON mode plus prompt schemas for structured output.
- Keep planning loops bounded and log per-function token usage.
How it works, step by step
- Add the Semantic Kernel package for your language (NuGet or pip).
- Export PLUGSKY_API_KEY and pick a model such as plugsky-pro.
- In C#, register the chat service with the Plugsky endpoint and key.
- In Python, build an AsyncOpenAI client with the Plugsky base URL and wrap it in OpenAIChatCompletion.
- Invoke a prompt and confirm the response before adding plugins.
- Register kernel functions and let the model call them through function calling.
- Add timeouts, retries and structured logging around every invocation.
Try it yourself
C#: register Plugsky as a chat service
The C# connector takes a model id, key and endpoint, so the change is one builder call:
using Microsoft.SemanticKernel;
var builder = Kernel.CreateBuilder();
builder.AddOpenAIChatCompletion(
modelId: "plugsky-pro",
apiKey: Environment.GetEnvironmentVariable("PLUGSKY_API_KEY")!,
endpoint: new Uri("https://api.plugsky.com/v1"));
var kernel = builder.Build();
var result = await kernel.InvokePromptAsync(
"Summarise this incident report in three bullets.");
Console.WriteLine(result);Registering the service once in your DI container is enough. Rebuild only when configuration changes — the underlying HTTP handler pools connections and should be reused.
Python: wrap a custom client
The Python connector accepts an AsyncOpenAI instance, which is where the Plugsky base URL goes:
from openai import AsyncOpenAI
from semantic_kernel import Kernel
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion
client = AsyncOpenAI(
api_key="sk-live-…",
base_url="https://api.plugsky.com/v1",
)
service = OpenAIChatCompletion(
ai_model_id="plugsky-pro",
async_client=client,
)
kernel = Kernel()
kernel.add_service(service)
result = await kernel.invoke_prompt(
"Classify this support ticket: low, medium or high priority")
print(result)Create one client and one service per process. The connector reuses the client's connection pool, and creating new clients per request is a common source of avoidable latency.
Plugins and function calling
Semantic Kernel turns annotated methods into kernel functions, and the model calls them through the OpenAI tools schema. C# example:
using System.ComponentModel;
public class DocsPlugin
{
[KernelFunction, Description("Search internal documentation")]
public string Search(string query) => SearchIndex(query);
}
kernel.Plugins.AddFromType<DocsPlugin>();Two rules keep plugin loops safe. First, expose only the functions a task needs — every extra function is a way for the model to drift. Second, treat plugin return values as untrusted text: sanitize before injecting them back into the conversation, and never let a plugin output become a shell command or a SQL fragment without validation. For structured outputs, request JSON mode and parse against a schema; if validation fails, retry once with the error before falling back to a human review path.
Planners, orchestration and production
Semantic Kernel's planners compose multiple functions into a plan. Plans multiply model calls, so cost and latency grow with plan depth — cap steps and prefer deterministic orchestration (explicit code paths) when the sequence is known in advance. Reserve planner-driven flows for genuinely open-ended tasks.
In production, wrap every invocation with a timeout, retry 429 and 5xx responses with backoff, and log the kernel function name, model id and token usage per call. Plugsky errors follow the OpenAI schema, which makes structured logging straightforward: message, type, code and param map to fields your observability stack already understands. Assistants and responses endpoints are coming soon, so keep orchestration state inside your application today.
Honest comparison
| Capability | Plugsky + Semantic Kernel | SK with Azure OpenAI | Custom orchestration |
|---|---|---|---|
| Setup | Endpoint and key override | Azure deployment configuration | Write the client yourself |
| Auth | Bearer sk-live-… | Azure keys or Entra ID | Your own auth |
| Model choice | 30+ models behind one endpoint | Azure catalogue and deployments | Whatever you integrate |
| Functions | Kernel functions via OpenAI tools | Native function calling | Hand-built dispatch |
| Regions | Region pin plus private deployment options | Azure regions and data zones | You control |
| Ops | Managed API | Managed service | You operate it all |
Frequently asked questions
Does Semantic Kernel support custom OpenAI-compatible endpoints?
Yes. The C# connector accepts an endpoint parameter, and the Python connector accepts a custom AsyncOpenAI client with a base URL.
Which Plugsky model should I use with SK?
plugsky-pro is a good default for planning and synthesis; plugsky-lite handles high-volume plugin calls at lower cost.
Do plugins and kernel functions still work?
Yes. Kernel functions are exposed through the OpenAI function-calling schema, and tool-capable Plugsky models invoke them normally.
How do I get structured output?
Use JSON mode through response_format, or instruct the prompt to follow a JSON schema and validate the result before use.
How should I handle plans and cost?
Cap planner steps and prefer deterministic orchestration when the sequence is known. Log token usage per kernel function.
Can I use both Azure OpenAI and Plugsky?
Yes. Register two chat services and select per operation or per tenant; the Kernel supports multiple services.
What about errors and retries?
Plugsky returns OpenAI-schema errors. Retry 429 and 5xx with exponential backoff, honor Retry-After, and set explicit request timeouts.
Are assistants and threads available?
They are coming soon on Plugsky. Keep conversation and plan state in your own store for now.