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. That requires 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. It gives the agent a
whole Firecracker microVM with a shell, not only Python cells. It costs
$0.03125 an hour for 2 vCPU and 4 GiB while the model is thinking.
semantic-kernel 1.45.0 was the current PyPI release on 25 October 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. That tutorial also advises a separate kernel and tool for each 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. The
agent can call the plugin's functions:
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(). The sandbox
is an AsyncSandbox, so the four functions are coroutines. They never block
the event loop. The model sees them as runtime-runtime_exec,
runtime-runtime_read_file and so on. Each name is 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.45.0, 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 that thread back, and the agent keeps the
conversation. The sandbox keeps 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 the same machine.
Security settings that hold even if the model is tricked
Semantic Kernel filters can inspect a function call before it runs. That is a good place for policy. The sandbox adds limits that no prompt can get around, 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_total_cost_micros, which stops the sandbox once its total cost reaches the value 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. The real value is added only on requests to the named hosts.
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 when the team wants billing by 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. A new account gets 100 free hours of a 1 GB machine in its first 30 days, with no card:
Terminalprintf '%s\n' 'print(sum([125, 250, 375]))' > invoice.pynpx withruntime sandboxes run -- python3 - < invoice.pyRelated
Sources
- Microsoft Learn: Use code interpreter sessions in Semantic Kernel with Azure Container Apps, updated 14 April 2026, read 25 October 2026
- Microsoft Learn: Provide native code to your agents, read 25 October 2026
- Microsoft Learn: The ChatCompletionAgent, read 25 October 2026
- semantic-kernel on PyPI, version 1.45.0;
KernelPluginand the default function choice behavior were read from that release's source on 25 October 2026
Facts on this page were checked on 25 October 2026.