Observed since 20 Oct, 23:13 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
agentrubric
AgentRubric: trajectory-level evaluation for LLM agents
Trajectory-level evaluation for LLM agents. Zero dependencies, five metrics, one score.
📦 Live on PyPI: pypi.org/project/agentrubric —
pip install agentrubric
Current tools (LangSmith, Langfuse, etc.) give you logging. AgentRubric gives you scores .
When an LLM agent runs, it produces a trajectory — a sequence of thoughts, tool calls, observations, and a final answer. Knowing whether that trajectory was actually correct is hard: Did it call the right tools? With the right arguments? Did it wander in loops? Did it finish the task at all? AgentRubric answers all of that with a single evaluate() call.
trajectory (list of steps)
│
▼
AgentRubric.evaluate()
│
▼
EvaluationReport
├─ tool_accuracy_score — did it call the right tools?
├─ argument_fidelity_score — did it call them with the right arguments?
├─ trajectory_length_score — did it solve the task efficiently?
├─ completion_score — did it actually finish the task?
└─ failure_taxonomy — what went wrong, categorised
pip install agentrubric
Zero required dependencies. Optional extras for framework integrations:
pip install agentrubric[langchain] # LangChain agent parsing
pip install agentrubric[openai] # OpenAI function-calling parsing
Then say hello:
agentrubric
from agentrubric import Trajectory, Step, evaluate
trajectory = Trajectory(
task="Find the latest JAX release and summarize the changelog",
steps=[
Step(step_type="thought", content="I need to search for JAX releases"),
Step(step_type="tool_call", content="", tool_name="search",
tool_args={"query": "JAX latest release"}),
Step(step_type="observation", content="JAX 0.4.30 released on July 2026..."),
Step(step_type="final_answer",
content="The latest JAX release is 0.4.30, released July 2026."),
],
final_answer="The latest JAX release is 0.4.30, released July 2026.",
)
report = evaluate(
trajectory=trajectory,
expected_tools=["search"],
expected_calls=[{"tool_name": "search", "expected_args": {"query": "JAX latest release"}}],
optimal_steps=4,
completion_keywords=["JAX", "release"],
)
print(report)
print(report.overall_score) # 0.9-ish
print(report.failures) # []
AgentRubric Evaluation Report
========================================
Overall Score : 0.93
Tool Accuracy : 1.00
Argument Fidelity : 0.70
Trajectory Efficiency : 1.00
Completion : 1.00
No failures detected.
========================================
Export to JSON for dashboards, CI gates, or logging pipelines:
report.to_json()
Run it yourself: python examples/basic_evaluation.py
| Metric | Question it answers | Signal |
|---|---|---|
| Tool Accuracy | Did the agent call the tools it was supposed to? | expected_tools matched against tools actually called |
| Argument Fidelity | Were those tools called with the right arguments? | exact + fuzzy match against expected_calls |
| Trajectory Length | Did it solve the task efficiently? | optimal_steps / actual_steps, capped at 1.0 |
| Completion | Did it actually finish? | binary, or keyword coverage of the final answer |
| Failure Taxonomy | When it broke, why? | WRONG_TOOL, MISSING_TOOL, BAD_ARGS, LOOP, NO_COMPLETION, HALLUCINATED_TOOL |
overall_score is a weighted average: 0.3 × tool_accuracy + 0.3 × argument_fidelity + 0.2 × trajectory_length + 0.2 × completion.
Already using LangChain or OpenAI function calling? Don't hand-build trajectories — parse them straight out of the agent's own output.
LangChain
from agentrubric.integrations.langchain import from_langchain
result = agent_executor.invoke({"input": task})
trajectory = from_langchain(result, task=task)
report = evaluate(trajectory, expected_tools=["search"])
OpenAI function calling
from agentrubric.integrations.openai import from_openai_messages
trajectory = from_openai_messages(messages, task=task)
report = evaluate(trajectory, expected_tools=["search"])
Trajectory and Step are plain dataclasses — build them from any agent framework, or by hand.pip install -e ".[dev]"
pytest
MIT
Download counts and popularity will appear here as the collector receives them.
| Package / target | Requirement | Relationship |
|---|---|---|
langchainEnvironment{
"extras": "",
"marker": "extra == \"langchain\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | langchain>=0.2.0; extra == "langchain" | runtime |
openaiEnvironment{
"extras": "",
"marker": "extra == \"openai\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | openai>=1.0.0; extra == "openai" | runtime |
pytestEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | pytest; extra == "dev" | runtime |
blackEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | black; extra == "dev" | runtime |
ruffEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | ruff; extra == "dev" | runtime |
bdist_wheel · 12.38 KB · Python py3
sdist · 11.7 KB · Python source
Shared repository data · GitHub
Public sponsor counts have not been collected. These signals belong to the repository owner.
github · 1 observations shown. Missing days are unknown.
| Date / source period | Value | Observed at |
|---|---|---|
| 2026-10-22 | 1 | 2026-10-22T21:17:25.6224052Z |
Observed since 20 Oct, 23:13 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package_version:e25dc5c0fba759d7e3cc759bb6be13434c4bb6aed7c5478544598fe0574fa4e0