Agentic Workflows

Teaching: 20 min · Exercises: 0 min · Total: 20 min

Open a JupyterHub terminal

▶ Open a JupyterHub terminal — opens JupyterLab in the training workspace directory on jh-training.nrp-nautilus.io; use a Terminal for the opencode steps below.

In Part 2 you used NRP's managed LLM from Python. Now you'll point an agentic coding CLI at the same managed endpoint and have it write a small program from scratch. The CLI we use is opencode, a terminal UI similar in spirit to Claude Code or Cursor's CLI — it plans, edits files, runs tools, and iterates. The key teaching point is portability: anything that speaks an OpenAI-compatible base URL works against NRP, so the agentic workflow you already use locally runs unchanged against NRP's managed inference.

Run all commands from a JupyterHub terminal. Command blocks are formatted for copy/paste into that terminal.

Schedule

TopicOutcome
SetupInstall opencode and point it at the NRP managed LLM.
Build a chess gameDrive opencode through a small but real coding task.
Discussion and Q&AImplementation strategies for under-resourced classrooms.

Setup

Install opencode into the JupyterHub session. The installer drops the binary in ~/.opencode/bin/ — no sudo needed.

Bash
curl -fsSL https://opencode.ai/install | bash
export PATH="$HOME/.opencode/bin:$PATH"
opencode --version

Write an opencode config that uses the NRP managed LLM via the already exported OPENAI_API_KEY:

Bash
mkdir -p ~/.config/opencode
cat > ~/.config/opencode/opencode.json <<'JSON'
{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "nrp": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "NRP LLM",
      "options": {
        "baseURL": "https://ellm.nrp-nautilus.io/v1",
        "apiKey": "{env:OPENAI_API_KEY}"
      },
      "models": {
        "minimax-m2":      { "name": "MiniMax M2"        },
        "gpt-oss":         { "name": "GPT-OSS"           },
        "qwen3":           { "name": "Qwen3 397B"        },
        "gemma-small-e4b": { "name": "Gemma 3n E4B"      }
      }
    }
  },
  "model": "nrp/gpt-oss"
}
JSON

gpt-oss is the default model here because it tends to do well on code; you can switch in-session with Ctrl+P → Switch models.

Build a chess game

Create a clean project directory and launch the agent:

Bash
mkdir -p ~/chess && cd ~/chess
opencode

Inside the opencode TUI, press / to open the prompt and paste:

text
Write a single-file Python program chess_game.py that lets two humans play
chess in the terminal. Use the python-chess library. Render the board after
every move using board.unicode(). Accept moves in SAN (e.g., "e4", "Nf3").
When the game ends, print the result. Add a top-of-file docstring. After
writing the file, add a requirements.txt pinning python-chess to 1.999, and
tell me the exact commands to install and play.

opencode plans, writes chess_game.py and requirements.txt, and prints the run instructions. Install and play:

Bash
pip install -r requirements.txt
python chess_game.py

⚠️ Don't name the file chess.py — it shadows the python-chess package. import chess then re-imports your script and chess.Board() raises AttributeError. Models sometimes pick chess.py anyway because the prompt says "chess game"; if that happens, rename it. Models have also been known to invent versions like python-chess==1.10.0 that do not exist on PyPI — the actual current pin is python-chess==1.999. The prompt above pre-pins to avoid the round-trip.

Try a few moves: e4, e5, Nf3, Nc6, Bb5, a6, Bxc6, dxc6. Press Ctrl+C to quit.

Switch models inside opencode with Ctrl+P → Switch models. Try the same prompt against qwen3 (the largest context window) or minimax-m2 (strong general-purpose reasoning) — same agent, same prompt, different inference backend.

Discussion and Q&A

Key teaching points:

Practical classroom strategies:

Reference: client configs.