symfonic.core.learning.procedural_extractor_llm¶
procedural_extractor_llm ¶
LLM-backed procedural extractor (v7.6 — adopter Ask 9 Option A).
Single LLM call per tenant per nightly_nap. Reads recent episodic
entries enriched with the v7.4.7 metadata['tool_calls'] trace
producer, asks the model to identify durable action / preflight /
recovery / guardrail rules, and emits structured
:class:~symfonic.core.learning.procedural_extractor.ProceduralDraft
records that the dispatch site in
:mod:symfonic.core.learning.phases_procedural_promotion turns into
draft :class:~symfonic.memory.models.entry.MemoryEntry writes via
:func:~symfonic.memory.layers.procedural.layer.ProceduralLayer.store_skill.
Lift-and-shift from :mod:symfonic.core.learning.entity_extractor_llm
(v7.2) — same best-effort JSON parsing contract: malformed responses,
missing fields, and model-invocation exceptions all yield [] rather
than raise.
Default-off ship: the extractor is reachable only when
FrameworkConfig.phase_12_use_llm_extractor=True AND the consolidator
has a bound chat model. Either-or with the regex extractor (the eval
recommended this over a merged stream).
Design reference:
.claude/docs/2026-05-28-adopter-llm-procedural-extractor-eval.md
§8.2 / §8.3.
LlmProceduralExtractor ¶
LlmProceduralExtractor(chat_model: Any, *, max_drafts_per_run: int = 10, max_episodes_per_run: int = 100, observability_hook: ObservabilityHook | None = None)
LLM-backed Phase 12 procedural-draft extractor.
Implements :class:~symfonic.core.learning.procedural_extractor.ProceduralExtractor.
Construct the extractor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chat_model
|
Any
|
A LangChain-compatible chat model exposing
|
required |
max_drafts_per_run
|
int
|
Hard cap on drafts the extractor will
return per call. Default 5 mirrors the regex
extractor's |
10
|
max_episodes_per_run
|
int
|
Hard cap on episodes fed into the prompt. Excess episodes are dropped from the tail (older entries) so the freshest context wins. |
100
|
Source code in src/symfonic/core/learning/procedural_extractor_llm.py
extract
async
¶
extract(episodes: list[MemoryEntry], existing_skills: list[MemoryEntry], scope: TenantScope, *, callback_manager: CallbackManager | None = None, run_id: str = '', model_name: str = 'procedural_extractor_llm') -> list[ProceduralDraft]
Extract procedural drafts from recent episodes.
Returns [] rather than raising on every failure path: empty
input, None chat model, model exception, malformed JSON,
missing fields. The dispatch site logs the empty result via
the standard Phase 12 telemetry line.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
episodes
|
list[MemoryEntry]
|
Recent episodic entries (already filtered to
|
required |
existing_skills
|
list[MemoryEntry]
|
Procedural skills already in storage so the LLM can avoid duplicating them. |
required |
scope
|
TenantScope
|
Tenant scope -- forwarded for future per-tenant prompt customisation; not used by the default prompt. |
required |
callback_manager
|
CallbackManager | None
|
Optional v7.4.3 callback manager. When
provided, fires
|
None
|
run_id
|
str
|
Engine run identifier for callback correlation. |
''
|
model_name
|
str
|
Identifier stamped on the LLMEndEvent. Defaults to the module identifier; consumers that want to surface the actual SKU should pass the resolved model string. |
'procedural_extractor_llm'
|
Returns:
| Type | Description |
|---|---|
list[ProceduralDraft]
|
A list of :class: |
list[ProceduralDraft]
|
<= |