Adapt Learning¶
adapt_learning — mvp.adapt_learning
Cluster: ML & Optimisation | Type: component | MCP Tools: 23
Overview¶
Meta-learning algorithm selector that analyses a dataset's statistical properties — sample count, feature count, class imbalance, sparsity, linearity — and recommends the most suitable scikit-learn algorithm ranked by estimated performance, with complexity and reasoning included. Works without any external model or API call; all recommendations are derived from heuristic meta-feature rules and can be passed directly to adapt_sklearn or adapt_automl for execution.
When to use:
- Choosing an appropriate ML algorithm before committing to training in a resource-constrained pipeline
- Explaining algorithm selection decisions to downstream agents or human reviewers
- Routing tabular datasets to the right solver (classification / regression / clustering) automatically
- Building a two-phase pipeline: recommend with
adapt_learning, then fit withadapt_sklearn
Example:
from mvp.adapt_learning import AdaptLearningBlock, MetaLearningInput
block = AdaptLearningBlock(name="learning")
result = block.infer(MetaLearningInput(
X=[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]],
y=[0, 1, 0],
task="classification",
budget="small",
))
# result.value.recommendations[0].algorithm → e.g. "LogisticRegression"
# result.value.recommendations[0].reasoning → explanation string
Works well with: adapt_sklearn, adapt_automl, align_evals
Operational Notes¶
AdaptLearningBlockis a deterministic rule-based selector. It is useful for fast algorithm triage, explainable recommendations, and routing into training components, but itsestimated_scorevalues are heuristic priors, not measured model accuracy.task="auto"uses simple target-shape heuristics. Emptyyis treated as clustering, string labels are treated as classification, and low-cardinality numeric targets are treated as classification. Pass an explicittaskwhen the target semantics are known.- The MCP layer adds SQLite-backed memory for experiences, heuristics, algorithm outcomes, feedback patterns, and tool-use strengths. This memory can improve ranking through recorded outcomes, but it should be treated as local/project history rather than a global benchmark.
- MCP search requires a non-empty query. Blank queries return an empty result with an explanatory message instead of returning arbitrary records.
- MCP numeric controls are bounded for production safety:
limitis 0-500,top_kis 0-100,scoreandworthare finite values from 0.0 to 1.0, andlatency_msmust be finite and non-negative. AdaptLearningMCPBlock.aio_run()runs synchronous work in a thread pool. Calls are serialized per block instance to protect the shared SQLite connection during concurrent writes.statusandinfoincludeavailable_opsmetadata so MCP clients can discover the supported 20-operation contract without relying on undocumentedopsorhelpoperations.- The
recommendop is uplifted with an advisory LLM re-ranking layer over the deterministic blended-ranking floor: when an LLM backend is reachable (and not opted out viaG6_LEARNING_AGENTIC_RUNTIME=0orG6_DISABLE_LLM=1) the model may RE-RANK the same fixed candidate algorithms using the natural-languagenotescontext; it can never introduce a new algorithm, train a model, or write the store, and degrades to the floor with honestdegraded/degradation_reasonevidence.list_patternslists the applied agentic pattern cards.
Public API¶
RankedAlgorithmRecommendation¶
Validated ranked algorithm recommendation decision record.
| Field | Type | Default |
|---|---|---|
ranking | tuple[dict[str, Any], ...] | required |
source | str | required |
notes | str | '' |
context | str | '' |
Methods:
top() -> dict[str, Any]¶
The top-ranked recommendation dict (empty dict if the ranking is empty).
top_algorithm() -> str¶
to_dict() -> dict[str, Any]¶
The advisory payload: the ranked list of recommendation dicts.
to_metadata() -> dict[str, Any]¶
LearningDecisionError(ValueError)¶
The LLM did not produce a usable, validated algorithm recommendation.
LLMLearningRuntime¶
Provider-neutral algorithm-ranking runtime over G6's LLM caller.
Constructor:
| Parameter | Type | Default |
|---|---|---|
llm | LLMCaller \| None | None |
Methods:
recommend(meta_features: dict[str, Any], candidates: list[dict[str, Any]], context: str = '') -> Result[dict]¶
LearningAlgorithmPlanner¶
Runtime-first facade with the deterministic floor as honest fallback.
Constructor:
| Parameter | Type | Default |
|---|---|---|
runtime | LearningRuntime \| None | None |
Methods:
recommend(meta_features: dict[str, Any], candidates: list[dict[str, Any]], history: dict[str, float] | None = None, context: str = '') -> RankedAlgorithmRecommendation¶
AdaptLearningBlock(AIBlock[MetaLearningInput, MetaLearningOutput, None])¶
Meta-learning algorithm selector.
| Field | Type | Default |
|---|---|---|
name | str | 'adapt_learning' |
resource_bounds | ResourceBounds \| None | None |
usage | ResourceUsage | field(default_factory=ResourceUsage) |
Methods:
infer(data: MetaLearningInput) -> Result[MetaLearningOutput]¶
MetaLearningInput(BaseModel)¶
Input to AdaptLearningBlock.
| Field | Type | Default |
|---|---|---|
X | list[list[float]] | required |
y | list[float \| int \| str] | Field(default_factory=list) |
task | Literal['classification', 'regression', 'clustering', 'auto'] | 'auto' |
budget | Literal['tiny', 'small', 'medium', 'large'] | 'small' |
AlgorithmRecommendation(BaseModel)¶
A recommended algorithm with justification.
| Field | Type | Default |
|---|---|---|
algorithm | str | required |
reasoning | str | required |
estimated_score | float | required |
complexity | Literal['O(n)', 'O(n log n)', 'O(n²)', 'O(n³)'] | required |
MetaLearningOutput(BaseModel)¶
Output from AdaptLearningBlock.
| Field | Type | Default |
|---|---|---|
task_detected | str | required |
n_samples | int | required |
n_features | int | required |
recommendations | list[AlgorithmRecommendation] | required |
dataset_properties | dict[str, object] | Field(default_factory=dict) |
degraded | bool | False |
degradation_reason | str | '' |
Methods:
to_sklearn_config(rank: int = 0) -> 'ModelConfig'¶
Convert the top recommendation to an adapt_sklearn ModelConfig.
AdaptLearningMCPBlock(AIBlock[MCPLearningInput, MCPLearningOutput, dict])¶
Full-featured meta-learning block with SQLite persistence.
| Field | Type | Default |
|---|---|---|
name | str | 'adapt_learning_mcp' |
state | dict \| None | None |
db_path | str | ':memory:' |
resource_bounds | ResourceBounds \| None | None |
usage | ResourceUsage | field(default_factory=ResourceUsage) |
Methods:
infer(data: MCPLearningInput) -> Result[MCPLearningOutput]¶
aio_run(data: MCPLearningInput) -> Result[MCPLearningOutput]¶
Async wrapper: runs the synchronous infer() in a thread pool to avoid blocking the event loop.
MCPLearningRecord(BaseModel)¶
| Field | Type | Default |
|---|---|---|
id | str | required |
record_type | str | required |
key | str | required |
value | str | required |
tags | list[str] | Field(default_factory=list) |
timestamp | str | required |
metadata | dict[str, Any] | Field(default_factory=dict) |
MCPLearningInput(BaseModel)¶
| Field | Type | Default |
|---|---|---|
op | Literal['recommend', 'meta_features', 'detect_task', 'list_algorithms', 'status', 'record_experience', 'query_experiences', 'summarize_experiences', 'store_heuristic', 'retrieve_heuristics', 'evaluate_heuristic', 'record_outcome', 'query_outcomes', 'record_feedback', 'get_feedback_patterns', 'record_tool_use', 'get_strengths', 'search', 'info', 'list_patterns', 'native_sklearn_capabilities', 'native_recommendation_preview', 'native_estimator_config_preview'] | required |
X | list[list[float]] | Field(default_factory=list) |
y | list | Field(default_factory=list) |
task | str | 'auto' |
budget | str | 'small' |
key | str | '' |
value | str | '' |
tags | list[str] | Field(default_factory=list) |
query | str | '' |
limit | int | Field(default=50, ge=0, le=500) |
top_k | int | Field(default=5, ge=0, le=100) |
task_id | str | '' |
description | str | '' |
what_worked | str | '' |
what_failed | str | '' |
task_type | str | '' |
name | str | '' |
domain | str | '' |
worth | float | 0.5 |
algorithm | str | '' |
score | float | 0.0 |
notes | str | '' |
success | bool | True |
error_type | str | '' |
tool_name | str | '' |
latency_ms | float | 0.0 |
backend | str | 'sklearn' |
estimator | str | '' |
params | dict[str, Any] | Field(default_factory=dict) |
request_id | str | '' |
run_id | str | '' |
MCPLearningOutput(BaseModel)¶
| Field | Type | Default |
|---|---|---|
op | str | required |
key | str | '' |
value | str | '' |
found | bool | False |
count | int | 0 |
records | list[MCPLearningRecord] | Field(default_factory=list) |
recommendations | list[dict[str, Any]] | Field(default_factory=list) |
retrieved | list[str] | Field(default_factory=list) |
scores | list[float] | Field(default_factory=list) |
summary | str | '' |
message | str | '' |
metadata | dict[str, Any] | Field(default_factory=dict) |
degraded | bool | False |
degradation_reason | str | '' |
capability_status | str | 'available' |
completion_state | Literal['verified', 'qualified-draft', 'blocked-escalated'] | 'qualified-draft' |
warning_card | dict[str, Any] | Field(default_factory=dict) |
evidence | list[dict[str, Any]] | Field(default_factory=list) |
request_id | str | '' |
task_id | str | '' |
run_id | str | '' |
LearningStore¶
Sync SQLite learning store with 5 tables.
Constructor:
| Parameter | Type | Default |
|---|---|---|
db_path | str | ':memory:' |
Methods:
get_schema_version() -> int¶
Return the stored schema version integer.
add_experience(task_id: str, description: str, what_worked: str, what_failed: str, task_type: str, tags: list[str]) -> str¶
query_experiences(query: str = '', task_type: str = '', limit: int = 50) -> list[dict[str, Any]]¶
upsert_heuristic(name: str, description: str, domain: str, worth: float, tags: list[str]) -> str¶
query_heuristics(query: str = '', domain: str = '', top_k: int = 5) -> list[dict[str, Any]]¶
update_heuristic_eval(name: str, success: bool, score: float, notes: str) -> bool¶
add_outcome(algorithm: str, task_type: str, score: float, notes: str) -> str¶
get_avg_scores_by_task(task_type: str = '') -> dict[str, float]¶
Return {algorithm: avg_score} from recorded outcomes, optionally filtered by task type.
query_outcomes(algorithm: str = '', task_type: str = '', limit: int = 50) -> list[dict[str, Any]]¶
add_error(task_type: str, algorithm: str, error_type: str, notes: str) -> str¶
get_error_patterns(min_frequency: int = 2) -> list[dict[str, Any]]¶
add_tool_use(tool_name: str, domain: str, success: bool, latency_ms: float) -> str¶
get_domain_strengths() -> list[dict[str, Any]]¶
text_search(query: str, top_k: int = 5) -> list[dict[str, Any]]¶
TF-IDF search across experiences, heuristics, and outcomes. Results cached per write cycle.
count_all() -> dict[str, int]¶
Functions¶
agentic_planner_enabled(default_enabled: bool = True) -> bool¶
Decide whether the agentic algorithm-planner should be used.
validate_algorithm_recommendation(rec: Any, allowed: set[str]) -> dict¶
Reject any algorithm recommendation outside the canonical shape / vocabulary.
recommend_floor(candidates: list[dict[str, Any]], history: dict[str, float] | None = None, context: str = '') -> RankedAlgorithmRecommendation¶
Deterministic blended-ranking algorithm selector (the honest floor).
MCP Tools¶
| Operation | Source |
|---|---|
recommend | learning_mcp |
meta_features | learning_mcp |
detect_task | learning_mcp |
list_algorithms | learning_mcp |
status | learning_mcp |
record_experience | learning_mcp |
query_experiences | learning_mcp |
summarize_experiences | learning_mcp |
store_heuristic | learning_mcp |
retrieve_heuristics | learning_mcp |
evaluate_heuristic | learning_mcp |
record_outcome | learning_mcp |
query_outcomes | learning_mcp |
record_feedback | learning_mcp |
get_feedback_patterns | learning_mcp |
record_tool_use | learning_mcp |
get_strengths | learning_mcp |
search | learning_mcp |
info | learning_mcp |
list_patterns | learning_mcp |
native_sklearn_capabilities | learning_mcp |
native_recommendation_preview | learning_mcp |
native_estimator_config_preview | learning_mcp |