Model or dataset
SJTU-IPADS/SkVM avatar
SJTU-IPADS/SkVM

SkVM treats an agent skill as something you compile

The Language Virtual Machine for Agent Skills

565 stars54 forksTypeScriptMIT

At a glance

What is it?
SkVM is a compilation and runtime system for LLM agent skills, from SJTU's IPADS lab, and its premise is that a skill behaves like a program rather than a prompt. You profile what a model and harness can actually do, compile the skill ahead of time against that profile, optimise it at runtime, and benchmark the result across models and conditions.
Who is it for?
Adopt SkVM if you are running agent skills across more than one model or harness and the same skill behaves differently on each, since the profiling step exists to measure that difference rather than guess at it. Skip it if you run one skill on one model, because the setup cost is real, and if your organisation forbids the headless agent usage that the JIT optimisation step performs.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 43 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Skills as programs

The tagline is the whole thesis: compile and run LLM agent skills across heterogeneous models and harnesses.

A skill, in the sense this project means it, is the reusable instruction set an agent follows to do a particular kind of task. That is normally just text. It gets pasted into a prompt, and its behaviour depends entirely on the model reading it, the harness interpreting it, and the tool definitions available at that moment.

The consequence is that a skill that works well in one place can behave differently in another. The same instructions produce different tool calls on a different model, a different harness may expose a different set of primitives, and a skill written for one model may lean on habits that another model does not have.

SkVM's answer is to treat a skill the way a compiler treats a program. There is a target description of what the model and harness can do, there is a compilation step that produces an adapted artefact, there is a runtime optimisation step, and there is a benchmark to check the result against the original.

The reference is a paper, SkVM: Revisiting Language VM for Skills across Heterogenous LLMs and Harnesses, on arXiv. The framing in the title is the interesting part. A language virtual machine is the layer that lets one set of instructions run on many different processors, and this is the same idea applied to skills rather than to bytecode.

The project is TypeScript, MIT licensed, published to npm as @ipads-skvm/skvm, with a website at skillvm.ai and a Chinese README alongside the English one. The last push was on 2026-09-10 and the releases are v0.1.5 from 2026-04-18 and v0.1.4 from 2026-04-17.

Four parts, and each is a separate command

The system is described as having four major parts, and reading them in order tells you the intended workflow.

Profiling is the first. It measures a model plus harness against pre-defined primitive capabilities. So before you compile anything, you establish what the target can actually do: which primitives it can call reliably, what it gets wrong, how it behaves. The output is a capability profile.

AOT-Compilation is the second, compiling a skill with multiple passes in an ahead-of-time compiler. Multiple passes is the detail that matters here. A single-pass transformation would have to be right the first time, and since the target capability profile tells you what a model struggles with, a multi-pass compiler can use that information to rewrite the skill accordingly.

JIT-Optimization is the third and it splits in two. jit-boost improves runtime speed, and jit-optimize improves skill content. The first is a caching and execution concern, and the second is rewriting the skill based on what happened while it ran.

Benchmark is the fourth, evaluating original, compiled and optimized skills across tasks, conditions and models. Note the three-way comparison. A compiled skill that is not measured against the original is just a different skill, and the point of the system is that you can show the compiled one is better.

There is also a proposals concept, mentioned in the skills list as one of the things skvm-general drives. A proposal is the unit of change that jit-optimize produces, and the news section says the metadata records which driver produced each proposal for replay and audit.

That audit property is worth noticing. An optimiser that rewrites a skill based on observed behaviour is producing changes that affect what your agent does. Being able to replay a proposal and see what it was and which driver made it is a precondition for trusting the system with anything important.

Installing, and a deliberately isolated runtime

There are two install routes and they are chosen by platform.

bash
# curl one-liner (macOS / Linux)
curl -fsSL https://skillvm.ai/install.sh | sh

# or via npm (any platform with Node ≥ 18; postinstall fetches the matching binary)
npm i -g @ipads-skvm/skvm

The curl one-liner is macOS and Linux. The npm route works on any platform with Node 18 or newer, and the postinstall script fetches the matching binary.

The installer drops a standalone binary at ~/.local/share/skvm/bin/skvm and symlinks it into ~/.local/bin/skvm. It also bundles a private, isolated headless agent runtime used internally by skvm jit-optimize, and the documentation is emphatic that it is fully self-contained and does not touch any agent or CLI you may have installed globally.

That isolation is a design decision with a practical reason behind it. The JIT optimisation step runs an internal coding agent, and that agent needs to be somewhere. If it used your installed coding agent, it would inherit its configuration, its credentials and its permissions, and a tool that rewrites skills would be running with the same access as your working setup. Bundling a private runtime keeps the blast radius small.

The skills section makes the same point from the other side. There is a skvm-jit skill, which is a post-task JIT optimisation skill for submitting conversation logs to skvm jit-optimize, and there is a skvm-general skill, which drives profile, aot-compile, bench and proposals on behalf of a user.

So the tool ships two skills for your agent to use, and you copy them into your harness's skills directory:

bash
# OpenClaw
cp -r ~/.local/share/skvm/skills/skvm-jit ~/.openclaw/workspace/skills/
cp -r ~/.local/share/skvm/skills/skvm-general ~/.openclaw/workspace/skills/

# Hermes Agent
cp -r ~/.local/share/skvm/skills/skvm-jit ~/.hermes/skills/
cp -r ~/.local/share/skvm/skills/skvm-general ~/.hermes/skills/

# pi Agent
mkdir -p ~/.pi/agent/skills
cp -r ~/.local/share/skvm/skills/skvm-jit ~/.pi/agent/skills/
cp -r ~/.local/share/skvm/skills/skvm-general ~/.pi/agent/skills/

Three harnesses are shown. OpenClaw uses ~/.openclaw/workspace/skills/, Hermes Agent uses ~/.hermes/skills/, and pi uses ~/.pi/agent/skills/.

The division between the two skills is the interesting design. skvm-general is the ordinary interface: it exposes profiling, compilation, benchmarking and proposals to your agent as tools it can call. skvm-jit is the automatic one: it fires after a task and submits the conversation log for optimisation.

That second one is the more interesting of the pair, because it means the improvement loop runs without you asking. The news section records the switch that made it practical: since 2026-05-18, jit-optimize and jit-boost run their internal coding agent via the pi coding agent in-process by default, with OpenCode remaining a first-class peer that you select with headlessAgent.driver set to opencode in skvm.config.json.

Configuration, adapter modes and model identifiers

The quick start is an interactive wizard:

bash
skvm config init

That configures the agent harness, the provider and the API key, and it writes $SKVM_CACHE/skvm.config.json, defaulting to ~/.skvm/skvm.config.json. For non-interactive setups, the documentation points at docs/providers.md.

The adapter config mode is the part that decides how much of your machine the system touches. External harnesses run in one of two modes, managed or native, with managed the default.

In managed mode, SkVM provisions a fresh, minimal config inside the sandbox, such as a new OpenClaw agent or a generated hermes config.yaml. The stated property is a clean baseline with no reliance on host state.

In native mode, SkVM clones the user's existing harness config, such as an OpenClaw source agent under ~/.openclaw/agents/<name> or a Hermes active profile, and the harness has to be set up locally first.

That default is a considered choice rather than an accident. A profiling or optimisation run that inherits your live agent configuration picks up whatever state that agent has, and the results then describe a system you cannot reproduce. A clean baseline gives you numbers that mean the same thing every time.

The native mode exists because sometimes the harness configuration is the thing you actually want to measure. If you are asking which of your three production agents handles a skill best, you need to profile them as they are, not as fresh defaults.

The model identifier format is the other thing to get right, since it appears on every command line. Model parameters take the form of a provider and a model id, where the leading provider selects the model service provider and the model id is how that provider refers to the model. For OpenRouter that is three segments, for example openrouter/qwen/qwen3.5-35b-a3b, and for the Anthropic native API it is two, for example anthropic/claude-sonnet-4.6.

The two-level scheme means the same skill can be pointed at different providers without rewriting it, which is the portability claim in practice.

The profiling command writes a target capability profile to ~/.skvm/profiles/, and there is a shortcut for people who do not need to measure anything themselves. If the target model and adapter pair is already covered by the pre-built profiles shipped in skvm-data/profiles/, you can copy the cached result into your local profile cache and skip skvm profile entirely:

bash
mkdir -p ~/.skvm/profiles
cp -R skvm-data/profiles

For a project with a small set of supported models, that removes the most expensive step from getting started.

The build machinery and the release model

The package file shows that this is a Bun project that ships a compiled binary rather than a Node library.

The scripts are the giveaway. The dev entry point runs bun run src/index.ts directly. The test script is bun test, and the type check is bunx tsc --noEmit. The binary build is a single bun build with the compile and minify flags, and build:all runs a shell script that builds for all targets.

Shipping a compiled binary from a TypeScript project is an unusual choice and it is the right one for a command line tool that people install with curl. It means the tool does not need a JavaScript runtime on the target machine at all, and the bun compile output is a single file.

The npm package is the distribution channel for the other platforms. Its files list is explicit about what ships: the bin directory, two files under install/, the two skill directories, the README and the LICENSE. The bin entry maps the skvm command to ./bin/skvm.js, and the postinstall script is what fetches the matching binary for the platform it is running on.

Those two install files are worth naming, because they explain the mechanism. install/release-host.json and install/opencode-version.json are configuration that the postinstall step reads, and the second one is a pinned OpenCode version, which tells you the system manages the version of the agent runtime it drives.

The dependencies are short and describe the system honestly. There is the Anthropic SDK, and there is the pi coding agent at a pinned 0.67.68, which is the internal agent the JIT commands run. There is smol-toml, which is how the skill content is parsed, and zod for validation. There is yaml for the harness configuration files, and the inquirer packages for the interactive wizard.

The repository layout matches. There is src/, bin/, install/, skills/, docs/, scripts/ and test/, a skvm-data directory holding the pre-built profiles, a skvm.config.example.json, a bunfig.toml and a bun.lock. The .gitmodules file suggests some content is pulled in as submodules, and there is a separate Chinese README plus a CONTRIBUTING.md.

The release tags are v0.1.4 and v0.1.5, so this is a version 0.1 project. That is worth keeping in mind, because a system that rewrites the instructions your agent follows is the kind of thing you would want to run on your own infrastructure and inspect before trusting.

Where this sits against writing a better prompt

The honest comparison is with the thing most people will actually do, which is write a better prompt and test it by hand.

That approach has real advantages. It costs nothing, it needs no infrastructure, and it is fully under your control. If you have one skill on one model, it is almost certainly the right approach, and the profiling step of SkVM would tell you something you already know.

The case for a compilation system appears when the variables multiply. Several models, several harnesses, and a skill whose behaviour you need to predict rather than discover. At that point you are running a compatibility problem, and a compatibility problem is exactly what a compiler is for.

There is a second case that the news section points at: a skill that improves over time based on what happens while it runs. A human rewriting a skill after reading ten transcripts is slow and inconsistent, and it does not scale. An automated optimiser does, provided you can trust it and provided you can see what it changed.

That proviso is where the design choices show. The proposal metadata records which driver produced each change, for replay and audit. The managed adapter mode gives a clean baseline so the measurements are comparable. The bundled private runtime keeps the optimiser away from your own tooling. Those are all choices aimed at a system that changes behaviour, and they are the right ones to look for when you are judging whether to trust it.

The limits are honest ones. The version is 0.1. The JIT step runs an agent on your behalf, and the news section warns that heavy headless usage may hit account rate limits or usage-terms issues, which is a real constraint when the provider is the one charging you.

There is also a browser route, since you can upload and optimise a skill with SkVM in your browser from the website. That is a sensible way to try the idea without installing anything, and it is also a reason to be careful: a skill you upload is a skill you have handed to somebody else's service.

So the decision comes down to scale. One skill, one model, hand-written and hand-tested is better than a compiler. Many skills across many models, with an evidence trail of what changed and why, is what this is built for.

Editorial conclusion

Adopt SkVM if you are running agent skills across more than one model or harness and the same skill behaves differently on each, since the profiling step exists to measure that difference rather than guess at it. Skip it if you run one skill on one model, because the setup cost is real, and if your organisation forbids the headless agent usage that the JIT optimisation step performs. Verify first which harness you are targeting and which adapter mode fits, and that the model identifier format matches your provider, since the provider prefix selects the service.

Frequently asked questions

What is SkVM and what does it do?

It is a compilation and runtime system that makes LLM agent skills portable across heterogeneous models and harnesses. It has four major parts: profiling, which measures a model and harness against pre-defined primitive capabilities; AOT compilation, which compiles a skill with multiple passes in an ahead-of-time compiler; JIT optimization, which improves runtime speed with jit-boost and skill content with jit-optimize; and benchmarking, which evaluates original, compiled and optimized skills across tasks, conditions and models.

How do I install SkVM and how do I install its agent skills?

On macOS or Linux you can run `curl -fsSL https://skillvm.ai/install.sh | sh`, and on any platform with Node 18 or newer you can install it with `npm i -g @ipads-skvm/skvm`, where the postinstall fetches the matching binary. The installer drops the binary at ~/.local/share/skvm/bin/skvm, symlinked into ~/.local/bin/skvm, and bundles a private isolated headless agent runtime. The two agent-facing skills are then copied into your harness's skills directory, for example ~/.openclaw/workspace/skills/ for OpenClaw, ~/.hermes/skills/ for Hermes Agent and ~/.pi/agent/skills/ for pi.

What are the managed and native adapter modes in SkVM?

External harnesses run in one of two modes, with managed the default. In managed mode SkVM provisions a fresh, minimal config inside the sandbox, such as a new OpenClaw agent or a generated hermes config.yaml, giving a clean baseline with no reliance on host state. In native mode SkVM clones the user's existing harness config, such as an OpenClaw source agent under ~/.openclaw/agents/<name> or a Hermes active profile, and the harness has to be set up locally first.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. SJTU-IPADS/SkVM on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/sjtu-ipads-skvm.svg)](https://hysenlabs.com/projects/sjtu-ipads-skvm)

Was this useful?