Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Cheminformatics toolkit for fine-grained molecular control. SMILES/SDF parsing, descriptors (MW, LogP, TPSA), fingerprints, substructure search, 2D/3D generation, similarity, reactions. For standard workflows with simpler interface, use datamol (wrapper around RDKit). Use rdkit for advanced control, custom sanitization, specialized algorithms.
.claude/skills/lingxling-rdkit/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-07 | ✗→✓ | ▲ Improved | 97% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 195% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 301% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 207% | 0% |
| case-14 | ✗→✓ | ▲ Improved | 231% | 0% |
RDKit is a comprehensive cheminformatics library providing Python APIs for molecular analysis and manipulation. This skill provides guidance for reading/writing molecular structures, calculating descriptors, fingerprinting, substructure searching, chemical reactions, 2D/3D coordinate generation, and molecular visualization. Use this skill for drug discovery, computational chemistry, and cheminformatics research tasks.
Current baseline (checked 2026-06-07): RDKit 2026.03.3 is the latest GitHub/PyPI release (rdkit 2026.3.3 on PyPI). Official installation docs continue to recommend conda-forge for most users, while cross-platform PyPI wheels are published under the rdkit package name. rdkit-pypi is the old PyPI package name and should only appear when maintaining legacy environments.
Use uv when installing into an existing Python environment:
bashuv pip install rdkit
For reproducible chemistry environments, especially when mixing compiled scientific packages, conda-forge remains the upstream recommendation:
bashconda create -c conda-forge -n my-rdkit-env rdkit conda activate my-rdkit-env
Avoid installing both conda rdkit and PyPI rdkit/rdkit-pypi into the same environment unless you are deliberately debugging packaging behavior. Mixed installs can make it unclear which binary extension is being imported.
Reading Molecules:
Read molecular structures from various formats:
pythonfrom rdkit import Chem # From SMILES strings mol = Chem.MolFromSmiles('Cc1ccccc1') # Returns Mol object or None # From MOL files mol = Chem.MolFromMolFile('path/to/file.mol') # From MOL blocks (string data) mol = Chem.MolFromMolBlock(mol_block_string) # From InChI mol = Chem.MolFromInchi('InChI=1S/C6H6/c1-2-4-6-5-3-1/h1-6H')
Writing Molecules:
Convert molecules to text representations:
python# To canonical SMILES smiles = Chem.MolToSmiles(mol) # To MOL block mol_block = Chem.MolToMolBlock(mol) # To InChI inchi = Chem.MolToInchi(mol)
Batch Processing:
For processing multiple molecules, use Supplier/Writer objects:
python# Read SDF files suppl = Chem.SDMolSupplier('molecules.sdf') for mol in suppl: if mol is not None: # Check for parsing errors # Process molecule pass # Read SMILES files suppl = Chem.SmilesMolSupplier('molecules.smi', titleLine=False) # For large files or compressed data import gzip with gzip.open('molecules.sdf.gz') as f: suppl = Chem.ForwardSDMolSupplier(f) for mol in suppl: # Process molecule pass # Multithreaded processing for large datasets suppl = Chem.MultithreadedSDMolSupplier('molecules.sdf') # Write molecules to SDF writer = Chem.SDWriter('output.sdf') for mol in molecules: writer.write(mol) writer.close()
Important Notes:
MolFrom* functions return None on failure with error messagesNone before processing moleculesRDKit automatically sanitizes molecules during parsing, executing 13 steps including valence checking, aromaticity perception, and chirality assignment.
Sanitization Control:
python# Disable automatic sanitization mol = Chem.MolFromSmiles('C1=CC=CC=C1', sanitize=False) # Manual sanitization Chem.SanitizeMol(mol) # Detect problems before sanitization problems = Chem.DetectChemistryProblems(mol) for problem in problems: print(problem.GetType(), problem.Message()) # Partial sanitization (skip specific steps) Chem.SanitizeMol(mol, sanitizeOps=Chem.SANITIZE_ALL ^ Chem.SANITIZE_PROPERTIES)
Common Sanitization Issues:
Accessing Molecular Structure:
python# Iterate atoms and bonds for atom in mol.GetAtoms(): print(atom.GetSymbol(), atom.GetIdx(), atom.GetDegree()) for bond in mol.GetBonds(): print(bond.GetBeginAtomIdx(), bond.GetEndAtomIdx(), bond.GetBondType()) # Ring information ring_info = mol.GetRingInfo() ring_info.NumRings() ring_info.AtomRings() # Returns tuples of atom indices # Check if atom is in ring atom = mol.GetAtomWithIdx(0) atom.IsInRing() atom.IsInRingSize(6) # Check for 6-membered rings # Find smallest set of smallest rings (SSSR) from rdkit.Chem import GetSymmSSSR rings = GetSymmSSSR(mol)
Stereochemistry:
python# Find chiral centers from rdkit.Chem import FindMolChiralCenters chiral_centers = FindMolChiralCenters(mol, includeUnassigned=True) # Returns list of (atom_idx, chirality) tuples # Assign stereochemistry from 3D coordinates from rdkit.Chem import AssignStereochemistryFrom3D AssignStereochemistryFrom3D(mol) # Check bond stereochemistry bond = mol.GetBondWithIdx(0) stereo = bond.GetStereo() # STEREONONE, STEREOZ, STEREOE, etc.
Fragment Analysis:
python# Get disconnected fragments frags = Chem.GetMolFrags(mol, asMols=True) # Fragment on specific bonds from rdkit.Chem import FragmentOnBonds frag_mol = FragmentOnBonds(mol, [bond_idx1, bond_idx2]) # Count ring systems from rdkit.Chem.Scaffolds import MurckoScaffold scaffold = MurckoScaffold.GetScaffoldForMol(mol)
Basic Descriptors:
pythonfrom rdkit.Chem import Descriptors # Molecular weight mw = Descriptors.MolWt(mol) exact_mw = Descriptors.ExactMolWt(mol) # LogP (lipophilicity) logp = Descriptors.MolLogP(mol) # Topological polar surface area tpsa = Descriptors.TPSA(mol) # Number of hydrogen bond donors/acceptors hbd = Descriptors.NumHDonors(mol) hba = Descriptors.NumHAcceptors(mol) # Number of rotatable bonds rot_bonds = Descriptors.NumRotatableBonds(mol) # Number of aromatic rings aromatic_rings = Descriptors.NumAromaticRings(mol)
Batch Descriptor Calculation:
python# Calculate all descriptors at once all_descriptors = Descriptors.CalcMolDescriptors(mol) # Returns dictionary: {'MolWt': 180.16, 'MolLogP': 1.23, ...} # Get list of available descriptor names descriptor_names = [desc[0] for desc in Descriptors._descList]
Lipinski's Rule of Five:
python# Check drug-likeness mw = Descriptors.MolWt(mol) <= 500 logp = Descriptors.MolLogP(mol) <= 5 hbd = Descriptors.NumHDonors(mol) <= 5 hba = Descriptors.NumHAcceptors(mol) <= 10 is_drug_like = mw and logp and hbd and hba
Fingerprint Types:
pythonfrom rdkit.Chem import rdFingerprintGenerator from rdkit.Chem import MACCSkeys # RDKit topological fingerprint rdk_gen = rdFingerprintGenerator.GetRDKitFPGenerator(minPath=1, maxPath=7, fpSize=2048) fp = rdk_gen.GetFingerprint(mol) # Morgan fingerprints (circular fingerprints, similar to ECFP) # Modern API using rdFingerprintGenerator morgan_gen = rdFingerprintGenerator.GetMorganGenerator(radius=2, fpSize=2048) fp = morgan_gen.GetFingerprint(mol) # Count-based fingerprint fp_count = morgan_gen.GetCountFingerprint(mol) # MACCS keys (166-bit structural key) fp = MACCSkeys.GenMACCSKeys(mol) # Atom pair fingerprints ap_gen = rdFingerprintGenerator.GetAtomPairGenerator() fp = ap_gen.GetFingerprint(mol) # Topological torsion fingerprints tt_gen = rdFingerprintGenerator.GetTopologicalTorsionGenerator() fp = tt_gen.GetFingerprint(mol) # Avalon fingerprints (if available) from rdkit.Avalon import pyAvalonTools fp = pyAvalonTools.GetAvalonFP(mol)
Similarity Calculation:
pythonfrom rdkit import DataStructs from rdkit.Chem import rdFingerprintGenerator # Generate fingerprints using generator mfpgen = rdFingerprintGenerator.GetMorganGenerator(radius=2, fpSize=2048) fp1 = mfpgen.GetFingerprint(mol1) fp2 = mfpgen.GetFingerprint(mol2) # Calculate Tanimoto similarity similarity = DataStructs.TanimotoSimilarity(fp1, fp2) # Calculate similarity for multiple molecules fps = [mfpgen.GetFingerprint(m) for m in [mol2, mol3, mol4]] similarities = DataStructs.BulkTanimotoSimilarity(fp1, fps) # Other similarity metrics dice = DataStructs.DiceSimilarity(fp1, fp2) cosine = DataStructs.CosineSimilarity(fp1, fp2)
Clustering and Diversity:
python# Butina clustering based on fingerprint similarity from rdkit.ML.Cluster import Butina # Calculate distance matrix dists = [] mfpgen = rdFingerprintGenerator.GetMorganGenerator(radius=2, fpSize=2048) fps = [mfpgen.GetFingerprint(mol) for mol in mols] for i in range(len(fps)): sims = DataStructs.BulkTanimotoSimilarity(fps[i], fps[:i]) dists.extend([1-sim for sim in sims]) # Cluster with distance cutoff clusters = Butina.ClusterData(dists, len(fps), distThresh=0.3, isDistData=True)
Basic Substructure Matching:
python# Define query using SMARTS query = Chem.MolFromSmarts('[#6]1:[#6]:[#6]:[#6]:[#6]:[#6]:1') # Benzene ring # Check if molecule contains substructure has_match = mol.HasSubstructMatch(query) # Get all matches (returns tuple of tuples with atom indices) matches = mol.GetSubstructMatches(query) # Get only first match match = mol.GetSubstructMatch(query)
Common SMARTS Patterns:
python# Primary alcohols primary_alcohol = Chem.MolFromSmarts('[CH2][OH1]') # Carboxylic acids carboxylic_acid = Chem.MolFromSmarts('C(=O)[OH]') # Amides amide = Chem.MolFromSmarts('C(=O)N') # Aromatic heterocycles aromatic_n = Chem.MolFromSmarts('[nR]') # Aromatic nitrogen in ring # Macrocycles (rings > 12 atoms) macrocycle = Chem.MolFromSmarts('[r{12-}]')
Matching Rules:
Reaction SMARTS:
pythonfrom rdkit.Chem import AllChem # Define reaction using SMARTS: reactants >> products rxn = AllChem.ReactionFromSmarts('[C:1]=[O:2]>>[C:1][O:2]') # Ketone reduction # Apply reaction to molecules reactants = (mol1,) products = rxn.RunReactants(reactants) # Products is tuple of tuples (one tuple per product set) for product_set in products: for product in product_set: # Sanitize product Chem.SanitizeMol(product)
Reaction Features:
Reaction Similarity:
python# Generate reaction fingerprints fp = AllChem.CreateDifferenceFingerprintForReaction(rxn) # Compare reactions similarity = DataStructs.TanimotoSimilarity(fp1, fp2)
2D Coordinate Generation:
pythonfrom rdkit.Chem import AllChem # Generate 2D coordinates for depiction AllChem.Compute2DCoords(mol) # Align molecule to template structure template = Chem.MolFromSmiles('c1ccccc1') AllChem.Compute2DCoords(template) AllChem.GenerateDepictionMatching2DStructure(mol, template)
3D Coordinate Generation and Conformers:
python# Generate single 3D conformer using ETKDG AllChem.EmbedMolecule(mol, randomSeed=42) # Generate multiple conformers conf_ids = AllChem.EmbedMultipleConfs(mol, numConfs=10, randomSeed=42) # Optimize geometry with force field AllChem.UFFOptimizeMolecule(mol) # UFF force field AllChem.MMFFOptimizeMolecule(mol) # MMFF94 force field # Optimize all conformers for conf_id in conf_ids: AllChem.MMFFOptimizeMolecule(mol, confId=conf_id) # Calculate RMSD between conformers from rdkit.Chem import AllChem rms = AllChem.GetConformerRMS(mol, conf_id1, conf_id2) # Align molecules AllChem.AlignMol(probe_mol, ref_mol)
Constrained Embedding:
python# Embed with part of molecule constrained to specific coordinates AllChem.ConstrainedEmbed(mol, core_mol)
Basic Drawing:
pythonfrom rdkit.Chem import Draw # Draw single molecule to PIL image img = Draw.MolToImage(mol, size=(300, 300)) img.save('molecule.png') # Draw to file directly Draw.MolToFile(mol, 'molecule.png') # Draw multiple molecules in grid mols = [mol1, mol2, mol3, mol4] img = Draw.MolsToGridImage(mols, molsPerRow=2, subImgSize=(200, 200))
Highlighting Substructures:
python# Highlight substructure match query = Chem.MolFromSmarts('c1ccccc1') match = mol.GetSubstructMatch(query) img = Draw.MolToImage(mol, highlightAtoms=match) # Custom highlight colors highlight_colors = {atom_idx: (1, 0, 0) for atom_idx in match} # Red img = Draw.MolToImage(mol, highlightAtoms=match, highlightAtomColors=highlight_colors)
Customizing Visualization:
pythonfrom rdkit.Chem.Draw import rdMolDraw2D # Create drawer with custom options drawer = rdMolDraw2D.MolDraw2DCairo(300, 300) opts = drawer.drawOptions() # Customize options opts.addAtomIndices = True opts.addStereoAnnotation = True opts.bondLineWidth = 2 # Draw molecule drawer.DrawMolecule(mol) drawer.FinishDrawing() # Save to file with open('molecule.png', 'wb') as f: f.write(drawer.GetDrawingText())
Jupyter Notebook Integration:
python# Enable inline display in Jupyter from rdkit.Chem.Draw import IPythonConsole # Customize default display IPythonConsole.ipython_useSVG = True # Use SVG instead of PNG IPythonConsole.molSize = (300, 300) # Default size # Molecules now display automatically mol # Shows molecule image
Visualizing Fingerprint Bits:
python# Show what molecular features a fingerprint bit represents from rdkit.Chem import Draw from rdkit.Chem import rdFingerprintGenerator # For Morgan fingerprints additional_output = rdFingerprintGenerator.AdditionalOutput() additional_output.AllocateBitInfoMap() morgan_gen = rdFingerprintGenerator.GetMorganGenerator(radius=2, fpSize=2048) fp = morgan_gen.GetFingerprint(mol, additionalOutput=additional_output) bit_info = additional_output.GetBitInfoMap() # Draw environment for specific bit img = Draw.DrawMorganBit(mol, bit_id, bit_info)
Adding/Removing Hydrogens:
python# Add explicit hydrogens mol_h = Chem.AddHs(mol) # Remove explicit hydrogens mol = Chem.RemoveHs(mol_h)
Kekulization and Aromaticity:
python# Convert aromatic bonds to alternating single/double Chem.Kekulize(mol) # Set aromaticity Chem.SetAromaticity(mol)
Replacing Substructures:
python# Replace substructure with another structure query = Chem.MolFromSmarts('c1ccccc1') # Benzene replacement = Chem.MolFromSmiles('C1CCCCC1') # Cyclohexane new_mol = Chem.ReplaceSubstructs(mol, query, replacement)[0]
Neutralizing Charges:
python# Remove formal charges by adding/removing hydrogens from rdkit.Chem.MolStandardize import rdMolStandardize # Using Uncharger uncharger = rdMolStandardize.Uncharger() mol_neutral = uncharger.uncharge(mol)
Molecular Hashing:
pythonfrom rdkit.Chem import rdMolHash # Generate Murcko scaffold hash scaffold_hash = rdMolHash.MolHash(mol, rdMolHash.HashFunction.MurckoScaffold) # Canonical SMILES hash canonical_hash = rdMolHash.MolHash(mol, rdMolHash.HashFunction.CanonicalSmiles) # Regioisomer hash (ignores stereochemistry) regio_hash = rdMolHash.MolHash(mol, rdMolHash.HashFunction.Regioisomer)
Randomized SMILES:
python# Generate random SMILES representations (for data augmentation) from rdkit.Chem import MolToRandomSmilesVect random_smiles = MolToRandomSmilesVect(mol, numSmiles=10, randomSeed=42)
Pharmacophore Features:
pythonfrom rdkit.Chem import ChemicalFeatures from rdkit import RDConfig import os # Load feature factory fdef_path = os.path.join(RDConfig.RDDataDir, 'BaseFeatures.fdef') factory = ChemicalFeatures.BuildFeatureFactory(fdef_path) # Get pharmacophore features features = factory.GetFeaturesForMol(mol) for feat in features: print(feat.GetFamily(), feat.GetType(), feat.GetAtomIds())
pythonfrom rdkit import Chem from rdkit.Chem import Descriptors def analyze_druglikeness(smiles): mol = Chem.MolFromSmiles(smiles) if mol is None: return None # Calculate Lipinski descriptors results = { 'MW': Descriptors.MolWt(mol), 'LogP': Descriptors.MolLogP(mol), 'HBD': Descriptors.NumHDonors(mol), 'HBA': Descriptors.NumHAcceptors(mol), 'TPSA': Descriptors.TPSA(mol), 'RotBonds': Descriptors.NumRotatableBonds(mol) } # Check Lipinski's Rule of Five results['Lipinski'] = ( results['MW'] <= 500 and results['LogP'] <= 5 and results['HBD'] <= 5 and results['HBA'] <= 10 ) return results
pythonfrom rdkit import Chem from rdkit.Chem import rdFingerprintGenerator from rdkit import DataStructs def similarity_screen(query_smiles, database_smiles, threshold=0.7): query_mol = Chem.MolFromSmiles(query_smiles) if query_mol is None: return [] morgan_gen = rdFingerprintGenerator.GetMorganGenerator(radius=2, fpSize=2048) query_fp = morgan_gen.GetFingerprint(query_mol) hits = [] for idx, smiles in enumerate(database_smiles): mol = Chem.MolFromSmiles(smiles) if mol: fp = morgan_gen.GetFingerprint(mol) sim = DataStructs.TanimotoSimilarity(query_fp, fp) if sim >= threshold: hits.append((idx, smiles, sim)) return sorted(hits, key=lambda x: x[2], reverse=True)
pythonfrom rdkit import Chem def filter_by_substructure(smiles_list, pattern_smarts): query = Chem.MolFromSmarts(pattern_smarts) hits = [] for smiles in smiles_list: mol = Chem.MolFromSmiles(smiles) if mol and mol.HasSubstructMatch(query): hits.append(smiles) return hits
Always check for None when parsing molecules:
pythonmol = Chem.MolFromSmiles(smiles) if mol is None: print(f"Failed to parse: {smiles}") continue
Use safe storage formats:
pythonimport base64 import json from pathlib import Path from rdkit import Chem # Portable exchange formats such as SMILES and SDF are safest for shared data. # For local caches, RDKit's binary molecule representation avoids generic pickle. payload = [base64.b64encode(mol.ToBinary()).decode("ascii") for mol in mols] Path("molecules.rdmol.json").write_text(json.dumps(payload)) cached = json.loads(Path("molecules.rdmol.json").read_text()) mols = [Chem.Mol(base64.b64decode(item)) for item in cached]
Do not load Python pickle files from untrusted sources. Pickle deserialization can execute arbitrary code; prefer SMILES/SDF for interchange and RDKit binary payloads for trusted local caches.
Use bulk operations:
pythonfrom rdkit import DataStructs from rdkit.Chem import rdFingerprintGenerator # Calculate fingerprints for all molecules at once morgan_gen = rdFingerprintGenerator.GetMorganGenerator(radius=2, fpSize=2048) fps = [morgan_gen.GetFingerprint(mol) for mol in mols] # Use bulk similarity calculations similarities = DataStructs.BulkTanimotoSimilarity(fps[0], fps[1:])
Pin RDKit versions when exact molecular identifiers or numeric features are part of a persisted dataset, model feature pipeline, or regulated report. Recent releases changed or documented behavior in several Python-facing areas:
rdkit.Chem.Draw canvas modules and functions such as MolToImageFile, MolToMPL, and MolToQPixmap were removed; use Draw.MolToFile, Draw.MolToImage, or rdMolDraw2D.rdkit.Chem.MolStandardize.rdMolStandardize; the older Python MolStandardize implementation was removed.GetSimilarityMapFromWeights(), GetSimilarityMapForFingerprint(), and GetSimilarityMapForModel() now require an rdMolDraw2D drawing object.RDKit operations are generally thread-safe for:
Not thread-safe: MolSuppliers when accessed concurrently.
For large datasets:
python# Use ForwardSDMolSupplier to avoid loading entire file with open('large.sdf') as f: suppl = Chem.ForwardSDMolSupplier(f) for mol in suppl: # Process one molecule at a time pass # Use MultithreadedSDMolSupplier for parallel processing suppl = Chem.MultithreadedSDMolSupplier('large.sdf', numWriterThreads=4)
DetectChemistryProblems() to debugAddHs() when calculating properties that depend on hydrogenThis skill includes detailed API reference documentation:
api_reference.md - Comprehensive listing of RDKit modules, functions, and classes organized by functionalitydescriptors_reference.md - Complete list of available molecular descriptors with descriptionssmarts_patterns.md - Common SMARTS patterns for functional groups and structural featuresLoad these references when needing specific API details, parameter information, or pattern examples.
Only the files listed in references/ and scripts/ are bundled local resources. Names such as rdkit, datamol, scipy, and sklearn refer to installable Python packages, not local files in this skill.
Example scripts for common RDKit workflows:
molecular_properties.py - Calculate comprehensive molecular properties and descriptorssimilarity_search.py - Perform fingerprint-based similarity screeningsubstructure_filter.py - Filter molecules by substructure patternsThese scripts can be executed directly or used as templates for custom workflows.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | pass→pass | 16,771 | 19,530 | +16% | 1 | 1 | 0% | 3,260 | 9,501 | +191% | 0 | 0 | — |
case-02 | pass→pass | 5,897 | 3,508 | -41% | 1 | 1 | 0% | 1,018 | 7,038 | +591% | 0 | 0 | — |
case-03 | pass→pass | 21,579 | 14,665 | -32% | 1 | 1 | 0% | 3,118 | 9,133 | +193% | 0 | 0 | — |
case-04 | pass→pass | 12,049 | 7,766 | -36% | 1 | 1 | 0% | 1,725 | 7,669 | +345% | 0 | 0 | — |
case-05 | pass→pass | 12,331 | 6,597 | -47% | 1 | 1 | 0% | 1,803 | 7,637 | +324% | 0 | 0 | — |
case-06 | pass→pass | 12,469 | 7,617 | -39% | 1 | 1 | 0% | 1,832 | 7,954 | +334% | 0 | 0 | — |
case-07 | fail→pass | 22,699 | 7,659 | -66% | 1 | 1 | 0% | 3,944 | 7,775 | +97% | 0 | 0 | — |
case-08 | fail→pass | 17,308 | 5,402 | -69% | 1 | 1 | 0% | 2,499 | 7,383 | +195% | 0 | 0 | — |
case-09 | fail→fail | 22,222 | 23,149 | +4% | 1 | 1 | 0% | 3,375 | 11,486 | +240% | 0 | 0 | — |
case-10 | fail→fail | 18,832 | 20,457 | +9% | 1 | 1 | 0% | 2,671 | 9,439 | +253% | 0 | 0 | — |
case-11 | fail→pass | 14,729 | 16,677 | +13% | 1 | 1 | 0% | 2,264 | 9,072 | +301% | 0 | 0 | — |
case-12 | pass→pass | 11,829 | 11,945 | +1% | 1 | 1 | 0% | 1,924 | 8,153 | +324% | 0 | 0 | — |
case-13 | fail→pass | 19,101 | 18,042 | -6% | 1 | 1 | 0% | 2,953 | 9,068 | +207% | 0 | 0 | — |
case-14 | fail→pass | 16,093 | 4,757 | -70% | 1 | 1 | 0% | 2,210 | 7,321 | +231% | 0 | 0 | — |
case-15 | pass→pass | 16,669 | 15,222 | -9% | 1 | 1 | 0% | 2,459 | 9,162 | +273% | 0 | 0 | — |
case-16 | fail→pass | 13,440 | 9,373 | -30% | 1 | 1 | 0% | 2,470 | 8,229 | +233% | 0 | 0 | — |
case-17 | pass→pass | 19,776 | 16,146 | -18% | 1 | 1 | 0% | 2,856 | 9,068 | +218% | 0 | 0 | — |
case-18 | fail→pass | 11,572 | 23,141 | +100% | 1 | 1 | 0% | 2,059 | 10,764 | +423% | 0 | 0 | — |
case-19 | fail→fail | 14,435 | 19,165 | +33% | 1 | 1 | 0% | 2,851 | 10,334 | +262% | 0 | 0 | — |
case-20 | pass→pass | 10,586 | 12,642 | +19% | 1 | 1 | 0% | 2,198 | 8,782 | +300% | 0 | 0 | — |
case-21 | pass→pass | 18,770 | 14,753 | -21% | 1 | 1 | 0% | 2,821 | 9,479 | +236% | 0 | 0 | — |
case-22 | fail→fail | 16,243 | 8,855 | -45% | 1 | 1 | 0% | 3,025 | 8,300 | +174% | 0 | 0 | — |
case-23 | pass→pass | 15,373 | 21,294 | +39% | 1 | 1 | 0% | 2,256 | 10,996 | +387% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +30 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.