Skip to main content
BB AI SDK: 0.1.9 (pin when installing from Artifactory — see Installation). Starter repo version: see the repository badge / pyproject.toml (independent of the SDK).
The Starter Multi-Agent (Level 1) demonstrates patterns for multiple agents working together using Agno Teams. It supports delegation, collaboration, and coordination modes to handle more complex tasks that require specialization.
This repository can be used as a base template for creating your own application. Select starter-multi-agent as the repository_template when provisioning a new repository via Self Service.

GitHub repository

View source code, releases, and issues

Prerequisites

  • Python 3.11+: Managed via UV (see pyproject.toml)
  • UV Package Manager: Modern Python package manager (replaces pip/poetry)

Quick start

1. Clone and install UV

git clone https://github.com/bb-ecos-agbs/starter-multi-agent.git
cd starter-multi-agent

# Install UV (macOS)
brew install uv

# Install UV (Linux/WSL)
curl -LsSf https://astral.sh/uv/install.sh | sh

2. Set up environment

# Create virtual environment
uv venv --python 3.11
source .venv/bin/activate  # macOS/Linux
# Or .venv\scripts\activate # Windows

# Copy environment template
cp env.template .env

3. Configure credentials

Update .env with Artifactory credentials (when resolving bb-ai-sdk from the Backbase index), AI Gateway keys, and observability. Observability vars are read by bb-ai-sdk, not src/config/config.py.
# Artifactory (when using the Backbase PyPI index)
export UV_INDEX_BACKBASE_USERNAME=your-email@backbase.com
export UV_INDEX_BACKBASE_PASSWORD=your-Artifactory-token

# AI Gateway (AI_GATEWAY_API_KEY preferred; AZURE_OPENAI_API_KEY is a fallback)
AI_GATEWAY_ENDPOINT=https://ai-gateway.backbase.cloud
AI_GATEWAY_API_KEY=your-api-key

# Observability — pick one path (see Observability docs)

# Option A: Langfuse (typical local dev)
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_HOST=https://langfuse.backbase.cloud

# Option B: Custom OTLP (Grand Central — omit LANGFUSE_*)
# OTEL_EXPORTER_OTLP_ENDPOINT=https://your-otlp-endpoint
# OTLP_ENDPOINT=https://your-otlp-endpoint
# OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer your-token
# OTEL_RESOURCE_ATTRIBUTES=project=<your-project-identifier>
# OTEL_SERVICE_NAME=starter-multi-agent

# Tracing on by default; set OBSERVABILITY_ENABLED=false to disable export

# Application
HOST=0.0.0.0
PORT=8000
APP_ENV=local
LOG_LEVEL=INFO

# Logging redaction (optional — merged with SDK built-ins)
# BB_AI_SDK_REDACTION_PATTERNS='[{"name":"iban","pattern":"...","replacement":"..."}]'

# Web proxy (required for local dev on Backbase network)
HTTP_PROXY=http://webproxy.infra.backbase.cloud:8888
HTTPS_PROXY=http://webproxy.infra.backbase.cloud:8888
NO_PROXY=localhost,127.0.0.1,::1

4. Install dependencies and run

source .env && uv sync
uv run python -m src.main
VPN and Web Proxy: Required for local development. If traces do not export, extend NO_PROXY for your Langfuse, Grafana, or OTLP host — see Observability — proxy configuration.

Team modes

The starter demonstrates three core multi-agent patterns:

Delegation mode

Content Team: Team leader delegates specific tasks sequentially (Researcher → Writer → Reviewer). Endpoint: /run/content_team

Collaboration mode

Collaboration Team: Agents (Researcher and Writer) work together, sharing context to solve a problem. Endpoint: /run/collaboration_team

Coordination mode

Coordinator Team: Team leader orchestrates workflow and uses tools directly for coordination. Endpoint: /run/coordinator_team

API usage

curl -X POST "http://localhost:8000/run/content_team" \
  -H "Content-Type: application/json" \
  -H "X-Observability-Project: my-project" \
  -d '{"query": "Write an article about AI trends"}'

Project structure

starter-multi-agent/
├── .github/                    # CI/CD workflows
├── promptfoo_config/           # Evaluation configurations
├── prompts/                    # Centralized prompt definitions
├── providers/                  # AI provider configurations
├── src/
│   ├── main.py                 # Application entry point
│   ├── logger.py               # Logging configuration
│   ├── agents/                 # Agent and team implementations
│   ├── api/
│   │   ├── app.py              # FastAPI, configure_observability, teams
│   │   ├── openai_http_errors.py  # OpenAI/Agno → HTTP (app-owned)
│   │   └── schemas.py
│   └── config/                 # App/server settings (not OTLP/Langfuse keys)
├── evals/                      # bb-ai-sdk evals entry (configure_observability)
├── tests/
├── redteam.yaml
├── Dockerfile
└── pyproject.toml              # bb-ai-sdk[guardrails,instrument-fastapi,instrument-agno]==0.1.9

Observability

Install bb-ai-sdk[guardrails,instrument-fastapi,instrument-agno]==0.1.9 from Artifactory (see pyproject.toml). In src/api/app.py:
configure_observability(
    fastapi_app=app,
    framework="agno",
    service_name="starter-multi-agent",
    environment=settings.app_env,
)
Per team run, run_team() uses await team.arun(...) (not sync run) and scope(agent_name=..., trace_name=..., trace_input=...) so you get one trace per HTTP request. Optional header X-Observability-Project sets bb.project on spans.
ConcernWhere
TracerProvider, OTLP/Langfuse, FastAPI + Agno + HTTPX + threadingconfigure_observability(...) in app.py
Service identityservice_name="starter-multi-agent" → Resource service.name
bb.projectHeader X-Observability-Project (middleware)
bb.agent.name, bb.trace.name, bb.trace.inputscope(agent_name=..., trace_name=..., trace_input=...) in run_team()
Model errors → HTTP statussrc/api/openai_http_errors.py (application policy)
NeMo guardrails per teaminit_guardrails(...) in the FastAPI lifespan handler
There is no src/observability.py — setup lives in the SDK plus the calls above. Full key list and constants: BB AI SDK — Backbase attribute keys. Backends: Export paths — Langfuse via LANGFUSE_*, Grafana via init(backend="grafana", otlp_endpoint=...) then configure_observability(..., init_observability=False), or custom OTLP via OTEL_EXPORTER_OTLP_ENDPOINT (or OTLP_ENDPOINT) plus OTEL_RESOURCE_ATTRIBUTES=project=<your-project-identifier> when your operations team requires it. Evals call the same service_name from init_observability() in evals/__init__.py (no fastapi_app).

Logging and redaction

src/logger.py uses STANDARD_FORMAT, DEFAULT_DATEFMT, and LOG_LEVEL from app settings. After basicConfig, it calls bb_ai_sdk.logging.init(capture_warnings=True) so API keys and tokens are redacted in logs and share the same patterns as span attributes. Log lines include [trace_id=… span_id=…] for correlation with traces. Optional: BB_AI_SDK_REDACTION_PATTERNS* in .env.

Development

Run tests

source .env && uv sync --extra dev
uv run python -m pytest tests/ -v

CI/CD

Standard workflows are pre-configured in .github/workflows:
  • PR Checks: Linting, testing, and validation.
  • Build and Publish: Docker image creation on merge.
  • Release: Automated versioning and release notes.
See CI/CD workflows for pipeline details.

Next steps