agent/ directory and Eve runs it on Vercel Functions. In this guide you’ll scaffold a weather agent, wire it to Arize AX with two instrumentation files, run a session, and explore the resulting traces: the per-turn breakdown of model steps, model calls, and tool executions.
Eve emits OpenTelemetry GenAI spans, and Arize AX ingests them through the @arizeai/openinference-vercel span processor. This is the same processor the Vercel AI SDK integration uses.
Prerequisites
- Node.js 24+ (Eve’s CLI requires it)
- Eve 0.62 or later (this guide scaffolds the latest)
- An Arize AX account (sign up). Copy your Space ID and API Key from Space Settings.
- An
AI_GATEWAY_API_KEYfor Eve’s model routing (or runvercel linkto use aVERCEL_OIDC_TOKEN)
Step 1: Scaffold the agent
Create a new Eve agent. The CLI scaffolds the project, installs dependencies, and initializes Git:agent/ directory with instructions.md (the system prompt), agent.ts (runtime config), and channels/eve.ts (the built-in HTTP channel). Replace the scaffolded instructions in agent/instructions.md:
agent/agent.ts:
openai/gpt-5.4-mini or another provider/model if you prefer.
Add a tool so the agent has something to call. Each file in agent/tools/ is one tool, and the runtime tool name comes from the filename. Create agent/tools/get_weather.ts:
Step 2: Add Arize AX observability
Tracing in Eve is configured with files in theagent/instrumentation/ directory. Eve discovers every file there and loads them once when the server starts, before any agent or tool code runs. That ordering is why tracing lives in its own directory: OpenTelemetry has to be registered before the agent code runs, otherwise its spans are never captured. Because Eve owns the startup and registers the OpenTelemetry pipeline itself, there’s no per-call telemetry flag to set, unlike the raw Vercel AI SDK, where you pass experimental_telemetry on every call.
Each file exports one piece of the setup:
otel()declares the process-wide OpenTelemetry settings: the resource attributes and what content spans capture. Declare it once.otelIntegration()declares one trace destination. Add one file per destination; Eve combines them into one pipeline.
agent/instrumentation/otel.ts. It sets the model_id resource attribute, which Arize uses to route spans to a project; without it the OTLP endpoint rejects spans:
agent/instrumentation/otel.ts
workflow.*, step.*, and queue and HTTP spans), well over a hundred per turn. Filtering with isOpenInferenceSpan drops them and keeps only the agent, model, and tool spans. Setting reparentOrphanedSpans: true re-roots any AI span whose dropped parent was a non-AI span. Eve already roots each turn at its own invoke_agent span, so this is a safeguard rather than a fix.
Create agent/instrumentation/arize.ts to declare Arize AX as a destination. It registers the OpenInference span processor with an OTLP exporter pointed at Arize:
agent/instrumentation/arize.ts
OpenInferenceSimpleSpanProcessor exports each span as it ends, so there’s no forceFlush to call on exit, even on the short-lived serverless functions Eve runs on. reparentOrphanedSpans runs statelessly at span start, so it adds no buffering.tracePolicy in otel(). See Control what content is captured.
Step 3: Run a session
Set your credentials and start the dev server:http://127.0.0.1:2000 by default (pass --port to change it). Open a session against the built-in HTTP channel. The agent should call your get_weather tool and answer (for example, “The weather in Brooklyn is sunny and 72°F.”):
202 with the session id in the x-eve-session-id response header, but not the model’s reply; Eve runs the turn in the background. Stream the session to watch it run and see the answer:
session.started, the get_weather actions.requested and action.result, streaming message.appended deltas, and a message.completed event with the full reply:
Step 4: Explore the trace in Arize AX
Open your Arize AX space and select theweather-agent project. Each turn is one trace, rooted at Eve’s invoke_agent agent span. Eve runs the turn as a series of model steps. Each step is an agent.step chain span holding the chat LLM span for the model call. When the model calls a tool, the step also holds an agent.action chain span over the execute_tool tool span:
- The
chatLLM span, with the prompt, the model’s response, and input and output token counts. - The
execute_tooltool span, carryingtool.name, with its arguments and returned result. - Session grouping. Every span carries a
session.idtaken from Eve’s session id (gen_ai.conversation.id), so the two turns from your follow-up message group under one session on the Sessions tab.
Next steps
- Add more tools or a skill and watch new
execute_toolspans appear per turn. - Gate a tool behind an approval or delegate to a subagent, and see the
agent.approvaland subagent spans described in the integration guide. - Set up an LLM-as-a-judge evaluator over the captured spans to score the agent’s responses.
- For the processor options, content capture, and troubleshooting, see the Vercel Eve integration guide.