Text features (experimental)

SkillAI & models

Lets your agent turn free-text rows into calibrated numeric features and fit a model on a leakage-safe split.

Available today. Use it from your connected AI after setup.

Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.

Then ask your AI: use the Text features (experimental) skill

About this skill

Turn free-text rows into calibrated numeric features with TypeSafe Jev, then model them on a leakage-safe development split. The main model proposes Noul/Score questions; host.judge answers every row; sklearn in the science extra fits and evaluates. Features keep their source question and measuremen

What this skill tells your AI

The instructions your AI receives, as published by pku-yuangroup/openai4s in skills/text-features/SKILL.md and read by ahel’s review.

Use this skill when you have many free-text rows and a supervised target, and you want calibrated numeric features instead of bag-of-words. The main model proposes operationalizable questions; Jev answers each row; the sidecar fits a model on a development split and scores the frozen test split once.

This is experimental. Turn on text_features under Customize → Experimental (the master experimental-judgment switch must also be on). Headless: set OPENAI4S_EXPERIMENTAL_JUDGMENT=1 and OPENAI4S_JUDGMENT_TEXT_FEATURES=1. When the capability is off, the helpers return status: "disabled" and do not raise.

When to use it

  • Lots of free text (notes, abstracts, reports) plus a label or score.
  • You need features a colleague can read: each column is a question, a probability or graded expectation, and a spread.
  • You can hold out a test set and leave it untouched while questions change.

When not to use it

  • Small samples, or no supervised target — there is nothing to freeze against.
  • Sensitive data. Selected row text is sent to api.typesafe.ai. The service is hosted in the United States. Do not enable this on clinical notes, secrets, or anything that must not leave the machine.
  • You need a human gold standard. Jev features are not a human gold standard. They are calibrated model judgments of the text you sent, with measurement error. Do not treat a Noul probability as a verified fact.

Data that leaves the machine

Every featurize call sends the user-selected row text in state.text to TypeSafe Jev, together with the question instructions. Identifiers go in state.id so you can audit which rows were judged. Quote location and numeric modeling stay in this sidecar.

Import and run

The directory contains a hyphen, so import it with importlib:

from importlib import import_module

tf = import_module("text-features.kernel")

questions = tf.propose_questions(
    "Predict whether an abstract reports a significant clinical result.",
    examples,
    n=12,
)
table = tf.featurize(
    rows,
    questions,
    text_field="text",
    id_field="id",
)
study = tf.run_feature_study(
    rows,
    target="label",
    split_by="patient_id",  # or time_col="date"
    rounds=3,
    text_field="text",
    id_field="id",
)

propose_questions asks host.llm for Noul (yes/no facts) and Score (written-level grades) questions, then validates and deduplicates them.

featurize calls host.judge("features.custom", ...) once per row. Each Noul becomes one column, P(yes). Each Score becomes two columns: the expected level normalized to [0, 1], and the standard deviation of that distribution on the same scale. Unavailable rows are filled with NaN and counted; they are not replaced with a default. Every column keeps the question text and template version.

run_feature_study reuses audit-dataset, plan-ml-experiment (grouped or chronological split), and evaluate-model (metrics and bootstrap 95% CI). Question edits, feature screening, and thresholds use the development rows only. The test split is judged once, after the question set is frozen. The report includes lift versus a constant baseline and a bootstrap interval, plus the question-set version and per-feature provenance. Binary targets are encoded in the reported target_classes order; predictions are probabilities of the second class. Rows with missing targets are excluded from fitting and metrics. Baseline and feature-model lift use the same rows with available predictions.

Modeling uses numpy / pandas / scikit-learn when the science extra is installed. They are imported lazily. They are not core dependencies. Without them the sidecar still featurizes and falls back to a linear least-squares fit.

Required output

Name the split, the frozen question-set version, each feature's source question and template version, unavailable-row counts, cost (requests and tokens), the baseline, the lift, and the bootstrap interval. Never describe the features as labels, facts, or a human gold standard.

Signals

GitHub stars
590
Forks
68
Last commit
Sep 2026
Advanced
Catalog kind
skill
Key
text-features
Source
github.com/pku-yuangroup/openai4s