Semantic Kernel code interpreter without Azure: a sandbox plugin
Wrap Runtime's sandbox functions with kernel_function into a KernelPlugin, and a Semantic Kernel agent runs code in a microVM.
On Runtime a Semantic Kernel agent gets a code sandbox without an Azure
subscription. Semantic Kernel's built-in SessionsPythonTool runs Python in
Azure Container Apps dynamic sessions, which means a session pool, its
management endpoint and role assignments before the first cell runs. A Runtime
sandbox needs a pip install and one browser approval, and gives the agent a
whole Firecracker microVM with a shell, not only Python cells. It starts in
351 ms at the median (24 September 2026) and costs $0.03125 an hour for 2 vCPU
and 4 GiB while the model is thinking. semantic-kernel 1.44.1 was the current
PyPI release on 25 September 2026.
Built-in plugin or Runtime plugin
| Question | SessionsPythonTool |
Runtime plugin |
|---|---|---|
| Where code runs | An Azure Container Apps dynamic session | A Runtime Firecracker microVM |
| Setup before first run | Resource group, session pool, pool endpoint, Session Executor role | pip install withruntime and a browser approval |
| What the agent can do | Run Python code | Run any shell command, read, write, list files |
| Credentials in your app | Azure identity (DefaultAzureCredential in Microsoft's tutorial) |
A Runtime key, or the machine's saved connection |
| State | The same session across calls from one tool instance | The same sandbox for the life of your block |
The Azure column follows Microsoft's own tutorial for the Python SDK, updated 14 April 2026, which also advises a separate kernel and tool per end user so each user gets their own session.
Build the plugin
In Python, kernel_function marks a function for the kernel and reads its
signature. Applied to the four Runtime functions, it produces a plugin whose
functions the agent can call:
Terminalpip install semantic-kernel withruntimePythonfrom semantic_kernel.agents import ChatCompletionAgentfrom semantic_kernel.functions import KernelPlugin, kernel_functionfrom withruntime import AsyncRuntimefrom withruntime.tools import sandbox_toolsasync def solve(service, task: str) -> str: async with AsyncRuntime() as runtime: async with await runtime.sandboxes.create(timeout_seconds=900, on_lease_end="stop") as sbx: plugin = KernelPlugin(name="runtime", functions=[kernel_function(f) for f in sandbox_tools(sbx)]) agent = ChatCompletionAgent( service=service, name="engineer", instructions="Use the runtime plugin to run code in a Linux sandbox. Check exit codes.", plugins=[plugin], ) response = await agent.get_response(messages=task) return str(response.content)service is any chat completion service, for example
OpenAIChatCompletion(ai_model_id=...) or AzureChatCompletion(). Because the
sandbox is an AsyncSandbox, the four functions are coroutines and never block
the event loop. The model sees them as runtime-runtime_exec,
runtime-runtime_read_file and so on, the plugin name joined to the function
name.
This agent ran on 25 September 2026 against semantic-kernel 1.44.1 with a
scripted OpenAI-style endpoint: the agent called runtime_exec, got the exit
code and output, and answered from them.
How many tool calls the agent may make
A ChatCompletionAgent built this way uses automatic function calling. In
1.44.1 its default allows five automatic invocation rounds per response. For a
longer task, such as install, run, fix and rerun, pass your own behavior:
Pythonfrom semantic_kernel.connectors.ai.function_choice_behavior import FunctionChoiceBehaviorbehavior = FunctionChoiceBehavior.Auto(maximum_auto_invoke_attempts=15)# ChatCompletionAgent(..., function_choice_behavior=behavior)Continue a conversation in the same sandbox
get_response returns a thread. Pass it back and the agent remembers the
conversation, while the sandbox remembers the files and installed packages:
Pythonfrom semantic_kernel.agents import ChatCompletionAgentasync def two_turns(agent: ChatCompletionAgent) -> str: first = await agent.get_response(messages="Write primes.py that prints primes under 100, then run it.") second = await agent.get_response(messages="Now make it take the limit as an argument.", thread=first.thread) return str(second.content)Both turns work on /workspace/primes.py in one machine.
Security settings that hold even if the model is tricked
Semantic Kernel filters can inspect a function call before it runs, which is a good place for policy. The sandbox adds limits no prompt can talk its way past, because the host enforces them outside the microVM:
network={"internet": False}on the create for pure computation, or anallowlist of hosts for package installs.timeout_secondsandon_lease_end="stop", so an abandoned conversation does not keep a machine running.max_cost_micros, which refuses the create if its first lease would cost more than you set.- A daily spending limit on the application's key. Past it, creates fail with
spending_limit_reachedand nothing is charged. - Runtime secrets for any token the code needs: the sandbox sees a placeholder, and the real value is added on requests to the named hosts only.
Which to use
Choose SessionsPythonTool when the application already runs on Azure, uses
Azure identity throughout, and Python cells are enough. Choose the Runtime
plugin when the agent must work outside Azure, needs a shell, pip, apt or
Docker (sudo enable-docker), or the team wants a price billed on CPU used:
$0.025 per vCPU-hour and $0.0075 per GiB-hour, with no plan fee
(pricing).
See also a code interpreter for chatbots, code interpreter and the framework guide. New accounts get 50 free sandbox hours, no card:
Terminalnpx withruntime sandbox run --trial -- python3 -c 'print(6 * 7)'Related
Sources
- Microsoft Learn: Use code interpreter sessions in Semantic Kernel with Azure Container Apps, updated 14 April 2026, read 25 September 2026
- Microsoft Learn: Provide native code to your agents, read 25 September 2026
- Microsoft Learn: The ChatCompletionAgent, read 25 September 2026
- semantic-kernel on PyPI, version 1.44.1;
KernelPluginand the default function choice behavior were read from that release's source on 25 September 2026
Facts on this page were checked on 25 September 2026.