Basketball Demo

Minimal end-to-end Orchid example: GenericAgents with built-in tool classes, PostgreSQL storage, cross-agent skills, and an event-driven trivia agent.

What this demonstrates

The basketball demo is Orchid's "hello world". It wires two chat-facing GenericAgent instances — an NBA stats expert and a sports psychologist — using built-in tools implemented as OrchidTool subclasses in the example's Python package, plus the PostgreSQL storage backend provided by the orchid-storage-postgres plugin. A third agent, trivia_generator, is activated by the example's Pollen + Bloom schedule to produce a weekday morning trivia digest. No MCP servers, no external APIs, and no custom agent classes are required — the agent definitions live in agents.yaml.

Run it

git clone https://github.com/gadz82/orchid-examples
cd orchid-examples/basketball
cp .env.example .env
docker compose up --build

This starts the API (http://localhost:8080), the web UI (http://localhost:3000), PostgreSQL, Qdrant, and the MCP gateway. Ollama runs on your host with llama3.2 and nomic-embed-text (plus minicpm-v for document uploads).

Configuration walkthrough

orchid.yml sets the runtime environment — LLM, storage backend, and pointer to agent configs:

# orchid.yml (trimmed)
agents:
config_path: examples/basketball/agents.yaml

llm:
model: ollama/llama3.2
ollama_api_base: http://host.docker.internal:11434

auth:
dev_bypass: true          # skip identity check for local dev

storage:
class: orchid_storage_postgres.OrchidPostgresChatStorage
dsn: postgresql://orchid:${POSTGRES_PASSWORD}@postgres:5432/orchid

# ...truncated

Agent configs define the agents, their tools, the cross-agent skills, and the morning-trivia event wiring:

# agents.yaml (trimmed)
version: "1"

defaults:
llm:
  model: "ollama/llama3.2"
  temperature: 0.2
rag:
  enabled: false

tools:
get_player_stats:
  class: "examples.basketball.tools.basketball.GetPlayerStatsTool"
  description: "Get stats for an NBA player (points, rebounds, assists, team, position)"
compare_players:
  class: "examples.basketball.tools.basketball.ComparePlayersTool"
  description: "Side-by-side comparison of two NBA players with advantage analysis"
assess_motivation:
  class: "examples.basketball.tools.psychology.AssessMotivationTool"
  description: "Assess a player's motivation level, drive type, and risk factors"
# ...truncated

skills:
player_performance_review:
  description: "Get a player's stats then assess their motivation"
  steps:
    - agent: basketball
      instruction: "Look up the player's current stats and performance data"
    - agent: psychologist
      instruction: "Assess their motivation and suggest mental strategies"

agents:
basketball:
  description: "NBA basketball expert with player stats and roster tools."
  prompt: |
    You are a Basketball Expert AI assistant. Provide insightful
    basketball analysis using the stats from your tools.
  tools: [get_player_stats, compare_players, get_team_roster]

psychologist:
  description: "Sports psychologist for motivation and team dynamics."
  prompt: |
    You are a Sports Psychologist specialized in basketball performance.
  tools: [assess_motivation, suggest_mental_strategy, analyze_team_dynamics]

trivia_generator:
  description: "Event-driven agent that produces the morning trivia digest."
  tools: [get_player_stats, get_team_roster]

# ...truncated

What to look for

  • storage.class: orchid_storage_postgres.OrchidPostgresChatStorage → the orchid-storage-postgres plugin provides chat persistence; any importable OrchidChatStorage subclass can be plugged in here, and the framework resolves it via dotted import at startup.
  • tools.<name>.class → built-in tools are OrchidTool subclasses referenced by dotted path; plain Python functions referenced with handler: are also supported.
  • skills.player_performance_review.steps → a cross-agent skill chains two agents in sequence; the supervisor executes each step in order and passes context forward.
  • events.schedules + events.triggers → a weekday cron schedule activates the event-driven trivia_generator agent. See Pollen + Bloom.
  • defaults.rag.enabled: false → RAG is disabled globally; individual agents can override this per-field.
  • auth.dev_bypass: true → skips identity resolution for local development; remove this in production.

Related concepts