Skip to main content

Getting Started with AI

Level: Beginner · Time: 45–60 min · Category: Guide

Tags: OpenCode · OpenWork · VS Code · Open WebUI · Agents · Prompting

Work through this once and you will have an API key, an AI assistant that can read and edit your projects, and a sense of how to work with the models we host. Every tutorial on this site starts from here.

You do not need any prior experience with AI tools. You will use a terminal for a handful of commands — each one is written out for you to copy, and there is a short note in Step 1 on how to open one if you never have.

Short on time?

Step 1 and Step 3 are enough to begin any tutorial. Come back for Step 7 when your first few attempts do not go the way you expected — that section explains why.

The four pieces

Four things sit between what you type and the code that comes back. It is worth learning which is which, because when something goes wrong the fix is nearly always in one specific piece.

PieceWhat it isWhere it comes from
1The toolThe program you install and talk to. It reads your files, edits code, and runs commands.You pick one in Step 2.
2Your API keyProves the request is yours. Treat it like a password.The Voyager portal.
3The gatewayThe address requests go to: https://openai.rc.asu.edu/v1. It speaks the OpenAI-compatible protocol, so standard tools work with it unchanged.Research Computing.
4The modelThe AI itself. It interprets your request and decides what should happen next.Runs on RC hardware.

The tool and the model work as a pair: the model decides what should happen — write this file, run this command — and the tool carries it out on your machine, within the permissions you have given it. Both halves are worth keeping in view. A model that cannot call tools will discuss your code happily and never change a line, which is what the Tools badge in Step 1 is about. And the permissions you set on the tool in Step 3b are what bound how far any model can go.

Why does "OpenAI-compatible" matter?

OpenAI published the request format that most AI tools now speak. Our gateway speaks the same format, so a tool built for OpenAI works with our models once you change two settings: the base URL and the API key. That is the whole trick behind every setup on this page, and it means what you learn here transfers to other providers.

Your prompts stay on RC hardware

These models run in our data center, so prompts and code sent through the RC gateway are not passed to a commercial AI provider. Follow your unit's normal data-handling rules for regulated or sensitive data.


Step 1: Get your API key and a model ID

Everything else needs these two values.

  1. Log in to the Voyager portal with your ASURITE credentials.
  2. Open the LLM Access tab.
  3. Click Create Key. Copy the key somewhere safe — treat it like a password.
  4. On the LLMs sub-tab, review the available models and copy one model ID exactly as written (for example muse-glimmer-30b). The ID is what tools want, not the friendly display name.

The LLM Access tab holds more than LLMs — there are sub-tabs for Image, Video, Embeddings, Speech, and Usage, plus the two this guide uses: opencode (a config generator) and Skills (a library of ready-made HPC instructions).

No account yet? LLM API access is free to anyone with an ASURITE username — see Requesting an Account. Full API details, including code samples, are in the LLM API Access guide.

Read the model badges

Each model in the list carries capability badges and a context size. They are easy to scroll past, but they determine what a model can do for you:

BadgeWhat it meansWhy it matters
ToolsThe model can call tools.Required for editing files. Without it, an assistant can discuss your code but never change it.
VisionThe model can read images.Lets you paste a screenshot of a broken layout or a whiteboard sketch.
ReasoningThe model works through a problem before answering.Better on multi-step logic. Worth the extra wait for algorithms and debugging.
131K ctxThe size of its context window.How much text it can hold at once. Larger is more forgiving, though quality tends to drop before you reach the limit — see Step 7.

For coding, start with something that has Tools and Reasoning and a large context — muse-glimmer-30b, glm35-27b, and devstral2-123b all qualify.

Store your key as an environment variable

Do this before anything else that uses the key. An environment variable is a named value your shell hands to every program it launches, so tools can read the key without it ever appearing in a project file, a command, or a screenshot.

Where do I type this? (if you have never used a terminal)

macOS: press Cmd+Space, type "Terminal", press Enter.


Windows: press the Start key, type "PowerShell", press Enter.


Linux: press Ctrl+Alt+T.

A terminal is a place to type commands rather than click buttons. You will use it to install things and to run your projects; the tutorials always give you the exact command.

Open your shell's startup file in a text editor — ~/.zshrc on macOS, ~/.bashrc on most Linux systems:

nano ~/.zshrc     # macOS; use ~/.bashrc on most Linux systems

Add this line at the bottom, pasting your key between the quotes, then save and exit (Ctrl+O, Enter, Ctrl+X in nano):

export OPENAI_API_KEY="paste-your-key-here"

Load it into the terminal you already have open, and confirm:

source ~/.zshrc
echo $OPENAI_API_KEY # should print your key

source re-reads the startup file so you do not have to close and reopen the terminal. New terminals pick it up automatically.

Type the key as few times as possible

Everything you type at a prompt is saved to your shell history in plain text — ~/.zsh_history, ~/.bash_history, or PowerShell's ConsoleHost_history.txt. That is why the steps above put the key in a file you edit, or behind a prompt, rather than in a command you type. For the same reason, avoid pasting it directly into curl commands, code, or anything you might commit or screenshot.

If a key does end up somewhere it should not, regenerate it on the Voyager LLM Access tab. Rotating a key takes seconds and invalidates the exposed one.

Prove it works before installing anything

This checks the key and the model ID on their own. If it fails here, no amount of editor configuration will help, so it is worth thirty seconds now. The key comes from the environment variable you just set, so it stays out of the command:

curl -sS https://openai.rc.asu.edu/v1/chat/completions \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "PASTE-MODEL-ID-HERE",
"messages": [{"role": "user", "content": "Reply with exactly: RC API ok"}]
}'

A JSON response containing RC API ok means you are ready. A 401 means the key is wrong, expired, or not set in this terminal — check echo $OPENAI_API_KEY (echo $env:OPENAI_API_KEY on Windows) first. A model error means the ID does not match the portal.

On a shared machine, such as an HPC login node

Your shell replaces $OPENAI_API_KEY with the actual key before running curl, so the key sits in that command's arguments while it runs — and command arguments are visible to other users on the same machine through ps. The window is brief, but on a shared login node it is real.

To avoid it, hand the header to curl through standard input instead. printf is built into the shell, so no separate process carries the key:

printf 'header = "Authorization: Bearer %s"\n' "$OPENAI_API_KEY" | \
curl -sS --config - https://openai.rc.asu.edu/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model": "PASTE-MODEL-ID-HERE", "messages": [{"role": "user", "content": "Reply with exactly: RC API ok"}]}'

The assistants in this guide read the environment variable directly and never place your key on a command line, so this only applies to ad-hoc curl testing.


Step 2: Choose your tool

All four options below reach the same RC models with the same key. What differs is how much they can do on your behalf and how much of the terminal you have to touch.

ToolSuits you ifEdits your files?InterfaceSetup
OpenCodeYou want the option our tutorials are written against.YesTerminal or desktop app10 min
OpenWorkYou would rather see an agent's plan in a window than a scrolling terminal.YesDesktop app5 min after OpenCode
VS CodeYou already work in an editor and want chat beside your code.Yes, in Agent modeEditor15 min
Open WebUIYou want to think a problem through, or you cannot install anything.NoWebsiteNone

If you have no preference, install OpenCode and add OpenWork afterwards. OpenWork runs OpenCode underneath, so the second setup is mostly done once the first is.

These are not mutually exclusive, and using several is normal: Open WebUI to think a problem through, OpenCode or OpenWork to build it, VS Code to read the resulting changes. They share one key, so nothing is duplicated.


Step 3: Set up OpenCode

OpenCode is a free, open-source AI coding assistant. You describe what you want in plain English; it reads your project, writes and edits files, and runs commands. It has a terminal interface and a desktop app that share the same configuration.

3a. Install it

curl -fsSL https://opencode.ai/install | bash

Or with a package manager:

brew install anomalyco/tap/opencode   # macOS (Homebrew)
sudo pacman -S opencode # Arch Linux

Confirm the install — this should print a version number:

opencode --version

If you get command not found, fully quit and reopen your terminal so it picks up the new command.

3b. Generate your config in Voyager

OpenCode needs a config file telling it where the RC gateway is, which models exist, what agents you have, and what those agents may do. You do not have to write it by hand — Voyager builds it for you, with the endpoint and your account's real model list already filled in.

Go to the Voyager portalLLM Accessopencode tab. The page has four sections, with a live preview of the resulting opencode.json on the right.

Pick a preset

The presets across the top are ready-made teams of agents. Starting from one is easier than assembling your own:

PresetWhat you get
StarterOne primary assistant plus a reviewer. The simplest thing that works.
Full-stackA delegating tech lead with backend, frontend, API design, and two critics.
Data scienceA research lead with an ML engineer, a statistician, and leakage/figure critics.
Scientific computingAn HPC lead with CUDA/MPI implementation, numerics, Slurm, and rigor critics.
Web designA design lead that turns mockups into UI, gated by design and accessibility critics.

Starter is the right choice for the tutorials on this site. Move to a specialized preset once you have a real project: Scientific computing if you work on the clusters, Data science for analysis work.

Set the connection

Most of this section is already filled in. There is one decision to make.

  • Provider key asu and display name ASU Air — leave both alone. Agents refer to models as asu/model-id, so changing the key means changing every reference too.
  • Base URL https://openai.rc.asu.edu/v1 — already correct.
  • API key — choose between Paste key inline and Environment variable.
Choose "Environment variable"

Pasting inline writes your key into the generated file in plain text, which Voyager warns you about on the page. Environment variable makes the config read OPENAI_API_KEY from the environment you set in Step 1 instead, which keeps the file safe to store in a project folder or share with a labmate.

If you do paste inline, keep that file out of Git and regenerate the key if it ever leaks.

Select your models

Tick the models you want available; these become the provider's model list, with the badges from Step 1 shown alongside. Two or three is plenty — a shorter list makes the model picker quicker to use, and you can always regenerate. At least one needs the Tools badge, or nothing will be able to edit files.

Review the agents and permissions

The Agents section lists each agent with its own model, mode (primary or subagent), and tool permissions. Starter gives you assistant (primary, general purpose) and reviewer (subagent, code review). Match models to roles assigns a suitable model to each role from the ones you selected. You can add roles from the dropdown and choose which agent is the default.

Global permissions below set what any agent may do unless it overrides the setting — read, edit, write, bash, webfetch, and so on, each allow, ask, or deny. The defaults are sensible to start with. The one worth noticing is external_directory: deny, which keeps an agent inside your project folder.

Consider setting bash to ask at first

The assistant then pauses for your approval before running any command. It is a little slower, and you will learn a lot about what it is actually doing.

Save the file

Use Copy or Download in the preview panel, then save it to one of these locations:

# Global — RC models and agents available in every project (recommended)
mkdir -p ~/.config/opencode
# save the file as ~/.config/opencode/opencode.json

# Or per-project — save it as opencode.json in your project root

Use the global path for now. Per-project configs become useful later, when one project needs different agents or tighter permissions than the others.

What the generated file looks like

Roughly this shape, with your own models, agents, and permissions:

~/.config/opencode/opencode.json
{
"$schema": "https://opencode.ai/config.json",
"default_agent": "assistant",
"permission": {
"read": "allow",
"edit": "allow",
"bash": "allow",
"webfetch": "allow",
"external_directory": "deny"
},
"provider": {
"asu": {
"npm": "@ai-sdk/openai-compatible",
"name": "ASU Air",
"options": {
"baseURL": "https://openai.rc.asu.edu/v1",
"apiKey": "{env:OPENAI_API_KEY}"
},
"models": {
"muse-glimmer-30b": { "name": "muse-glimmer-30b" }
}
}
},
"agent": {
"assistant": { "mode": "primary", "model": "asu/muse-glimmer-30b" },
"reviewer": { "mode": "subagent", "model": "asu/muse-glimmer-30b" }
}
}

npm: "@ai-sdk/openai-compatible" is the adapter for any OpenAI-compatible gateway. Each key under models must match a Voyager model ID exactly. The field-by-field walkthrough is in the OpenCode setup guide.

3c. Open it and send a test message

mkdir opencode-test
cd opencode-test
opencode

Type /models and press Enter to pick a model under ASU Air, then send:

Reply with exactly: OpenCode is connected to ASU Air.

A normal reply, with no authentication or model-not-found error, means every piece of the chain is working.

Two commands are worth knowing from the start:

  • /models — switch models.
  • /agent — switch between the agents your config defines, which is how you move from assistant to reviewer and back. Step 7 covers why you would.

Now try a real prompt. Note that it asks the assistant to look before touching anything, which is a good default for a first run in any project:

Look at the files in this folder and summarize what this project does. Do not edit anything yet.
This section is the short version

The complete OpenCode walkthrough, with every troubleshooting case, is at Set Up OpenCode with the RC LLM API.


Step 4: Add OpenWork

OpenWork is a free, open-source desktop app for working with AI agents on your own files, available for macOS, Windows, and Linux. It is built on OpenCode, so what you set up in Step 3 carries straight over.

Even if you are comfortable in the terminal, it is worth having. What it adds:

  • A visible plan. The agent's to-do list appears as a live timeline, so you can follow what it intends to do, watch the plan change, and stop it early when it heads somewhere wrong. In a terminal the same information scrolls past you.
  • A workspace. Files, chat, and results side by side rather than interleaved in one stream.
  • Skills and MCP connections configured once and reused across projects.
  • Local-first. Your files stay on your machine.

Install and connect

  1. Download the app for your OS from openworklabs.com/download.
  2. Open it and point it at a project folder.
  3. Open the model picker and choose a model under ASU Air. Because OpenWork runs OpenCode underneath, it reads the same ~/.config/opencode/opencode.json you created in Step 3 — including the agents and permissions Voyager generated for you.

If RC models do not appear, quit and reopen the app so it re-reads the config, and confirm opencode --version and echo $OPENAI_API_KEY both work in a terminal.

A good first task

OpenWork is at its best on multi-step work where you want to see the plan. Try this on a folder that already has a few files in it:

Read every file in this folder and write a README.md that explains what this project is,
how to run it, and what each file does.

Before you write anything, show me your plan as a checklist and wait for me to say go.

The point of the exercise is the checklist. Reading it and correcting it before a single file is written costs you a sentence; correcting the finished work costs a rewrite.

Optional: use OpenWork's shared skills from other tools

OpenWork also publishes an MCP server, which lets other agents reuse the skills and connections you set up in OpenWork. Adding it to OpenCode means adding an mcp block to your opencode.json:

~/.config/opencode/opencode.json (excerpt)
{
"mcp": {
"openwork": {
"type": "remote",
"enabled": true,
"url": "https://api.openworklabs.com/mcp/agent",
"oauth": {}
}
}
}

This is a team-sharing feature and signs you in to an OpenWork account, so it is optional and separate from everything else in this guide. The desktop app works fully without it.


Step 5: Set up VS Code

VS Code is a free code editor. Install it even if you plan to drive OpenCode from the terminal: reading generated code in an editor, with syntax highlighting and a proper diff view, is much easier than reading it scroll past — and reading it is the part where you add the most value.

5a. Install the editor

Download it from code.visualstudio.com and install it like any other application. On first launch, pick a theme and skip the rest of the tour.

5b. Install a few extensions

Open the Extensions panel (Ctrl/Cmd+Shift+X) and install whichever match the tutorials you plan to do:

ExtensionWhy
Python (Microsoft)Runs and debugs Python, picks up your .venv automatically.
Jupyter (Microsoft)Notebooks inside the editor.
ESLint + PrettierJavaScript/TypeScript linting and formatting for the web tutorials.
GitHub Pull RequestsReview pull requests without leaving the editor — used by the Git collaboration tutorial.

5c. Four things worth learning

VS Code has hundreds of features and you can ignore nearly all of them. These four carry the work:

  1. Open a folderFile → Open Folder. Open the project folder, not a single file, because assistants read the folder around a file for context.
  2. The integrated terminalCtrl plus the backtick key opens a terminal inside the editor, already in your project folder. You can run opencode there and have the assistant and your files side by side, which for many people is the entire setup.
  3. Source Control panel — the branch icon in the left bar shows every change made to your project, line by line, with buttons to stage and commit. This is where you review an assistant's work.
  4. Command PaletteCtrl/Cmd+Shift+P runs any command by name, which saves hunting for the button.

5d. Optional: connect VS Code Chat to the RC models

VS Code has its own chat, and it can point at the RC gateway using BYOK (Bring Your Own Key). Worth doing if you would rather have chat inside the editor than a separate assistant.

In short: Command Palette → Chat: Manage Language ModelsAdd ModelsCustom Endpoint, then give it the endpoint https://openai.rc.asu.edu/v1/chat/completions, your API key, and a model ID. The full walkthrough, including the chatLanguageModels.json file VS Code may open, is in Connect VS Code to the RC API.

Editing needs a tool-capable model

VS Code's Agent mode relies on tool calling to change files — the Tools badge from Step 1. If chat answers normally but edits never appear, that is usually the cause. Switch models, or keep VS Code Chat for explanations and let OpenCode do the editing.


Step 6: Use Open WebUI for thinking out loud

ai.rc.asu.edu is our hosted Open WebUI, a ChatGPT-style interface for the same RC models. Log in with ASURITE; there is nothing to install and no key to configure.

It is worth being precise about what it does. Open WebUI cannot read or edit your project files, so it does not replace OpenCode, OpenWork, or VS Code, and you cannot build a tutorial project in it. What it is very good at is the thinking that happens before you open an editor:

  • Shaping a problem. "I want a tool that summarizes lab meeting notes. What are three ways to structure this, with trade-offs?"
  • Getting unstuck. Paste an error message and ask what it means.
  • Understanding code you inherited. Paste a file and ask for a walkthrough.
  • Drafting the prompt you will use elsewhere. Ask it to turn a vague idea into a precise specification, then paste that specification into your coding assistant.

That last one pairs well with the prompt skeleton in Step 7.

Sub-agents

Open WebUI now supports sub-agents: the model can hand a self-contained piece of work to a background helper, which runs its own tool-driven conversation and reports back only its conclusion. It keeps a research-heavy chat readable instead of filling it with intermediate output.

  • Enabling it. An administrator switches sub-agents on globally, and they are enabled per model under Workspace → Models → Edit. They also require native function calling in the UI.
  • Using it. Ask for work that splits naturally — "research these four approaches and compare them" — and a capable model will delegate rather than working through everything in one thread.
  • The limits. A sub-agent cannot delegate again, so work never fans out without bound. There are administrator-set caps on how many run at once and how long each may iterate.

More on features and models: Using Open WebUI.


Step 7: Why prompting and agents matter more here

The models here run on Research Computing hardware, which is what makes them free to you and keeps your prompts in our data center. They are open-weight models, and generally smaller than the largest commercial frontier models. That trade is usually a good one, but it does change how you work with them.

The short version: a frontier model will often rescue a vague prompt by guessing what you meant. A smaller model gives you what you actually asked for. So you get better results by asking more precisely — and the habits below are worth having with any model, frontier ones included.

What you will notice, and what to do about it

What you will noticeWhy it happensWhat to do
It takes you literally and skips the "obvious" parts.Less capacity to infer unstated intent.State the obvious. Name the file. Name the function. Say what "done" means.
It loses the thread on long, multi-part requests.Weaker multi-step planning.One task per prompt. Finish and check it, then ask for the next.
Quality degrades in long sessions, before you hit any limit.Effective context is shorter than the advertised window.Start a fresh session per task. Point at one to three specific files rather than "the project".
It drifts from your conventions.It cannot remember across sessions.Write the conventions into AGENTS.md (below) so they are supplied every time.
It gets site-specific details wrong — wrong partition, wrong module, invented #SBATCH flags.It has never seen our clusters.Install the RC skills that describe how things work here.
File edits fail or repeat while chat works fine.Tool calling is more fragile in smaller models.Switch to a model with the Tools badge.
It states wrong things confidently.Less reliable self-correction.Ask for a plan before code, run the code, and read the diff.

The prompt skeleton

This shape suits any request beyond a one-liner. It is more than you would type for a frontier model, and it is usually the difference between one attempt and five.

CONTEXT
You are helping me build <what> in <language/framework>. I am a beginner.

GOAL
<One sentence. One outcome.>

FILES
Work only in <exact filenames>. Do not create new files unless I ask.

CONSTRAINTS
- <library or version limits>
- <things to keep simple, e.g. "no database, use a JSON file">
- Keep it under ~150 lines.

DONE MEANS
- I can run <exact command> and see <exact result>.
- <specific behavior a test would check>

PLEASE
1. Show me your plan first, in 3-5 bullets.
2. Wait for me to say go.
3. Then write the code and explain the two lines I am most likely to want to change.
The same request, before and after

Vague:

make me a csv viewer

You will get something back, but it will be built on guesses — invented column names, a database you did not ask for, a fixed file path, and no instructions for running it.

Specific:

CONTEXT
You are helping me build a small Streamlit app in Python. I am a beginner.

GOAL
Show a CSV file's contents in a web page with a filter box.

FILES
Work only in app.py.

CONSTRAINTS
- Use streamlit and pandas only.
- The user uploads the CSV through the page. Do not read from a fixed path.
- No database, no config files.
- Under 80 lines.

DONE MEANS
- I run `streamlit run app.py`, upload a CSV, and see the first 20 rows in a table.
- Typing in the filter box narrows the table to matching rows.
- If no file is uploaded, the page says so instead of crashing.

PLEASE
1. Show me your plan first in 3-5 bullets, then wait for me to say go.
2. After I approve, write app.py.
3. Tell me which line to edit to change the number of rows shown.

The second prompt is not longer for the sake of it. Each line removes a decision the model would otherwise have had to guess at.

Three places to put structure

Prompting well is the day-to-day habit. These three files are how you avoid retyping the same context every session:

LayerWhat it holdsWhen it loads
AGENTS.mdYour project's facts and rules.Every session, automatically.
AgentsSaved roles with their own model and permissions.When you switch to one (/agent, @name).
SkillsSpecialized know-how, such as how Slurm works here.On demand, when a task calls for it.

Write an AGENTS.md

AGENTS.md is a plain markdown file in your project root that OpenCode — and OpenWork, and several other tools — reads at the start of every session. Whatever is in it comes along as context every time, without you asking.

The easiest way to start one is to run /init inside OpenCode in your project and let it draft from what it finds, then trim by hand. Keep it short and specific: a bloated file spends the context you were trying to protect.

AGENTS.md
# Project: Lab CSV Explorer

## What this is
A single-page Streamlit app for previewing lab result CSVs. Beginner-maintained.

## Commands
- Run: `streamlit run app.py`
- Install: `pip install -r requirements.txt`

## Conventions
- All app code lives in app.py. Do not split into modules.
- Config comes from environment variables, never hardcoded.
- Standard library and the packages in requirements.txt only — ask before adding a dependency.

## Rules for you
- Show a plan before writing code.
- Change one thing at a time.
- Never commit .env or any API key.

You can also keep a personal one at ~/.config/opencode/AGENTS.md that applies across all your projects — a reasonable place for "explain things to me as a beginner" or "always show me the command to run."

Use agents instead of one big prompt

An agent is a saved role: a system prompt, a model, and a set of permissions, stored under a name. Rather than retyping "you are a careful code reviewer, do not edit anything, focus on…", you switch to your reviewer agent with /agent.

This is worth more here than it would be with a frontier model. A general-purpose prompt leaves the model to work out how to approach a task; a narrow agent tells it. A smaller model given one well-defined job — with the tools it should not use switched off — tends to do better than a larger model given a vague one.

If you used a Voyager preset in Step 3b, you already have agents. Starter gives you two:

  • assistant (primary) — the one you talk to. Press Tab to cycle primary agents, or use /agent.
  • reviewer (subagent) — a specialist the assistant can call, or that you invoke yourself by typing @reviewer in a message.

The critic agents in the other presets follow the same idea. A separate read-only pass, by an agent whose only job is finding problems, catches things the agent that wrote the code will not.

Add your own

The quickest route is back to the Voyager opencode tab: add a role, pick its model, regenerate, save. To create one locally instead, this command asks where to save it and writes the file for you:

opencode agent create

Or write the file yourself. Global agents go in ~/.config/opencode/agents/, per-project agents in .opencode/agents/, and the filename becomes the agent's name:

~/.config/opencode/agents/explainer.md
---
description: Explains existing code to a beginner without changing it
mode: subagent
temperature: 0.1
permission:
edit: deny
write: deny
bash: deny
---

You explain code to a researcher who is new to programming.

For the file you are given:
1. One sentence on what it does overall.
2. A walkthrough in the order the code actually runs, not top to bottom.
3. Any line that would surprise a beginner, and why it is written that way.

Use plain language. Define jargon the first time you use it.
Never modify the file. If something looks like a bug, say so at the end and stop.

The permission block is what makes a read-only agent worth trusting. With edit: deny it cannot change your code, so you can let it run without watching it closely.

Alongside the preset's reviewer, two more are useful early on: an explainer like the one above, and a test-writer that writes tests and touches nothing else.

Add skills for HPC and research work

A skill is a reusable instruction file an agent loads on demand, only when a task calls for it. AGENTS.md is always in context and agents are roles you switch into; skills sit on the shelf until they are needed, which is what you want when context is in short supply.

Research Computing publishes a library of these, so you do not have to write them. Go to VoyagerLLM AccessSkills. They are written in OpenCode's SKILL.md format and describe how things work on our clusters — partitions, QOS, filesystems, the module system — which is exactly the local knowledge a general-purpose model has no way of having:

SkillWhat it covers
Slurm batch scriptsCorrect #SBATCH headers, array jobs, and interactive sessions, with the site's partitions and QOS.
Diagnose stuck and failed jobsA triage path from "it's still PENDING" or "it died at 3am" to the actual cause.
GPU right-sizing and utilizationProving a GPU is actually busy before asking for more of them.
Python environments on HPCEnvironments that survive quotas, batch shells, and whoever inherits the project.
Containers on HPC (Apptainer)Portable, reproducible software stacks that run unprivileged on compute nodes.
Research data layout and quotasWhich filesystem, what layout, how to check usage — planning only, no data touched.
Parallel performance and scalingFind the real bottleneck, then optimize, with scaling studies that hold up in a paper.
Reproducible computational researchEvery number in the paper traceable to a commit, a config, and a job ID.
Publication-quality figuresFigures legible at column width, honest about uncertainty, and readable to everyone.

To install one, use Copy or Download in Voyager and put it where OpenCode looks. Each skill shows its exact path on the page:

# Example: the Slurm batch scripts skill, in your project
mkdir -p .opencode/skills/slurm-job-scripts
# save the file inside that folder as SKILL.md
Rename the download

Downloads are named like slurm-job-scripts.SKILL.md so several can share one downloads folder. Rename the file to exactly SKILL.md once it is inside its skill folder.

Each skill states what it does, when to use it, and where its safety boundary sits. The Slurm skill, for example, reads and writes files inside your project and runs read-only cluster queries (sinfo, squeue, sacctmgr show), but never submits or cancels jobs — it hands you the sbatch command and you decide whether to run it. Read that section before installing any skill, the same way you would check what a new tool is allowed to touch.

If you want to see the difference, ask for a Slurm script without the skill installed and then with it. Without, you get generic directives that look plausible; with, you get directives that work on Sol.

Pair the Scientific computing preset with these skills

If you work on the clusters, the Scientific computing preset from Step 3b together with the Jobs & scheduling skills is a combination worth setting up once and keeping.

The habits, in brief

  1. One task per prompt. Run it, check it, then ask for the next.
  2. Say what "done" means, in terms you can verify yourself.
  3. Ask for a plan before code on anything touching more than one file.
  4. Name exact files. "The project" is too much context; app.py is about right.
  5. Start a fresh session for a new task rather than continuing a long one.
  6. Read the diff. You are the reviewer. Treat the output as a draft from a fast, confident colleague who has never seen your data.
  7. Run the read-only reviewer agent before you commit. It costs one command.
  8. When a reply goes wrong, fix the prompt rather than arguing with it. Rewriting your original request usually beats three rounds of "no, not like that."
  9. When you correct the same thing twice, write it down — in AGENTS.md if it is a project rule, in an agent if it is a role, in a skill if it is specialized know-how.

Step 8: Practice on something fun

Before starting a real project, spend an hour on something with an obvious right answer. A puzzle you can watch run tells you more about how your model behaves than a form-and-database app does, and it is a lot more enjoyable to debug.

Each prompt below is ready to copy. They all produce a single self-contained index.html and install nothing at all: save the file, double-click it, and it opens in your browser. The sudoku solver is the one to start with.

Sudoku solver with a visual UI

A good first project: the definition of done is precise, breakage is obvious on sight, and the step-by-step solving animation requires the model to write genuine algorithmic code rather than something that merely looks right.

CONTEXT
You are helping me build a browser sudoku app. I am a beginner. Everything must live in
one file, index.html, that I can open by double-clicking it. No build step, no npm,
no external libraries or CDN links.

GOAL
A 9x9 sudoku board with a button to generate a random puzzle and a button to solve it
one box at a time, visibly.

DONE MEANS
- I open index.html and see a 9x9 grid with clear 3x3 block borders.
- "New Puzzle" fills in a random solvable puzzle. Given numbers are bold and dark;
empty cells are blank.
- "Solve" fills the empty cells one at a time with a short delay so I can watch it,
in a different color from the given numbers.
- The solver is real backtracking, not a lookup table. Show me the backtracking:
when it undoes a wrong guess, briefly flash that cell red.
- A "Stop" button halts the animation mid-solve.
- A status line reads "Solved in N steps" when finished.

CONSTRAINTS
- Plain HTML, CSS, and JavaScript in one file. No frameworks.
- Comment the solver function so I can follow the algorithm.
- Under 300 lines.

PLEASE
1. Show me your plan in 4-6 bullets, then wait for me to say go.
2. Then write index.html.
3. Explain how to change the animation speed and the puzzle difficulty.

Then push on it — this is where you learn the most:

Add a difficulty selector with Easy, Medium, and Hard that changes how many cells are
pre-filled. Change nothing else.
Add a "Check" button that highlights any cell that conflicts with another in its row,
column, or 3x3 block. Do not change the solver.

→ Full step-by-step tutorial: Build a Sudoku Solver with a Visual UI

Conway's Game of Life

Four simple rules, and you can tell at a glance whether the model implemented them correctly.

Build a single self-contained index.html with Conway's Game of Life. No libraries.

DONE MEANS
- A 50x30 grid of cells rendered on a canvas.
- Start, Stop, Step, Clear, and Randomize buttons.
- Clicking a cell toggles it alive or dead, even while running.
- A speed slider from 1 to 30 generations per second.
- A generation counter and a live-cell count.
- Edges wrap around, so a glider crossing the right edge reappears on the left.

Keep it under 250 lines. Comment the rule that decides whether a cell lives or dies.
Show me your plan first, then wait for me to say go.

Maze generator and solver

Two algorithms in one file, both of them visible while they run. A good test of how well a model handles "animate this".

Build a single self-contained index.html that generates and solves a maze. No libraries.

DONE MEANS
- "Generate" draws a random perfect maze (exactly one path between any two cells) on a
canvas, animating the generation so I can watch it carve.
- "Solve" animates a path from the top-left to the bottom-right, drawing explored dead
ends in light gray and the final path in a solid color.
- A size slider from 10x10 to 40x40.
- Both animations can be stopped mid-run.

Use recursive backtracking to generate and breadth-first search to solve. Say in a comment
why BFS gives the shortest path. Under 300 lines.
Show me your plan first, then wait for me to say go.

Lab timer with presets

Small enough to finish in a single pass, and it touches browser APIs that come up again later.

Build a single self-contained index.html: a countdown timer for lab work. No libraries.

DONE MEANS
- Preset buttons for 5, 15, 25, and 50 minutes, plus a custom minutes input.
- Start, Pause, and Reset. The remaining time shows as MM:SS in large text.
- The page title also shows the countdown, so I can see it in a background tab.
- A colored ring around the timer drains as time passes.
- When it hits zero, the page flashes and a short beep plays using the Web Audio API
(no audio files).
- The last preset I used is remembered in localStorage.

Under 200 lines. Show me your plan first, then wait for me to say go.

Flashcard quiz from a text file

The first of these that works on your own content, and a natural lead-in to the note-based tutorials.

Build a single self-contained index.html flashcard quiz. No libraries.

DONE MEANS
- A textarea where I paste lines in the form "question | answer", one per line.
- "Start Quiz" hides the textarea and shows one question at a time.
- Clicking the card flips it to reveal the answer with a CSS flip animation.
- "Got it" and "Missed it" buttons; missed cards come back later in the same session.
- A progress indicator: "Card 4 of 12 - 3 missed".
- The pasted cards persist in localStorage so a refresh does not lose them.

Under 250 lines. Show me your plan first, then wait for me to say go.

Paste-a-CSV chart

A stepping stone to the CSV Dataset Explorer, without installing anything first.

Build a single self-contained index.html that charts pasted CSV data. No libraries and
no CDN — draw the chart yourself on a canvas.

DONE MEANS
- A textarea where I paste CSV text with a header row, plus a "Plot" button.
- Dropdowns to pick which column is the X axis and which is the Y axis, populated from
the header row.
- A bar chart or line chart (my choice via a toggle) with labeled axes and gridlines.
- Hovering a point or bar shows its exact value in a tooltip.
- A clear message if a chosen column is not numeric, instead of a broken chart.

Under 300 lines. Show me your plan first, then wait for me to say go.
What to watch for

Whether it works is only half of it. Pay attention to where it needed help, because the same tendencies will show up on your real project. Did it pull in a library you said not to use? Did it skip the one-at-a-time animation? Did asking for a plan first change the outcome? Anything you find yourself correcting more than once belongs in your AGENTS.md.

Once it works, run @reviewer over the file before moving on. Getting used to a second, read-only pass on a small project is how it becomes automatic on a larger one.


Troubleshooting

SymptomFix
401 / authentication failedThe key is wrong, expired, or not visible to the tool. Confirm with echo $OPENAI_API_KEY (macOS/Linux) or echo $env:OPENAI_API_KEY (Windows), then restart the tool. Regenerate the key in Voyager if needed.
Model not foundA model ID does not match Voyager exactly. Copy it again from the LLM Access tab.
opencode: command not foundFully quit and reopen your terminal after installing.
No RC provider or models in the pickerThe config was not loaded. Check the file path from Step 3b and fully restart the tool — config changes need a restart.
Works in curl but not in the appThe app cannot see your shell's environment variable. For OpenCode's desktop app, run opencode auth login and paste the key.
Chat replies but file edits never happenThe model likely does not support tool calling. Switch to a tool-capable model from the Voyager list.
Replies are good but then go off the railsThe session got too long. Start a fresh session and point at specific files.
It keeps ignoring an instructionMove that instruction into AGENTS.md so it is supplied every session rather than once.
A skill never seems to loadCheck the folder path and that the file is named exactly SKILL.md (downloads arrive as name.SKILL.md and must be renamed). Restart OpenCode.
/agent shows nothing, or the wrong agentsThe config with your agent block was not loaded. Confirm you saved the file Voyager generated to the right path, then restart.
429 rate limitYou are sending requests too quickly. Wait a moment and retry.

Still stuck? See Getting Help to open a ticket or join office hours.


Where to go next

You now have a key, a tool that can edit your projects, and a working sense of how to get good results from the models we host.

Pick a project from the Tutorials & Projects index. The sudoku solver installs nothing at all, and the Streamlit chatbot and CSV dataset explorer are the gentlest starting points once you are ready to install something.