Quick start
This guide takes you from nothing to a working pair of services, with a first pipeline triggered by a real webhook. VectorStep orchestrates: it receives webhooks, resolves the matching pipeline, and gates each step’s result before continuing. The Gateway executes: it owns the full agentic loop for a step (LLM calls, MCP tool execution, multi-turn conversation) and hands VectorStep back one clean result — never the intermediate tool calls. Start the Gateway first, since VectorStep calls out to it.
Prerequisites
Section titled “Prerequisites”- macOS or Linux (or Windows via WSL2 — the commands below are bash scripts, so there’s no native Windows path yet)
- Python 3.11+,
git - An LLM provider API key (Anthropic, OpenRouter, Google, Azure OpenAI, or a local Ollama — the Gateway supports all of them)
- Nothing else. Local development runs on SQLite with zero infrastructure; PostgreSQL is recommended for production.
1. Start the Gateway
Section titled “1. Start the Gateway”curl -sSL https://raw.githubusercontent.com/bantex01/VectorStep-Gateway/main/install-gateway.sh | bashThis clones the Gateway into ~/.vectorstep-gateway/, creates a virtualenv,
installs dependencies, and copies the config template. Safe to run again
later — it never overwrites an existing config.yaml or agents/.
cd ~/.vectorstep-gateway# Edit config.yaml — set your LLM provider keys and any MCP serversFor a first agent, copy the bundled sample rather than writing one from scratch — it needs no MCP tools, just a model, so it runs with nothing more than an API key. Once you’re past this guide, Tutorials walks through writing a real one.
cp -r samples/agents/generic-pipeline-step agents/Copy it as-is, without renaming the directory — the Gateway requires
agent.yaml’s name: field to match its containing directory exactly, and
skips (with a logged error) any agent where they don’t.
The sample agent defaults to an Anthropic model, which is why that’s the key exported below. The Gateway also supports OpenRouter, Google, Azure OpenAI, and Ollama — see Providers for every model string format.
export ANTHROPIC_API_KEY=sk-ant-...source .venv/bin/activate && python -m gateway.mainOn first run the Gateway generates an identity and an operator token:
cat ~/.vectorstep-gateway/identity/device-auth.json# Copy the 'operator' token — VectorStep's config needs it in the next stepBoth config.yaml and agents/ are gitignored — they hold credentials and
environment-specific agent definitions.
2. Start the VectorStep service
Section titled “2. Start the VectorStep service”curl -sSL https://raw.githubusercontent.com/bantex01/VectorStep/main/install-service.sh | bashThis clones VectorStep into ~/.vectorstep/, with the venv and config set up
inside ~/.vectorstep/service/ (SQLite by default — no Postgres prompt).
Safe to run again later — it never overwrites an existing config.yaml.
cd ~/.vectorstep/serviceOpen config.yaml and paste the operator token from step 1 into
executors.gateway.token:
executors: gateway: token: <paste the operator token here>Then start it:
source .venv/bin/activate && uvicorn src.main:app --reload --port 80003. Add a pipeline
Section titled “3. Add a pipeline”Still inside ~/.vectorstep/service/ from step 2. Pipelines are YAML files
in pipelines/; reusable steps live in steps/ — both empty on a fresh
install. Create both of the files below — a complete pipeline built for the
agent you just made, with no MCP tools required, since
generic-pipeline-step reasons from the alert payload alone. (The samples
bundled in samples/pipelines/ and samples/steps/, one level up, are real
production examples wired to OpenClaw and external tools like Jira and
Confluence — worth exploring later, but not a fit for this walkthrough.)
Create steps/first-line-triage.yaml:
name: first-line-triagedescription: First-line triage for a critical alert — no MCP tools required.executor: gatewayexecutor_config: agent: generic-pipeline-step session_key: "agent:generic-pipeline-step:{{pipeline_run_id}}:{{current_step}}"confidence_threshold: 0.60on_low_confidence: escalateprompt_template: | A {{severity}} alert fired for {{labels.service}} in {{labels.environment}}. Summary: {{summary}}
Summarise what's happening. Set confidence based on how clearly the alert data explains the problem — not on how serious it is.
Return JSON only, no other text: { "confidence": 0.0, "summary": "One sentence: what's happening and how serious", "next_step_context": "Focused brief for whatever handles this next", "reasoning": { "supports": "Evidence that makes this alert credible", "contradicts": "Evidence that suggests noise or a false positive", "assumptions": "What you're assuming in the absence of data" } }Create pipelines/alert-triage.yaml:
name: alert-triagedescription: First-line triage for critical alertstrigger: match: { source: alertmanager, severity: critical } dedup: enabled: false
context_template: include: - severity - summary
steps: - name: triage use: first-line-triage # reusable step from your step library executor: gateway executor_config: agent: generic-pipeline-step confidence_threshold: 0.75 on_low_confidence: escalate # below the bar, a human sees it insteadcontext_template.include is what makes {{severity}} and {{summary}}
resolve to real values in the prompt above — only fields listed here are
pulled from the incoming alert; everything else you might reference (like
{{labels.service}}) is available without it. Leave a field out and it
silently renders as an empty string rather than erroring, so it’s easy to
miss if you add a new {{...}} reference later and forget to list it here.
dedup.enabled: false here is a quick-start convenience, not a general
recommendation — the bundled test fixture has no unique fingerprint, so
every replay hashes identical and would otherwise hit the (correct, and
normally desirable) service-wide dedup window. See Idempotency &
deduplication for
how it works against real alert traffic.
Reload without restarting:
curl -X POST http://localhost:8000/reload# → {"status": "reloaded", "pipelines_loaded": 1}4. Trigger it
Section titled “4. Trigger it”Send a test webhook using one of the bundled fixtures:
curl -X POST "http://localhost:8000/webhook?source=alertmanager&allow_testing=true" \ -H "Content-Type: application/json" \ -d @tests/fixtures/alertmanager_critical.json# → {"status": "accepted", "run_id": "<uuid>"}New pipelines default to stage: testing — fully executable, but inert to
real ingestion traffic until you deliberately opt in with
allow_testing=true (or promote the pipeline itself to stage: production
later). See Pipeline stages for what each stage
actually gates.
5. Watch it run
Section titled “5. Watch it run”Open http://localhost:8000/ui/ — the dashboard shows the run live. Click into it for the full run log: every step’s prompt, output, confidence score, and the Trust panel explaining exactly how each gating decision was made.
What you should see
Section titled “What you should see”Don’t expect a solved incident — expect an honest escalation, and that’s
the point. The triage step should show a badge reading escalated, with
confidence below the pipeline’s confidence_threshold: 0.75, and a summary
that references the real alert content now flowing through {{severity}}
and {{summary}} — something like “A critical alert fired for
payments-api: error rate exceeded 5% for 5 minutes. No deeper diagnostic
data (logs, traces, upstream dependencies) is available to confirm a root
cause or rule out a false positive.”
That’s the agent being honest, not broken: generic-pipeline-step has
tools: [] — no MCP tools — so even with a concrete metric breach in hand,
it has no way to independently verify anything beyond what the alert itself
states. It correctly recognises it can’t diagnose the actual cause from
that alone, scores its own confidence accordingly, and the pipeline’s
on_low_confidence: escalate gate does exactly what it’s supposed to:
refuse to let an under-verified assessment pass as if it were a real
finding. Expand REASONING on the step to see the model’s own
supports/contradicts/assumptions breakdown behind that score.
One thing that can look contradictory at first: the step may show
proceed: true right next to an escalated badge. Those are two different
signals — proceed is the agent’s own opinion (from its soul.md) about
whether its instructions call for stopping outright; the escalation itself
is a separate, pipeline-level decision driven purely by confidence falling
below the threshold. An agent can think there’s no reason to abort and
still get escalated for a human to check, because it didn’t feel confident
about what it found.
Giving this same agent real tools — so its low confidence turns into a grounded, higher one — is exactly what Tutorial: build your first agent does next.
You can also live-tail from the run detail page, or query the API directly:
curl http://localhost:8000/runs # newest firstcurl http://localhost:8000/runs/<run_id> # full detail with per-step confidenceWhere next
Section titled “Where next”If any of this — the Gateway, agents, MCP tools, confidence gating — is new to you, don’t jump straight to the reference docs below. Go to Tutorials next: it builds a real agent from scratch, wires it to two MCP servers, and then turns on gating one signal at a time, hands-on. It builds directly on the pipeline you just triggered.
Once you’re comfortable with the mechanics:
- How confidence and calibration work — the trust vector (S/V/G/D) and every knob that affects it. Read this before turning on any enforcement.
- Pipeline schema — the full YAML reference: verifiers, grounding, parallel groups, fan-out, flow control.
- Verifiers — adding a second opinion to a
step, and when to use
criticvsindependentmode.