AI Coding Assistants
One copy-paste block that teaches any AI coding tool how to integrate EvalKit correctly.
If you’re integrating EvalKit with the help of an AI coding tool — Claude Code, Cursor, OpenCode, Windsurf, Copilot, or anything else that reads project rules or a system prompt — paste the block below into it first. It’s tool-agnostic: drop it into a rules file, a project skill, or the start of a chat, then ask the assistant to add tracing/evaluation to your app.
evalkit-skill.md — paste into any AI coding tool
# EvalKit integration skill
EvalKit ("syntropylabs-evalkit") is a tracing + evaluation SDK for Python and
TypeScript/Node.js. Use this when asked to add tracing, evaluation, or LLM
observability to an app.
## Install
- Python: pip install syntropylabs-evalkit (import name stays "evalkit")
- TypeScript/Node: npm install syntropylabs-evalkit
## Core rule: init() does everything
Call evalkit.init() ONCE at app startup, before the app handles traffic.
After that, do NOT manually wrap LLM calls, HTTP requests, or DB queries —
they are already auto-instrumented. Never invent an API like
"evalkit.trace_llm_call()" — it does not exist.
Python:
import evalkit
evalkit.init(
subscription_key="tk_live_...", # required, from the dashboard
service_name="my-api",
environment="production", # development | staging | production
)
# ... app runs ...
evalkit.flush() # call before process exit
TypeScript:
import evalkit from "syntropylabs-evalkit";
evalkit.init({
subscriptionKey: "tk_live_...",
serviceName: "my-api",
environment: "production",
});
// before exit: await evalkit.flush();
## Already auto-instrumented after init() — do not wrap these manually
- LLM providers: OpenAI, Anthropic (incl. Bedrock/Vertex), Google Gemini,
Cohere, Mistral (Python), LiteLLM (Python), Groq/OpenAI-compatible via
the OpenAI client.
- HTTP: requests/httpx (Python), fetch/axios/node:http (TypeScript).
- Databases (auto): psycopg/asyncpg/PyMySQL/redis/pymongo (Python),
pg/mysql2/mongoose/ioredis (TypeScript). SQLAlchemy is the one manual
call: evalkit.patch_sqlalchemy_engine(engine).
- Logs: the "logging" module (Python) / console.* (TypeScript).
- Tool calls the model makes — attached to the LLM call automatically,
no manual spans needed.
## Web framework middleware — exactly one line
- FastAPI/Starlette: app.add_middleware(evalkit.EvalKitMiddleware)
- Flask: evalkit.instrument_flask(app)
- Django: add "evalkit.EvalKitDjangoMiddleware" to MIDDLEWARE
- Express: app.use(evalkit.expressMiddleware())
- Fastify: await app.register(evalkit.fastifyPlugin())
- NestJS: await evalkit.enableNestjsAutoTrace(app) — after NestFactory.create()
## Tracing the user's own functions (only if they ask for it)
- Python: @evalkit.trace_function() for one function, @evalkit.trace_tool()
for a tool the model calls, @evalkit.traced on a class,
evalkit.trace_module(mod) / evalkit.trace_package(pkg) for a whole
module/package. Python already auto-traces the caller's own source tree
by default — don't sprinkle trace_function everywhere redundantly.
- TypeScript: evalkit.traceFunction("name", fn), evalkit.traceTool("name", fn),
the @Traced() class decorator, evalkit.traceObject({...}, { prefix }).
## Offline evaluation (deterministic, no LLM cost)
Python:
scores = evalkit.evaluate(output=reply, expected_tools=[...],
tool_calls=[...], constraints={...})
TypeScript:
const { scores } = evalkit.evaluate({ output: reply, expectedTools: [...],
toolCalls: [...], constraints: {...} });
## Scenario simulation (synthetic-user testing of an agent)
Three calls, in order:
generate_scenarios(...) -> simulate_user(entrypoint, scenarios) ->
evaluate_simulation(simulation_id, collection_id=..., provider=...,
model=..., api_key=...)
The entrypoint function runs ONE turn and receives ctx with message /
session_id / state / turn; return a string or an AgentTurnResult.
## Hard rules — do not violate
1. Never invent SDK function/method names. If unsure whether something
exists, say so instead of guessing.
2. Never create manual spans for anything already auto-instrumented
(see the list above) — that duplicates data.
3. subscription_key / subscriptionKey is required and comes from the
user's own dashboard (Tracing -> create a trace project) — never
hardcode a placeholder value as if it were real.
4. Always call flush() (Python) / await flush() (TypeScript) before the
process exits — especially in short-lived scripts or serverless
functions, where spans can otherwise be dropped.
5. Full docs: https://syntropylabs.ai/docsFor a broader, machine-readable summary of the whole product (not just SDK integration) — the kind a general-purpose LLM crawler reads — see `/llms.txt`.