Building a Research Agent on Pi

Building a Research Agent on Pi

Agent Daily · Tutorial · June 2025
Research Agent on Pi — skill, AGENTS.md, and shell alias architecture
📖 Tutorial 🏷 Pi Agent · Skills · AGENTS.md · Research · Automation

Overview

Pi (@earendil-works/pi-coding-agent) is an open-source coding agent CLI by Mario Zechner. It has a minimalist philosophy: built-in tools for file operations and bash, with everything else driven by skills, AGENTS.md context files, and extensions.

In this guide, we build a Research Agent — a dedicated configuration that searches the internet, gathers data from multiple sources, cross-references findings, evaluates source credibility, and delivers structured reports to any folder you choose. The key: it activates only when you explicitly call it, and stays out of the way during normal pi usage.

We achieve this with three Pi features: a Skill (the research methodology), an AGENTS.md file (project-level instructions), and a shell function that ties them together. No custom code needed — just markdown files and a one-liner alias.

1 What We're Building

Our Research Agent has four core capabilities:

  • Internet Research — searches multiple sources using Brave Search and browser automation via the pi-skills package
  • Source Tracking — records every URL and source with metadata (date, author, credibility score)
  • Cross-referencing — compares claims across sources to identify consensus and contradictions
  • Evaluation Report — produces structured markdown files with findings, confidence levels, and full source bibliography

The implementation uses three Pi mechanisms:

MechanismRole
Skill (SKILL.md)The research methodology — step-by-step instructions Pi follows. Follows the Agent Skills standard.
AGENTS.mdProject-level context that tells Pi about the research workspace and output conventions
Shell functionA one-word command (research) that launches Pi with the right flags from anywhere
💡 Why not a permanent persona? Pi doesn't have built-in "profiles" or "personas." Instead, you compose behavior through skills + context files + CLI flags. This is deliberate — Pi stays minimal, and you assemble exactly what you need per invocation.

2 Architecture

Here's how the pieces fit together:

💻
Terminal
research "topic"
📋
Skill
deep-research
🌐
Web Search
+ Browser
📁
Output
./research/

When you type research "quantum computing breakthroughs 2025", the shell function launches pi in print mode (-p) with the --skill flag pointing to our research skill. Pi reads the skill's methodology, uses web search to gather sources, cross-references findings, and writes results to your current directory. Your normal pi sessions are completely unaffected.

3 Install Pi and Web Search Skills

First, install Pi itself (requires Node.js ≥22.19.0):

npm install -g --ignore-scripts @earendil-works/pi-coding-agent

Verify it works:

pi --version

Next, install the pi-skills package which includes web search (via Brave Search) and browser automation tools. Pi ships with four default tools — read, write, edit, and bash (plus optional grep, find, ls) — so we need pi-skills for internet access:

# Clone pi-skills into Pi's global skills directory git clone https://github.com/badlogic/pi-skills ~/.pi/agent/skills/pi-skills # Install dependencies for the skills you need cd ~/.pi/agent/skills/pi-skills/brave-search && npm install cd ~/.pi/agent/skills/pi-skills/browser-tools && npm install

This installs the skills to ~/.pi/agent/skills/pi-skills/. Each skill is a directory with a SKILL.md and helper scripts that Pi's agent calls via bash.

⚠️ Required API key: The brave-search skill requires a Brave Search API key. Create a free "Free AI" subscription at api-dashboard.search.brave.com (credit card required for free tier, you won't be charged) and set: export BRAVE_API_KEY="your-key-here"
Tip: You also need an API key for your preferred LLM provider. Set it in your environment: export ANTHROPIC_API_KEY="..." (or OpenAI, Google, etc.). Pi reads from standard environment variables.

4 The Research Skill

The skill is the brain of the operation. It contains the research methodology Pi follows. Skills in Pi use the Agent Skills standard — a SKILL.md file with YAML frontmatter plus markdown instructions.

Create the skill directory:

mkdir -p ~/.pi/agent/skills/deep-research

Write the SKILL.md:

# ~/.pi/agent/skills/deep-research/SKILL.md --- name: deep-research description: "Systematic internet research with source tracking, cross-referencing, and credibility evaluation. Use this skill when asked to research any topic in depth." allowed-tools: read bash write edit --- # Deep Research Methodology You are a meticulous research analyst. Your responses are precise, evidence-based, and properly sourced. You never speculate without clearly marking it as speculation. ## Output Directory - If the user specifies a folder → use it - If no folder specified → create ./research/ in the current working directory - Always create a subfolder named after the topic (slugified, e.g. quantum-computing-2025/) ## Phase 1 — Discovery (cast a wide net) 1. Break the topic into 3-5 search queries from different angles 2. For each query, use the brave-search skill's search.js script via bash: {baseDir}/../pi-skills/brave-search/search.js "query" --content 3. For JavaScript-heavy pages, use the browser-tools skill: {baseDir}/../pi-skills/browser-tools/browser-nav.js <url> and {baseDir}/../pi-skills/browser-tools/browser-content.js 4. Aim for at least 8-12 unique sources 5. Log every URL immediately — never discard a source silently 6. Include diverse source types: academic papers, news articles, official documentation, expert blogs, industry reports ## Phase 2 — Deep Extraction 1. For each promising source, read the full content 2. Extract: key claims, data points, dates, author credentials 3. Note the publication date — reject outdated info for time-sensitive topics 4. Save raw notes to sources.json with structured metadata ## Phase 3 — Cross-Referencing 1. Group claims by sub-topic 2. For each key claim, count how many independent sources support it 3. Flag contradictions explicitly — do NOT silently pick one version 4. Rate each claim: - ✅ Confirmed — 3+ independent sources agree - ⚠️ Likely — 2 sources agree, no contradictions - ❓ Unverified — single source only - ❌ Disputed — sources directly contradict each other ## Phase 4 — Evaluation 1. Score source credibility (1-5): - 5: Peer-reviewed, government, established institution - 4: Major news outlet, recognized expert - 3: Industry blog, company documentation - 2: Personal blog, forum post - 1: Social media, anonymous source 2. Weight claims by source credibility in the final assessment 3. Identify gaps — what questions remain unanswered? ## Phase 5 — Report Generation Write the final report to report.md with this structure: 1. **Executive Summary** — 3-5 sentence overview 2. **Key Findings** — numbered list with confidence ratings 3. **Detailed Analysis** — section per sub-topic, with inline source citations [1], [2], etc. 4. **Contradictions & Disputes** — explicit section for disagreements 5. **Gaps & Limitations** — what we couldn't confirm 6. **Source Bibliography** — numbered list with URL, title, author, date, credibility score 7. **Methodology Notes** — queries used, total sources checked ## Output Files Always produce these files in the output directory: - report.md — the main research report - sources.json — structured source data (machine-readable) - claims.md — cross-reference matrix (claim × sources) - summary.txt — one-paragraph plain text summary ## Rules - NEVER fabricate sources or data - NEVER claim a fact is confirmed without at least 2 sources - ALWAYS include access date for each source - If a source is paywalled, note it as "[paywalled]" - If search results are poor, tell the user — don't fill gaps with speculation

How Pi discovers the skill

Pi discovers skills automatically from these locations (in order):

  1. Global: ~/.pi/agent/skills/ — always available
  2. Project-local: .pi/skills/ — in the current directory or any parent up to the git root
  3. Packages: installed via pi install (e.g. pi-skills)
  4. CLI flag: --skill <path> — explicit loading per invocation

At startup, Pi scans these locations and includes skill names + descriptions in the system prompt. The agent then uses the read tool to load the full SKILL.md on-demand when it recognizes a matching task. You can also force-load it with /skill:deep-research in interactive mode.

💡 Progressive disclosure: Pi doesn't dump all skills into the system prompt. It lists available skills with their descriptions, and the agent decides which ones to load based on the task. This keeps the context window lean.
💡 {baseDir} placeholder: Pi replaces {baseDir} with the skill's actual directory path at runtime. This means your skill works regardless of where it's installed — always use {baseDir} for script paths inside SKILL.md.

5 AGENTS.md — Research Workspace Context

Pi loads AGENTS.md files from the current directory (and every parent up to the git root) plus the global ~/.pi/agent/AGENTS.md. All matching files are concatenated into the system prompt.

For our research agent, create a global context file that applies whenever you run research:

# ~/.pi/agent/AGENTS.md # (add this section to your existing AGENTS.md, or create one) ## Research Agent Convention When performing research tasks (identified by skill deep-research): - Output language matches the user's input language - All file paths should be relative to the current working directory - Create the output directory if it doesn't exist - Write machine-readable JSON alongside human-readable markdown - Use ISO 8601 dates in all metadata

You can also create project-specific context. If you have a research workspace at ~/research-projects/, you can add:

# ~/research-projects/AGENTS.md ## Research Project Workspace This directory contains research outputs. Each subdirectory is a separate research topic. When writing research output, organize files inside a topic-named subfolder. Preferred citation format: APA 7th edition.

AGENTS.md vs SYSTEM.md vs APPEND_SYSTEM.md

FileScopeBehavior
AGENTS.mdConcatenated from all parent dirsAppended to context — additive, non-destructive
SYSTEM.mdGlobal or project-localReplaces the entire default system prompt
APPEND_SYSTEM.mdGlobal or project-localAppended to system prompt without replacing
⚠️ Don't use SYSTEM.md for research. It replaces Pi's entire system prompt, disabling its built-in tool usage instructions. Use AGENTS.md (additive context) or APPEND_SYSTEM.md (append to system prompt) instead.

6 Shell Function — Call It from Anywhere

The final piece is a shell function that assembles the right pi invocation. This is what makes the research agent callable from any directory and ensures it only activates when you explicitly call it:

# Add to ~/.bashrc or ~/.zshrc research() { local topic="$*" local output_dir="$(pwd)" if [ -z "$topic" ]; then echo "Usage: research <topic> [--output /path/to/dir]" return 1 fi # Extract --output flag if provided if [[ "$*" == *"--output"* ]]; then output_dir="$(echo "$*" | sed 's/.*--output //' | awk '{print $1}')" topic="$(echo "$*" | sed 's/ --output .*//')" fi pi \ --skill ~/.pi/agent/skills/deep-research \ -p \ "Research the following topic and save results to $output_dir: $topic" }

Let's break down the Pi flags:

FlagWhat it does
--skill <path>Force-loads the specified skill into this session
-pPrint mode — Pi executes the task and exits (one-shot, non-interactive)

Now you can use it from anywhere:

# Research and save to current directory research quantum computing breakthroughs 2025 # Research and save to a specific folder research CRISPR gene therapy progress --output ~/Documents/research # Works from any directory cd /tmp && research Rust vs Go performance benchmarks

Interactive mode for follow-ups

If you want to discuss findings or ask follow-up questions, drop the -p flag and run Pi interactively:

pi --skill ~/.pi/agent/skills/deep-research

Inside the session, you can also force-load the skill with:

/skill:deep-research
Why the agent only activates when called: The skill lives in ~/.pi/agent/skills/ and Pi auto-discovers it, but it uses progressive disclosure — the skill is listed by name/description only. Pi won't load the full methodology unless the task matches the description or you explicitly load it via --skill or /skill:. Normal pi usage for coding tasks won't trigger it.

7 Complete Folder Structure

Here's the full picture of what lives where and why:

~/.pi/ └── agent/ ← Pi's global config directory ├── settings.json ← Global settings (provider, model, etc.) ├── AGENTS.md ← Global context (research conventions) ├── models.json ← Custom provider/model definitions ├── keybindings.json ← Keyboard shortcuts ├── skills/ ← Global skills directory │ ├── deep-research/ ← Our research skill │ │ └── SKILL.md ← Research methodology │ └── pi-skills/ ← Cloned from GitHub │ ├── brave-search/ ← Web search (requires BRAVE_API_KEY) │ └── browser-tools/ ← Browser automation (requires Chrome) ├── extensions/ ← TypeScript extensions ├── prompts/ ← Prompt templates ├── themes/ ← UI themes ├── sessions/ ← Session history ├── git/ ← Git-installed packages (via pi install) └── npm/ ← npm-installed packages (via pi install)

Project-local structure (optional)

If you keep a dedicated research workspace, you can also use project-local config:

~/research-projects/ ├── AGENTS.md ← Project-specific context/instructions ├── .pi/ ← Project-local Pi config (optional) │ └── settings.json ← Project-level settings override ├── quantum-computing-2025/ ← Research output │ ├── report.md │ ├── sources.json │ ├── claims.md │ └── summary.txt └── crispr-gene-therapy/ ← Another research output
File/DirPurposeEdit Frequency
settings.jsonModel, provider, compaction, transport settingsRarely — set once
AGENTS.mdGlobal context for research conventionsWhen you refine output preferences
SKILL.mdThe research methodology — the core logicWhen you improve the research process
sessions/Session history — Pi remembers past sessionsAuto — grows with each session
skills/pi-skills/Brave Search and browser tools (cloned from GitHub)Update with cd ~/.pi/agent/skills/pi-skills && git pull

8 How the Research Pipeline Works

When you invoke research "topic", here's the exact sequence:

Step 1 — Skill Loading

--skill ~/.pi/agent/skills/deep-research force-loads our research skill. Pi reads the full SKILL.md into the system prompt so the agent has the complete methodology before it starts.

Step 2 — Context Assembly

Pi walks up from the current directory, collecting any AGENTS.md files along the way, plus the global ~/.pi/agent/AGENTS.md. All of these are concatenated into the context.

Step 3 — Discovery Phase

The agent formulates multiple search queries and casts a wide net. It uses the brave-search skill's scripts (via Pi's built-in bash tool) for initial discovery, and the browser-tools skill for JavaScript-heavy sites that need full rendering.

Step 4 — Cross-Referencing

Claims are mapped against sources. The agent explicitly identifies where sources agree, where they disagree, and where only a single source exists for a claim — all following the methodology in the skill.

Step 5 — Report Writing

The agent uses Pi's built-in write tool to save all output files to the specified directory. Output is structured markdown — human-readable and machine-parseable.

Step 6 — Exit

Because we used -p (print mode), Pi completes the task and exits. No lingering sessions, no interactive prompts.

💡 Session continuity: Even in print mode, Pi saves the session. You can resume it later with pi --continue or pi --resume to ask follow-up questions about the research.

9 Usage Examples

Basic research

research latest advances in solid-state batteries

Creates ./research/latest-advances-solid-state-batteries/ in your current directory.

Custom output location

research AI regulation in the EU --output ~/projects/policy-brief

Interactive mode with follow-ups

pi --skill ~/.pi/agent/skills/deep-research # Then type your research request in the interactive session

Resume a previous research session

pi --continue # Or browse previous sessions pi --resume

Use a specific model for research

pi --model claude-sonnet-4 --skill ~/.pi/agent/skills/deep-research -p \ "Research quantum computing 2025"

Read-only mode (no file writes during research)

pi --tools read,grep,find,ls,bash --skill ~/.pi/agent/skills/deep-research -p \ "Research CRISPR and just print findings to screen"

10 Output Structure

Every research task produces a consistent set of files:

./research/quantum-computing-2025/ ├── report.md ← Full research report with citations ├── sources.json ← Machine-readable source metadata ├── claims.md ← Cross-reference matrix └── summary.txt ← One-paragraph executive summary

sources.json format

[ { "id": 1, "url": "https://example.com/article", "title": "Quantum Computing Progress in 2025", "author": "Dr. Jane Smith", "published": "2025-03-15", "accessed": "2025-06-05", "type": "journal", "credibility": 5, "key_claims": ["Claim A", "Claim B"] } ]

claims.md format

# Cross-Reference Matrix ## Claim: "1000-qubit systems expected by 2027" - Status: ✅ Confirmed - Sources: [1] Nature Physics, [4] IBM Blog, [7] MIT Review - Notes: All three sources independently cite this timeline ## Claim: "Quantum advantage achieved for drug discovery" - Status: ❌ Disputed - For: [2] D-Wave Press Release - Against: [5] Scott Aaronson's analysis - Notes: D-Wave has commercial interest; independent verification lacking

11 Going Further — A Pi Extension

If you want more control than a skill can offer, Pi's extension system lets you write TypeScript that hooks into the agent runtime. Extensions are loaded via jiti — no compilation needed. Here's a minimal extension that adds a custom save_research tool:

// ~/.pi/agent/extensions/research-tools.ts import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; import { Type } from "typebox"; export default function(pi: ExtensionAPI) { // Register a custom tool for structured research output pi.registerTool({ name: "save_research", label: "Save Research", description: "Save research results to a structured directory", parameters: Type.Object({ topic: Type.String({ description: "Research topic slug" }), report: Type.String({ description: "Markdown report content" }), sources: Type.String({ description: "JSON sources array" }), summary: Type.String({ description: "One-paragraph summary" }), }), async execute(toolCallId, params, signal) { const fs = await import("fs/promises"); const dir = `./research/${params.topic}`; await fs.mkdir(dir, { recursive: true }); await fs.writeFile(`${dir}/report.md`, params.report); await fs.writeFile(`${dir}/sources.json`, params.sources); await fs.writeFile(`${dir}/summary.txt`, params.summary); return { content: [{ type: "text", text: `Research saved to ${dir}/` }], details: {}, }; } }); };

Load the extension with:

pi -e ~/.pi/agent/extensions/research-tools.ts --skill ~/.pi/agent/skills/deep-research
The extension is optional. The skill alone handles everything via Pi's built-in bash and write tools. Extensions are for when you want programmatic control — validation, custom formatting, automated post-processing, or spawning sub-agents via tmux.

12 Version Control

The research agent is entirely defined by plain files. Version-controlling it is straightforward.

Option A: Track just the research skill and config

# Create a repo for your Pi customizations mkdir ~/pi-config && cd ~/pi-config git init # Copy skill and context files cp -r ~/.pi/agent/skills/deep-research ./skills/ cp ~/.pi/agent/AGENTS.md ./ cp ~/.pi/agent/settings.json ./ # Optional: include extension cp -r ~/.pi/agent/extensions/research-tools.ts ./extensions/ git add . git commit -m "Initial research agent config"

Option B: Track the entire ~/.pi/agent directory

cd ~/.pi/agent git init # Create a .gitignore cat > .gitignore <<'EOF' sessions/ git/ npm/ skills/pi-skills/ *.log EOF git add . git commit -m "Pi agent configuration"

What to track vs. what to ignore

Track (git add)Ignore (.gitignore)
skills/ — research methodologysessions/ — session history (large, machine-specific)
AGENTS.md — context conventionsgit/, npm/ — packages installed via pi install
settings.json — model/provider configskills/pi-skills/ — cloned from GitHub, reinstall on target
extensions/ — custom TypeScript extensionsAnything with API keys
prompts/, themes/ — templates and UI

13 Transfer to Another Computer

There are three ways to move the research agent to another machine:

Method 1: Git clone (recommended)

# On the new machine (install Pi first) npm install -g --ignore-scripts @earendil-works/pi-coding-agent # Clone your config git clone git@github.com:youruser/pi-config.git /tmp/pi-config # Copy into place cp -r /tmp/pi-config/skills/* ~/.pi/agent/skills/ cp /tmp/pi-config/AGENTS.md ~/.pi/agent/ cp /tmp/pi-config/settings.json ~/.pi/agent/ # Reinstall pi-skills git clone https://github.com/badlogic/pi-skills ~/.pi/agent/skills/pi-skills cd ~/.pi/agent/skills/pi-skills/brave-search && npm install cd ~/.pi/agent/skills/pi-skills/browser-tools && npm install # Set up API key export ANTHROPIC_API_KEY="your-key-here" # Add shell function to ~/.bashrc # (copy the research() function from Section 6) # Ready to use research your topic here

Method 2: Symlink from dotfiles repo

# If you use a dotfiles repo ln -s ~/dotfiles/pi/skills/deep-research ~/.pi/agent/skills/deep-research ln -s ~/dotfiles/pi/AGENTS.md ~/.pi/agent/AGENTS.md

Method 3: rsync/scp for quick copy

rsync -av --exclude 'sessions/' --exclude 'git/' \ --exclude 'npm/' --exclude 'skills/pi-skills/' \ ~/.pi/agent/ \ user@other-machine:~/.pi/agent/
⚠️ API keys are in environment variables, not files. Pi reads ANTHROPIC_API_KEY, OPENAI_API_KEY, etc. from the environment. You need to set them on the target machine separately — they're not part of the ~/.pi/agent/ directory.

🎯 Key Takeaways

  • Skills define behavior. The SKILL.md file IS the agent's research methodology. It follows the Agent Skills standard — the same format works with Claude Code, Codex, and other compatible agents.
  • AGENTS.md provides context. Hierarchical context files let you set global research conventions that apply everywhere, plus project-specific instructions per workspace.
  • Shell functions assemble invocations. Pi has no built-in personas — instead, you compose behavior by selecting the right combination of --skill, --tools, -p, and other flags per invocation. This is by design.
  • The agent only activates when called. Progressive skill disclosure means Pi won't use the research methodology during normal coding sessions — it only loads the full skill when the task matches or you force it with --skill.
  • Output is predictable. Every research task produces the same file structure — report.md, sources.json, claims.md, summary.txt.
  • Everything is just files. Skills, AGENTS.md, settings.json, extensions — all plain text. Git version control works out of the box.
  • Extensions add superpowers. When a skill isn't enough, TypeScript extensions give you custom tools, event hooks, and full agent runtime control.
  • Same skill works elsewhere. Because it follows the Agent Skills standard, the same SKILL.md file works in Claude Code (.claude/skills/) and Codex (.agents/skills/) with no changes.
Agent Daily · The Pi Side of Agents · June 2025