Skip to main content
Glama

flag_dif

Screen every item for differential item functioning (DIF) between subgroups using three methods, flagging uniform and non-uniform DIF for content review.

Instructions

Screen every item for differential item functioning between subgroups.

Runs three methods per item, deliberately not redundant:

  • Mantel-Haenszel with ETS A/B/C classification -- the operational standard, but it detects UNIFORM DIF ONLY.

  • Standardised p-difference (Dorans & Kulick) -- same finding on the proportion-correct metric, which panels read without translation.

  • Logistic regression -- adds the group-by-ability interaction, so it catches NON-UNIFORM DIF that Mantel-Haenszel is structurally blind to. Items flagged by logistic but category A under MH are called out separately; an MH-only screen would have missed them.

Matching is on observed number-correct score. purify=True (default) removes flagged items from the matching criterion and retests; note that difR in R defaults to no purification, so numbers differ from a naive difR comparison.

REFUSES when the smaller group is under 50, and warns under 200 because the ETS A/B/C bands were calibrated above that.

CRITICAL FOR REPORTING: a DIF flag is not a finding of bias. It means the item behaves differently for two groups of equal overall proficiency, which routes the item to human content review to decide whether there is a construct-irrelevant reason. Never describe flagged items as biased items, and never report the flag count as a count of biased items. Use the Benjamini-Hochberg adjusted p-values, not the raw ones -- screening a 65-item form is 65 simultaneous tests.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
layoutNo'wide' -- one row per examinee, one column per item. 'long' -- one row per examinee-item response, which requires `id_column` and expects `item_id` and `response` columns.wide
purifyNoRe-run the analysis with flagged items removed from the matching score, to a fixed point. On by default because a DIF item left in the criterion contaminates the ability match used to test every other item. difR in R defaults to no purification, so leave this on for defensibility and turn it off only to reproduce a difR run.
scoredNoTrue if the cells already hold 0/1 item scores. False if they hold the option each examinee selected (e.g. 'A', 'C'), which requires `answer_key`. This is never inferred: a raw-option file read as scored produces a complete, plausible-looking analysis of nothing. Confirm it with `describe_dataset` before trusting any statistic.
id_columnNoName of the examinee identifier column. Naming it excludes it from the item columns; leaving it unnamed makes it an extra 'item'. Identifiers are used only for exclusion and are never returned.
answer_keyNoCorrect option for each item, in the same order as the item columns. Required when `scored=False`; ignored otherwise. Its length must equal the item count -- a key that is off by one mis-scores every item after the offset, and the result looks like a form-wide item-quality problem. One entry per item, holding the option itself -- not its position, and not the whole key as a single string.
focal_groupNoValue in `group_column` whose examinees are tested against the reference group. Omit to run every non-reference level in turn; note that the false-discovery correction is applied within each comparison, so multiplicity compounds across them. A value found IN the column, not the column name.
linear_formNoTrue if every examinee saw the items in column order, which is what makes a trailing run of blanks readable as not-reached. Set False for adaptive or randomised-order delivery: position is then unknown, so all blanks are treated as omits and a warning says so.
group_columnYesName of the column holding the subgroup membership to test. DIF is a between-group comparison, so there is no default: check the column name and the subgroup sizes with `describe_dataset` first, since the smaller group's size determines whether this analysis can run at all.
response_fileYesPath to the response file on disk, read locally. Candidate responses are passed as a path and never inline, so that a multi-thousand-examinee file does not enter the conversation transcript.
missing_policyNoHow blank responses are scored. 'omit_incorrect_notreached_missing' (default) scores a blank mid-form as incorrect -- the examinee had the opportunity -- and excludes a trailing run of blanks as not-reached, because scoring those wrong confounds item difficulty with speededness. 'all_incorrect' scores every blank wrong, which makes end-of-form items look harder and less discriminating in proportion to how speeded the form is; use it only if the scoring rules genuinely penalise unreached items. 'all_missing' excludes every blank, which conditions p-values on having attempted the item and turns items examinees skip when unsure into easy-looking ones. The two non-default policies each raise a warning.omit_incorrect_notreached_missing
reference_groupNoValue in `group_column` to use as the reference (comparison) group. Defaults to the largest group other than the focal one. Which group is reference flips the sign of every DIF statistic, so set it explicitly whenever the direction of the finding will be reported. A value found IN the column, not the column name.
pool_thin_strataNoMerge adjacent score strata too thin to contribute to the Mantel-Haenszel table. Recovers information at the score extremes on small samples, at the cost of matching examinees less exactly on ability -- the exact match is the assumption the method rests on, so this is off by default. Affects Mantel-Haenszel and the standardised p-difference only; logistic DIF does not stratify. The choice is recorded in `method_notes.matching_criterion`.
effect_size_bandsNoEffect-size thresholds for logistic DIF on the Nagelkerke delta-R-squared scale. 'jodoin_gierl' (default, 0.035/0.070) is recalibrated to align with the ETS A/B/C categories. 'zumbo_thomas' (0.13/0.26) is far more permissive and will flag materially fewer items. Report which one was used -- the choice changes the flag count, which is why it is a parameter rather than a buried constant.jodoin_gierl

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes
Install Server

TDQS

A4.3/5.0
Behavior5/5

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

With no annotations provided, the description carries the full behavioral disclosure burden and does so thoroughly. It explains that purification changes results relative to difR, that the tool refuses under n=50 and warns under n=200, and that DIF flags must not be described as bias. It also instructs use of Benjamini-Hochberg adjusted p-values because screening many items is a multiple-testing situation.

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

Conciseness5/5

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

The description is long but every section earns its place: method rationale, purification behavior, sample-size thresholds, and critical reporting constraints. The bulleted method list and clear warning blocks make the structure easy to scan, and there is no filler.

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, the description is remarkably complete: it explains all three methods, their blind spots, matching and purification, operational constraints, and interpretation obligations. An output schema exists, so the description does not need to specify return fields, and the parameter schema covers the remaining operational details.

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

Parameters3/5

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

Schema description coverage is 100%, so the parameter semantics baseline is 3. The main description adds useful method-level context, such as purification and matching on number-correct score, but it does not need to explain individual parameters because the schema already documents them in depth.

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 and resource: 'Screen every item for differential item functioning between subgroups.' This clearly identifies the tool's function and its subgroup-comparison scope, which is enough to distinguish it from siblings like compute_classical_stats and compute_local_dependence without opening the schema.

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

Usage Guidelines3/5

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

The description gives strong context about when and how the analysis runs, including purification, sample-size refusals, and reporting cautions. However, it never explicitly says when to choose this tool over sibling tools or mentions alternatives, so the usage guidance is implied rather than stated.

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

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/JulieElkinsAWS/psychometrics-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server