Getting Started with an Agent
Coding agents are powerful tools, but they come with significant risks. To use agents safely, it’s important to run them in an environment where the potential harms are mitigated. Coder Workspaces are very helpful for this purpose because they are disposable virtual machines. Any agent running in a workspace can only interact with the files you upload to the VM. This provides more safety than running the agent on your personal computer, for example.
The Coder Workspace Environment
Coder workspaces are a UCSB-specific resource, however you could substitute any cloud-based service for running virtual machines.
Follow the setup instructions if necessary, to create a Coder Workspace. You should have a workspace with a dashboard like the image below.
The Workspace dashboard has several features:
- On the top row, there are buttons to “Stop” and “Restart” the workspace. Your workspace is a virtual machine: stopping the workspace is like turning off the computer; restarting it is like rebooting your computer.
- There are also buttons to open various applications: VS Code (more below), File Browser (to upload and download files to the workspace), and Terminal (a command line interface). Clicking these will open new browser windows.
The Visual Studio Code Interface
We will mainly use the VS Code Web interface, both to run our coding agent and to review files. VS Code Web is a browser-based variant of the VS Code editor.
The VS Code Interface includes a file Explorer on the left side. When it starts, the Explorer shows the contents of an empty default directory (~/workspace). There is also an Editor Area, that shows a tab with a welcome message at startup. You can close the startup message tab.
VS Code also includes AI-assisted coding features (Copilot), but we aren’t going to use them in this workshop. You can close the Copilot panel on the right side. Instead, we will run a coding agent, OpenCode, in a terminal window in the Editor Area.
To create a terminal window in the Editor Area:
- Right click on any open space in the Editor Area.
- Click “New Terminal”
You can also use VS Code’s Command Palette (⇧⌘P) and run Terminal: Create New Terminal in Editor Area. Next we’ll start OpenCode.
Starting with OpenCode
There are many coding agents out there. We like OpenCode because it is one of the few widely used coding agents that is model agnostic.
To start OpenCode, run opencode in the VS Code terminal.
By default, OpenCode on Coder Workspaces is configured to use open weights models through the College IT Gateway.
OpenCode needs to know which AI model to talk to. We’ll point it at the DREAM Lab AI Gateway, which gives us access to a range of models through a single API key. We only need to do this configuration once.
1. Connect to a model provider. In the OpenCode prompt, type /connect and press Enter. Start typing dream to filter the list, then select DREAM Lab AI Gateway under Providers.
2. Enter your API key. In the workshop, you will receive instruction for accessing your API key. Once you have it, paste the key into OpenCode and press Enter to submit.
3. Select a model. Choose Gemini 3.5 Flash from the list of available models. You can use (Ctrl+F) to “favorite” a model. We will use both Gemini 3.5 Flash and Gemini 3.1 Pro (Custom Tools) – you might want to favorite both of these to make switching models a little easier.
OpenCode is now configured and ready to use the DREAM Lab AI Gateway.
Our First Prompt
To demonstrate the capabilities of a coding agent, let’s ask OpenCode to inspect that machine we’re using.
Tell me about the machine you’re running on: OS, resources, etc.
OpenCode will probably ask you for permission to access files outside of the working directory. It’s safe to say yes because this isn’t your real machine! You can choose “Allow always” and then “Confirm”.
The response should look something like this.
I will run a few non-modifying commands to retrieve information
about the operating system, CPU, memory, and disk resources.
bash tool: "uname -a && cat /etc/os-release && free -h && nproc && df -h /"
This machine is running:
- **OS**: Ubuntu 26.04 LTS (Kernel 7.0.0, x86_64)
- **CPU**: 4 Cores
- **RAM**: 15 GiB (12 GiB available)
- **Disk**: 14 GiB total, 8.1 GiB free (41% used)Agent Permissions
Most coding agents, including OpenCode, have a permission system used to control what actions the agent is allowed to perform in its environment. In the example above, OpenCode paused and asked before running a bash command. Even though our agent is isolated in a throwaway virtual machine, it’s worth understanding how it decides when to ask for your approval.
The actions the agent can perform (e.g., reading files, editing them, running shell commands, fetching URLs) are determined by permission levels:
allow— the action runs automatically, no questions asked.ask— the agent pauses and waits for your approval.deny— the action is blocked entirely.
By default OpenCode allows most actions, but you can change this through OpenCode’s configuration file.
A few defaults worth knowing:
- Reading files outside the working directory defaults to
ask. .envfiles are denied by default, so secrets aren’t read accidentally.
OpenCode Commands
You can type “/” followed by a command name to configure OpenCode or perform various actions. You can find a complete list of commands in the OpenCode documentation.
The commands we will use in the workshop are listed here:
/connect- Add a model provider. Allows you to select from available providers and add their API keys./exit- Exit OpenCode. (You can also use/q)/help- Display help information/models- List and switch between models/new- Start a new session (fresh context)
Switching models
Your Coder Workspace includes configurations for several models, not just those provided through the DREAM Lab. These are grouped by provider:
DREAM Lab AI Gateway provides Google models:
- Gemini 3.5 Flash
- Gemini 3 Flash
- Gemini 3.1 Pro
- Gemini 3.1 Pro (Custom Tools)
UCSB College IT (CIT) AI Gateway provides several open weights models:
- Gemma 4
- Qwen3-Coder-Next
- GPT-OSS-120b
Ordering these models by their coding capability (roughly):
- Gemini 3.1 Pro [(Custom Tools)]
- Gemini 3.5 Flash
- Gemini 3 Flash / Qwen3-Coder-Next
- Gemma 4 / GPT-OSS-120b
To switch models, type /models and press Enter. Type the name of the model you want to filter the list, and use the arrow keys to move through the list (models are grouped by provider). Press Enter to select the model. OpenCode will use the selected model for the rest of the session. The active model appears at the bottom of the OpenCode interface.
We will soon start using git to track changes in our generated code. First, there are a few things to configure. Typically, we would do these directly with git config --global, but let’s just use OpenCode!
- Switch to an open weights model from CIT: Qwen3-Coder-Next (because this is not a difficult task and the models are running on campus).
- Use OpenCode to set git’s default branch to main and the name and email configurations to your name and email. Try to come up with the prompt yourself!
- It might not work on the first try. Hint: Did the model even ask for your name and email?
- Ask OpenCode to confirm that the configurations are correct.
- Quit OpenCode: you should be back on the terminal command line.
Discussion: Who/what did you just share your name and email with?
Starting a Project
Let’s explore OpenCode’s capability with an example project: analyzing ocean tide data from the National Oceanic and Atmospheric Administration (NOAA).
The recommended way to run OpenCode is from your project directory. We will create a project folder called noaa-tides, set it as the working directory, and then start OpenCode. If you didn’t quit OpenCode at the end of the previous exercise, do so now. From the terminal window run the commands:
# make our project directory
mkdir noaa-tides
# set noaa-tides as the working directory.
cd noaa-tides
# print working directory: should be "/home/coder/workspace/noaa-tides"
pwd
# start opencode
opencodeInstead of using mkdir, you can also create the noaa-tides folder through file Explorer (on the left side of VS Code), but you will still need to cd into the folder before running opencode.
Exercise: Download and Plot NOAA Tide Data
Complete the exercise individually but discuss results in small groups (2-5 people).
Use /models to select one of the models:
- Gemini 3.1 Pro (Custom Tools)
- Gemini 3.5 Flash
- Gemini 3 Flash
- Qwen3-Coder-Next
Try to use a different model from other members of your group. Paste the following prompt into OpenCode:
download monthly mean high water for all NOAA stations in California over the last ten years. Download as CSV and save in
data. Track code with git, but not the data.
Wait for the agent to complete the task (it may take a few minutes).
Weaker models (Qwen3-Coder-Next, Gemini 3 Flash), may get stuck or take too long. In that case, you can press Escape to interrupt the work, switch to a higher model, and ask OpenCode to continue.
In your group, discuss the following questions:
- What files were downloaded to the
datafolder? How many and what format? If they are CSVs (as expected), what columns do they include? - Does everyone in the group have the same set of files? What similarities and differences can you find?
- Look at the agent’s session transcript: how did the agent complete the task? For example: did it generate scripts to download the data and, if so, what language did it use? How did it construct the URL for the download request? (You can always ask the agent to explain the steps it took).
- In your group, discuss the different approaches the agent took.
Try an additional prompt and discuss the results:
Plot the mean high water value for all stations using a different color for each station. Include labels on x/y axes and a legend with the station name. What is the name of the station with the highest average mean high water value over the last decade? Save the code with a git commit, but ignore the image.
- You can view the generated plot image by clicking the file in the file Explorer.
- Compare the generated plots in your group. Did everyone get the same answer for the station with the highest mean high water value?
- In light of your discussion, how would you move forward to improve the analysis? Try an additional prompt to steer the agent toward better results.
These are notes from a previous run of the exercise prompts.
What files were downloaded?
The agent downloaded 18 CSV files, one per California tide station, saved to noaa-tides/data and named by station ID (e.g. 9410170_monthly_mean.csv). Each file is the NOAA monthly_mean product, so even though we only asked for mean high water, every CSV contains all the monthly datum columns (Year, Month, Highest, MHHW, MHW, MSL, MTL, MLW, MLLW, DTL, GT, MN, DHQ, DLQ, HWI, LWI, Lowest, Inferred). Each file holds ~120 monthly rows (June 2016 – May 2026), and some cells are blank where NOAA had no value.
How did the agent complete the task?
- The agent probed the NOAA metadata API (
mdapi/.../stations.json?state=CA) and the data API (datagetter?...product=monthly_mean) with small one-off commands to learn how the API behaves. - It generated a python script,
download.py, that looped over stations, requested CSV, and slept between calls. - It encountered some errors and worked around them:
- The
?state=CAfilter on the stations endpoint was silently ignored — the first run started downloading every US station (Hawaii, the East Coast, the Gulf) instead of just California. The agent caught this, then fetched the full station list and filtered client-side onstate == 'CA', which correctly yielded 18 stations. - The API began returning
403 Forbiddenafter rapid-fire requests (rate limiting). The agent diagnosed it withcurl -i, then added a browser-likeUser-Agentheader and increased the delay to 1 second per request.
- The
- Re-ran cleanly, then read one CSV back to confirm the format before reporting done.
Here is how the download request is created:
url = (
f"https://api.tidesandcurrents.noaa.gov/api/prod/datagetter"
f"?begin_date={begin_date}"
f"&end_date={end_date}"
f"&station={station_id}"
f"&product=monthly_mean"
f"&datum=MHW"
f"&time_zone=lst"
f"&units=metric"
f"&application=DataAPI_Sample"
f"&format=csv"
)Highest average MHW station
The agent reported North Spit as the station with the highest average MHW.
The agent averaged the MHW column across each file and reported North Spit (≈0.154 m). That arithmetic is correct for the data it downloaded — but it’s probably not the best answer to the question.
Caveats
The generated script downloads data using datum=MHW, so every MHW value is measured relative to each station’s own MHW datum rather than an absolute reference (see the NOAA API documentation). That makes the numbers tiny because they aren’t tide heights at all. They’re anomalies, i.e. how far each month sat above that station’s historical baseline. So “North Spit is highest” really means its high water has risen the most relative to its own reference. Ask for the same thing against a fixed physical datum (datum=MLLW, the actual height of mean high water above the chart datum) and the answer changes.
Here’s how I steered the agent:
This plot doesn’t look right. The values seem too small. I think I need to use MLLW as the datum. Fix the code and regenerate the plot, then commit those changes. What is the correct station?
The new station identified by the agent is Redwood City.








