huggingface_hub / transformers: The platform and library where the ML community collaborates on models, datasets, and applications.
Login: Register with Hugging Face and obtain a key to download hosted models.
Load tokenizer & model: Downloads Google Gemma-2b and its matching tokenizer.
Tokenise input: Converts your text into a tensor of token IDs the model can read.
Generate & decode: Model predicts tokens autoregressively; tokenizer converts them back to text.
Agentic AI
AI Agents are essentially some scaffolding / loop around LLM(s):
LLM: The reasoning engine. It can plan, evaluate, or decide whether to “act” or “answer.”
System Prompt: Defines the persona, available tools, and operational boundaries.
Working memory: Maintains the state, including history, tool outputs, and the current goal.
Tools: External capabilities like web search, code execution, APIs, or connecting to RAG.
Agentic AI
%%{init: {"flowchart": {"nodeSpacing": 40, "rankSpacing": 80}, "theme": "base", "themeVariables": {"edgeLabelBackground": "#ffffff"}}}%%
flowchart LR
S([System prompt]) --> C
H([Prompt]) --> C["Context window"]
C --> L["LLM: generate text"]
L --> D{Tool call?}
D -->|yes| T["Tools (incl. RAG)"]
T -->|result appended| C
D -->|no| O([Output])
classDef io fill:#6c757d,stroke:#495057,color:#fff
classDef core fill:#003b6f,stroke:#001f3f,color:#fff
classDef support fill:#4b9cd3,stroke:#2c6e9e,color:#fff
classDef decision fill:#e9c46a,stroke:#f4a261,color:#000
class S,H,O io
class L core
class C,T support
class D decision
We now need to configure opencode to run self-hosted LLMs
Add API key to .basrhc (or equivalent) e.g., export CAMLLM_API_KEY=sk-XXXXXXXXXXXXXXXXXXXXXX
Configure opencode (see next slide)
Note
If you already have access to UoC’s LiteLLM (https://llm.hpc.cam.ac.uk) you can create one from the virtual keys page: Virtual Keys\(\rightarrow\)Create New Key.
from fastmcp import FastMCPmcp = FastMCP(name="mcp-numbers")@mcp.tooldef add(a: int, b: int) ->int:"""Add two numbers"""return a + bif__name__=="__main__": mcp.run()
MCP example (add)
Now let’s add mcp-numbers to our opencode configuration
Follow instructions in mcp/README.md
Running /status in opencode should display
Try Use mcp tool "numbers_add" to add 4 and -1
MCP examples (netcdf)
What about a more interesting example…
Can we give LLM power to inspect netcdf .nc files?
Let’s try with MCP.
MCP examples (netcdf)
Inspect file mcp/mcp-netcdf.py
mcp/mcp-netcdf.py
# /// script# dependencies = [# "netCDF4",# "fastmcp",# ]# ///import netCDF4from fastmcp import FastMCP# Initialize the FastMCP servermcp = FastMCP("nc-mcp")@mcp.tool()def get_variables(path: str) ->str:""" Reads a NetCDF file from the given path and returns its variables. Args: path: The absolute or relative path to the NetCDF (.nc) file. Returns: A string representation of the NetCDF file's variables. """try:# Open the dataset dset = netCDF4.Dataset(path)# Capture the variables as a string to return to the client variables_output =", ".join(dset.variables.keys())# Close the dataset to free up resources dset.close()return variables_outputexceptFileNotFoundError:returnf"Error: Could not find the file at path: {path}"exceptExceptionas e:returnf"Error reading NetCDF file: {str(e)}"@mcp.tool()def get_variable_shape(path: str, variable_name: str) ->dict:""" Reads a NetCDF file from the given path and returns the shape of a specific variable. Args: path: The absolute or relative path to the NetCDF (.nc) file. variable_name: The name of the variable to get the shape for. Returns: A dictionary containing the shape of the specified variable. Example: {'temperature': (365, 180, 360)} Returns an error if the variable is not found. """passif__name__=="__main__": mcp.run()
MCP examples (netcdf)
mcp/mcp-netcdf.py contains 2 MCP tools
netcdf_get_variables
netcdf_get_variable_shape (to be implemented)
Try using netcdf_get_variables on file simple.nc
MCP examples (netcdf)
Implement netcdf_get_variable_shape
See stub in mcp/mcp-netcdf.py
mcp/mcp-netcdf.py
@mcp.tool()def get_variable_shape(path: str, variable_name: str) ->dict:""" Reads a NetCDF file from the given path and returns the shape of a specific variable. ... """pass
(15 minutes for exercise)
Skills
Define reusable behavior via SKILL.md definitions
Agent skills let LLMs discover reusable instructions
Skills are loaded on-demand
Skills are “just” markdown files
Anatomy of a Skill
Many genAI tools support skills e.g., Claude code, opencode, codex etc.
Note
opencode requires that skills are stored in a specific set of locations (A full list can be found here). We will focus on these:
Project config: .opencode/skills/<name>/SKILL.md
Global config: ~/.config/opencode/skills/<name>/SKILL.md
cd project/root/GenAI-teachingmkdir-p .opencode/skills/netcdfln-sf$(pwd)/skill/netcdf/SKILL.md .opencode/skills/netcdf/
Run /skills in opencode to check registration
Skills Example (netcdf)
skill/netcdf/SKILL.md
---name: netcdf-processingdescription: Use this skill for any operations involving NetCDF (.nc) files, including inspecting metadata, reading variable shapes, extracting data slices, or generating new NetCDF datasets.---# What I doThis skill provides guidance for inspecting and generating NetCDF files usingstandard command-line utilities. Use these commands to understand datasetstructures before writing extraction scripts.# When to use this skillUse this skill whenever a user mentions climate data, multidimensional arrays,.nc files, or atmospheric datasets.## Workflow Decision Tree- **Inspecting Schema**: Use `ncdump -h` first to understand dimensions.- **Data Access**: If the file is large, only request specific variable slices (don't read entire arrays into context).- **Creating Files**: Use `ncgen` for small CDL templates or `netCDF4` Python scripts for large datasets.## Viewing Metadata with `ncdump``ncdump` is the standard tool for converting NetCDF binary files intohuman-readable text (CDL format).* **View Header Only (Recommended):** Displays dimensions, variables, and attributes without printing raw data.```bashncdump-h filename.nc```* **View Specific Variable:** Look at the data for a single variable (e.g., 'temperature').```bashncdump-v temperature filename.nc```* **Coordinate Formatting:** Use `-c` to see the header plus the values of coordinate variables (lat, lon, time).```bashncdump-c filename.nc```## Creating Files with `ncgen``ncgen` takes a text-based CDL file and compiles it into a binary `.nc` file.* **Generate Binary from CDL:**```bashncgen-o output_file.nc input_text.cdl```
Skills Example (netcdf)
Try running the following command
Note
Disable netcdf MCP server before trying to test the skill. They may conflict.
Skills Exercise
Create your own SKILL.md
Register it in opencode
Try using it
(15 minutes for exercise)
Skills vs. MCP
So how do I choose between Skills vs MCP?
MCP Server
SKILL.md (Instruction)
Primary Purpose
Tool calling – Interact with external services or perform short actions.
Domain Expertise – Provides workflows, rules, and domain knowledge.
Context/Loading
Loaded immediately into context window (regardless of query) reducing effective context window size.
Lazy loaded when needed. Will still impact context window.
Timeout
Timeout ~ 1-2 minutes. Ideal for short, quick function calls
No timeout.
Taking it further
Live demo of profiling skill
Taking it further
opencode and other genAI tools often support agents/sub-agents (see docs)
Agents are specialized AI assistants that can be configured for specific tasks and workflows
They allow you to create focused tools with custom prompts, models, and tool access