Quickstart
Run your first portable evaluation against an agent in a few minutes.
1. Install
py -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install "ecp-runtime==0.7.0" "ecp-sdk==0.7.0"
For framework demos, install the matching SDK extra:
pip install "ecp-sdk[langchain]==0.7.0" langchain-openai
pip install "ecp-sdk[crewai]==0.7.0" crewai
pip install "ecp-sdk[pydanticai]==0.7.0" pydantic-ai
pip install "ecp-sdk[llamaindex]==0.7.0" llama-index llama-index-llms-openai llama-index-tools-yahoo-finance
2. Create a starter eval
ecp init
ecp validate ecp_eval/manifest.yaml
ecp run --manifest ecp_eval/manifest.yaml --json
3. Run the flagship demo
The customer support demo checks final output, required tool calls, and evaluator-safe audit context.
ecp validate examples/customer_support_demo/manifest.yaml
ecp run --manifest examples/customer_support_demo/manifest.yaml --report report.html
4. Run a framework demo
ecp run --manifest examples/langchain_demo/manifest.yaml
Other manifests live in:
examples/plain_python_demo/manifest.yamlexamples/two_agent_demo/manifest.yamlexamples/crewai_demo/manifest.yamlexamples/pydantic_ai_demo/manifest.yamlexamples/llamaindex_demo/manifest.yaml
5. Native Pytest Integration
Instead of using ecp run, you can write native Python test assertions using our built-in Pytest fixture:
# test_agent.py
def test_customer_support(ecp_agent):
result = ecp_agent.step("I need a refund")
assert "refund" in result.get("public_output", "").lower()
Run it directly with your agent target:
pytest test_agent.py --ecp-target="python agent.py"
6. Large Datasets (CSV/JSONL)
For large-scale evaluations, you can dynamically load datasets directly in your manifest.yaml instead of hardcoding steps:
scenarios:
- name: "Bulk refund tests"
dataset:
type: "csv"
source: "data/refund_queries.csv"
input_column: "user_query"
output_column: "expected_response"
7. Exporting to LangSmith
You can natively export all evaluation runs, including inputs and outputs, directly to LangSmith:
ecp run --manifest examples/customer_support_demo/manifest.yaml --export langsmith
8. JSON output for CI
Print a JSON report:
ecp run --manifest examples/customer_support_demo/manifest.yaml --json
Save a JSON report:
ecp run --manifest examples/customer_support_demo/manifest.yaml --json-out report.json
By default, ecp run exits non-zero when checks fail. Use --no-fail-on-error when you want a report without failing the process.
9. Optional LLM judge
If your manifest uses llm_judge, set:
$env:OPENAI_API_KEY="your_key_here"
$env:ECP_LLM_JUDGE_MODEL="gpt-4o-mini"
$env:ECP_LLM_JUDGE_TEMPERATURE="0"
10. Streamable HTTP
Start the HTTP agent:
python examples/streamable_http_demo/agent.py
Run the HTTP-target manifest:
ecp run --manifest examples/streamable_http_demo/manifest.yaml --json
11. Inspector
npm run inspector
Open http://127.0.0.1:6274.
12. Conformance smoke test
For protocol implementers:
ecp conformance --target "python examples/customer_support_demo/agent.py"
13. Execution boundaries
A hung agent must never pin a CI job. Bound a run from both directions:
ecp run --manifest manifest.yaml --timeout 30 --max-duration 900
--timeout bounds a single RPC; --max-duration bounds the whole run. Both matter: an agent that answers just inside the per-RPC timeout on every step can still run for hours without ever tripping it.
When either limit trips, or the agent crashes, the run degrades instead of aborting. The failing step is recorded as failed, the rest of that scenario is skipped, and the next scenario runs against a fresh agent, so you still get a complete report:
Step 1: PASS
FAIL | step 2 did not complete (timeout): Agent response timed out after 3.0s
Scenario: Healthy scenario after the hang
Step 1: PASS
Run Complete. Passed: 2/4 exit_reason=timeout
Steps that never produced a result still count as failed checks, so a timeout cannot be mistaken for a pass.
14. Audit record
Every run emits a structured audit payload, embedded under audit in the JSON report and writable standalone:
ecp run --manifest manifest.yaml --audit-out ecp_audit.json
It captures the run id, timestamps, the manifest SHA-256 digest, agent metadata, configured limits, per-step latency and exit_reason, token usage, and pass/fail totals:
{
"exit_reason": "timeout",
"manifest": { "digest": "sha256:c8a39311...", "target": "python agent.py" },
"agent": { "name": "SupportAgent" },
"totals": { "steps_planned": 4, "steps_executed": 2, "steps_failed": 1, "steps_skipped": 1 },
"latency": { "max_ms": 812.4, "p95_ms": 790.1 },
"usage": { "input_tokens": 4820, "output_tokens": 356, "total_tokens": 5176 }
}
Compare steps_planned with steps_executed to tell a clean run from one that degraded and measured a pass rate over fewer steps than intended.
Agents populate the token figures by returning usage from a step:
Result(
public_output="Order A100 is eligible for a refund.",
evaluation_context="Checked order A100 against the 30-day window.",
usage={"input_tokens": 1204, "output_tokens": 88},
)
Omit usage entirely if your agent cannot observe token counts; the runtime distinguishes "not reported" from "reported as zero".
Notes
- The current release line is
0.7.0. - New agents should use
evaluation_context;private_thoughtremains a deprecated compatibility alias. --timeoutcontrols the per-RPC timeout forrunandconformance. It overridesECP_RPC_TIMEOUT; the default is 30 seconds.--max-durationcaps total run time. It overridesECP_MAX_DURATIONand is unset by default.--audit-outwrites the audit payload to its own file. The same payload is always present underauditin--json/--json-outoutput.