Skip to main content
Glama
vikranthviki

Causal Decision Agent

by vikranthviki

match

Read-only

Estimate causal treatment effects from observational data by matching treated and control units on propensity scores or covariates, reducing confounding bias.

Instructions

Propensity score and covariate matching for treatment effect estimation. Validation: certified evidence with scoped limitations. Known limitations: greedy nearest-neighbour matching without replacement is order-dependent: the m_order convention can differ across packages and materially moves the estimate (>5x spread on MatchIt::lalonde with Mahalanobis distance). m_order='data' and 'closest' reproduce MatchIt exactly; m_order='farthest' is StatsPAI's own dynamic rule and is not MatchIt-equivalent; bias_correction=True follows a different convention from Matching::Match's BiasAdjust: StatsPAI regresses on the full covariate vector with unweighted OLS over all controls, the reference regresses on the matching variables weighted by match counts, so bias-corrected estimates can differ from it by about 0.1%. The uncorrected estimate and its Abadie-Imbens standard error are exact. Cost: Builds the dense n_treated x n_control distance matrix via scipy cdist before selecting neighbours: memory is O(n_treated x n_control). Comfortable into the thousands per arm; use a caliper or coarser blocking beyond that. Assumptions: Unconfoundedness / CIA: Y(d) perp D | X; Overlap / common support: tr...

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
tiesNoHow equidistant controls are handled under matching with replacement. 'first' keeps the lowest-index one; 'all' pools them and splits the weight (the Matching::Match convention, which removes the row-order dependence).first
detailNoPayload depth: 'minimal' (~150 tokens) for sub-step calls where only the point estimate is needed; 'standard' (~1K tokens) for diagnostics + coefficient table; 'agent' (~2K tokens, default) adds violations / next_steps / suggested_functions so the LLM can plan its next call without another round-trip.agent
methodNoMatching method. 'caliper' is not a method -- pass caliper= to any nearest-neighbour variant.nearest
m_orderNoOrder treated units are processed in for greedy matching without replacement. The result depends on it materially (>5x spread on lalonde with Mahalanobis distance). 'data' and 'closest' reproduce the MatchIt rules of the same name.smallest_min_dist
outcomeYesOutcome variable column name or outcome array.
as_handleNoIf true, cache the fitted result on the server and return result_id + result_uri alongside the JSON payload so a subsequent tools/call can chain without re-running.
data_pathYesAbsolute path or URL to a data file. Supported: .csv / .tsv / .txt (delimited), .parquet / .pq, .feather / .arrow, .xlsx / .xls, .dta (Stata), .json / .jsonl. Schemes: file://, s3://, gs://, https://.
result_idNoOptional handle to a previously-fitted result (returned by an earlier call when as_handle=true). Tools that operate on a fitted object accept this in place of re-supplying data_path + columns.
se_methodNoStandard error. 'auto' resolves to 'abadie_imbens' for nearest-neighbour, 'psmatch2' for kernel / radius, 'bootstrap' for llr. 'abadie_imbens' is the sample-ATT conditional variance (Stata psmatch2 ai()) and the only option measured to be correctly sized (0.95-1.04x the sampling SD, coverage 0.905-0.956 over 36 designs x 1000 reps; see benchmarks/matching_se_coverage.py). 'abadie_imbens_pop' is the population-ATT variance Matching::Match reports; 'psmatch2' the analytic Stata SE (1.50-1.69x, too wide); 'ai' the simple matched-pair SE (0.56-0.91x, never reaches nominal coverage); 'bootstrap' resamples within arm and re-estimates the propensity score each draw.auto
treatmentYesTreatment indicator, treatment variable, or treatment array.
covariatesYesCovariate matrix, DataFrame, or column names.
data_columnsNoOptional column projection. Parquet/Feather/Stata loaders honour this for fast partial reads.
caliper_scaleNoUnits of `caliper`: 'raw' on the distance scale (Stata psmatch2) or 'sd' in standard deviations of the propensity score (MatchIt std.caliper=TRUE).raw
data_sample_nNoOptional uniform random subsample size (seed=0, deterministic) — useful on huge panels.
tie_toleranceNoWith ties='all', how close squared distances (scaled by the variance of the distance measure) must be to count as tied. 1e-5 reproduces Matching::Match's distance.tolerance default.
bootstrap_repsNoReplications for se_method='bootstrap'
bootstrap_seedNoSeed for the bootstrap resampler
mahalanobis_covNoCovariance defining the Mahalanobis metric: 'pooled' within-group (Rubin 1980, MatchIt) or 'total' full-sample (pre-1.21 behaviour).pooled
llr_stata_compatNomethod='llr' only: reproduce Stata psmatch2's SUBSTITUTE for LLR (lpoly-smoothed outcome + nearest-neighbour matching) rather than genuine local linear regression.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.1.0

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description is exceptionally transparent about behavioral traits beyond the annotations. It discloses: order-dependence of greedy matching with a quantified >5x spread, exact reproducibility conditions (m_order='data'/'closest' reproduce MatchIt), the StatsPAI-specific 'farthest' rule, bias_correction convention differences with quantified ~0.1% deviation, exactness of the uncorrected estimate and Abadie-Imbens SE, memory complexity O(n_treated x n_control), practical scale limits, and the unconfoundedness/overlap assumptions. The readOnlyHint=true annotation is consistent with a matching estimator that computes estimates without mutating data. This is far beyond what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense and information-rich, with clear section labels (Validation, Known limitations, Cost, Assumptions). It front-loads the core purpose and then provides critical caveats. It is longer than ideal, but every sentence carries substantive information: quantified effect sizes, exact reproducibility rules, memory complexity, and statistical assumptions. The structure helps an agent scan for the relevant caveat. It loses one point for length and for the truncated 'Assumptions' section that cuts off mid-sentence ('tr...'), which is a structural flaw.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (19 parameters, 7 enums, 15 methods, 6 SE methods), the description is remarkably complete. It covers the key decision-relevant facts: what the tool does, when results are exact vs approximate, how to reproduce reference implementations, memory constraints, and statistical assumptions. The output schema exists, so return values need not be described. The only minor gap is the truncated assumptions sentence, but the core assumptions (unconfoundedness, overlap) are already stated. For a tool this complex, the description provides an agent with enough to select it and avoid known pitfalls.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds meaningful semantics beyond the schema: it explains the material impact of m_order (>5x spread), clarifies that 'caliper' is not a method but a parameter, explains the memory implications of the dense distance matrix, and gives the statistical meaning of se_method options with measured coverage properties. It also explains the bias_correction convention difference. This goes beyond the schema's per-parameter descriptions, though the schema itself is already rich. The description does not enumerate every parameter, but the schema covers them, so the combination is strong.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource: 'Propensity score and covariate matching for treatment effect estimation.' It names the tool's domain (matching for causal treatment effects) and its core function. It distinguishes itself from siblings like psm, psmatch2, propensity_score, and optimal_match by covering the full matching family (nearest, kernel, radius, cem, etc.) and by being the general-purpose matching entry point. The description also includes validation and known-limitations context that makes the tool's identity unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives strong usage context: it states the tool is for treatment effect estimation via matching, and the 'Known limitations' section tells the agent when to be cautious (order-dependence, memory cost, bias-correction conventions). It also gives practical guidance like 'use a caliper or coarser blocking beyond that' for large data. However, it does not explicitly name sibling alternatives or state when to choose this tool over psm, psmatch2, propensity_score, or optimal_match. The guidance is implied by the tool's comprehensive scope rather than stated as explicit routing rules.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Deploy Server

Other Tools