Project structure
As a review
- Move both
noaa-tidesandnoaa-tides-2to a new folder, calledtides-project - Start OpenCode in this new folder, make sure you select
Gemini 3.5 Flashas your model - Imagine for a moment you are new to this project, and you want to know what it is about. Therefore, you ask OpenCode:
What is this project about? What were the latest changes made?
A response might look like:
✱Glob "*" (41 matches)
→Read noaa-tides/download_data.py [limit=100]
→Read noaa-tides/plot_tides.py [limit=100]
$ git status && git log -n 5 --oneline
fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
Project Overview
This project is designed to download, analyze, and visualize NOAA tide and water level data, specifically focusing on the Monthly Mean High Water (MHW) levels for California tide stations over a 10-year period (2016–2026).
[...]
Latest Changes Made
Since this project is not initialized as a Git repository, we can infer the latest updates from the differences in structure and the file contents: [...]There is a lot to unpack here:
LLMs are very good at summarizing a big amount of information quickly. In a few seconds it read the files in our project and gave us an overview to get started.
It shows how the AI Agent called tools like
GlobandRead, and it tried to run agitShell command. Contrary to a chat-based AI tool, the AI Agent was able to access the files in our project and call tools to gather additional information.In this particular response, the agent somewhat complains that the project is not a Git repository. If it was, the AI Agent would be able to gather even more information about recent developments in the project.
AI coding agents makes it easier to use version control and, at the same time, more necessary, in order to access that valuable information about the history of a project. Makes even more sense to use it in case the AI messes up our entire project!
If we open a new chat session with the /new command, the AI Agent would have to read again files just to have a brief overview of the project, wasting precious time and tokens.
What if there was a file the AI always has access to with the most relevant information of our project?
The AGENTS.md file
AGENTS.md is a special file that is always included at the start of the conversation with the coding agent, without the user having to mention it.
Just like a README file describes the project and its structure to a human reader to facilitate its understanding, the AGENTS.md is meant for the AI to have a high level description of the project without having to read a bunch of files with every new conversation, and also to give the AI clear and important guidelines on conventions, coding styles, or workflows the user wants it to follow.
We can ask our AI Agent to get us started with an AGENTS.md, using the /init command. In OpenCode we can even review the prompt used for creating the file.
As you can see, it is a human-readable, plain markdown file. It can have any sections you feel are relevant to your project, but aim to keep it concise and focused on guiding the AI through specificities of your project.
Some common sections you’ll find in AGENTS.md files:
- Project overview: A short and high-level description.
- Tools / Tech stack: AI tools can be very opinionated on what programming languages and tools it uses. Being specific on the tools you use helps guide the AI, without having you repeat it in every prompt.
- Project structure / architecture: Having the directory structure of your project helps the AI to know where to save and find files.
- Code style guidelines: Any particular preferences you and your team may be following on your coding project.
- Workflows: For example, the Git and GitHub workflow you want to follow, conventions to name new branches or commit messages.
Exercise: Discuss real AGENTS.md examples
Customize the AGENTS.md file
The /init command was a great start, but you should personalize it and add important considerations for your project. Let’s add the following to the AGENTS.md file we have until now.
## Environment & Tooling
- Language: Python (>=3.11 recommended)
- Package manager: **uv** — do not use pip, conda, or poetry directly.
- Install dependencies: `uv add <package>`
- Sync environment from lockfile: `uv sync`
- Always keep `pyproject.toml` and `uv.lock` in sync; commit `uv.lock`.
- Do not manually edit `uv.lock` — regenerate it via `uv lock` or `uv sync`.
## Directory structure
Always consider this directory structure to find and create files in this project:
- data
- raw
- processed
- code
- docs
- results
- figures
- tables
## Workflows
### Before committing any changes
Always run the following checks before creating a commit. Do not commit if any step fails — fix the issues first (or ask the user if a fix isn't obvious).
1. Format code:
`uv run ruff format .`
2. Lint and auto-fix what's safe to fix:
`uv run ruff check --fix .`
3. Re-run lint to confirm no remaining errors:
`uv run ruff check .`
4. Stage only the relevant files (avoid `git add .` unless you're sure everything staged is intended):
`git add <files>`
5. Write a clear, conventional commit message (see below) and commit:
`git commit -m "<type>: <short summary>"`
### Commit message conventions
Keep it short and descriptive, e.g. `add sliding window aggregation for signal preprocessing`. No strict format required — just make it clear what changed and why, so it's easy to trace back for reproducibility.
### General rules
- Never commit directly to `main`. Create a branch (`git switch -c <branch-name>`) if one doesn't already exist for the current task.
- Never force-push (`git push --force`) without explicit user confirmation.
- If `ruff` reports errors that can't be auto-fixed, stop and explain the issue rather than silently ignoring or suppressing it.After this adjustments, make sure the project is actually following these conventions and test how it it works. Let’s use this prompt:
Make sure my project follows the guidelines stated on the @AGENTS.md file.
Creating a subagent
An additional instruction we can add in our AGENTS.md is to call a different agent (a subagent) to complete a given task. This can be greatly useful for multiple purposes:
when we want different AI LLM models to complete different tasks, depending on the cost and capability of the model.
For example: using a multimodal AI model to handle images or audio, delegating all coding tasks to a specific model, or summarizing content with a cheap small model.
to parallelize tasks that can be completed independently.
to have specialized roles or personas completing different tasks, or checking the work of other agents.
The subagent will start in a new session with its own context window, receive instructions from the agent, complete the task, and return a summary to the main session that spawned the subagent. This is another advantage of the subagent: it won’t overload your current chat session with all the analysis and process, it will only return a summary when the task is completed.
For our current project, let’s create a subagent that handles all coding tasks using the following prompt:
Following the documentation on “https://opencode.ai/docs/agents/” create a subagent in this project that is spawned every time there is a coding task. Call it
programmerand make it use the QWEN3 model available in this opencode session.
Make sure it did a correct job: 1) created a the file .opencode/agents/programmer.md 2) for model it has specified cit-litellm/Qwen3-Coder-Next.
With this completed, let’s edit our AGENT.md file and add the following instruction at the top of the file after the project overview.
## Agent Instructions & Routing
- Always spawn the `@programmer` subagent in opencode when a coding, scripting, or codebase modification task arises.Finally, give the AI Agent a new coding task to test if it is calling our newly created subagent.
Make a plot of the tides in the last 12 months for the closest station to Santa Barbara, CA, and highlight the three months with the lowest tides.