Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Guidance for package and feature lifecycle in the Agent Framework Python codebase, including stage meanings, feature-stage decorators, feature enums, and how to move APIs from one stage to the next.
.claude/skills/microsoft-python-feature-lifecycle/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-06 | ✗→✓ | ▲ Improved | -6% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 12% | 0% |
| case-01 | ✗→✓ | ▲ Improved | 31% | 0% |
| case-02 | ✗→✓ | ▲ Improved | -14% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 2% | 0% |
Agent Framework uses lifecycle at two different levels:
These are related, but they are not the same thing.
If a package is still in beta / experimental preview, all public APIs in that package are experimental by default.
@experimental(...) everywhere in that package.Once a package moves forward, you can keep individual features behind:
That is the main use case for feature-stage decorators.
Use for features that are still unstable and may change or be removed without notice.
Feature-level code pattern:
pythonfrom ._feature_stage import ExperimentalFeature, experimental @experimental(feature_id=ExperimentalFeature.MY_FEATURE) class MyFeature: ...
Behavior:
Enum setup:
ExperimentalFeatureUse for features that are nearly stable but may still receive small refinements before GA.
Feature-level code pattern:
pythonfrom ._feature_stage import ReleaseCandidateFeature, release_candidate @release_candidate(feature_id=ReleaseCandidateFeature.MY_FEATURE) class MyFeature: ...
Behavior:
Enum setup:
ReleaseCandidateFeatureUse for stable GA APIs.
Code pattern:
ExperimentalFeatureReleaseCandidateFeatureIf a feature is fully released, remove any stage-specific feature annotation.
Use for APIs that still exist but should not be used for new code.
Code pattern:
pythonimport sys if sys.version_info >= (3, 13): from warnings import deprecated # type: ignore # pragma: no cover else: from typing_extensions import deprecated # type: ignore # pragma: no cover @deprecated("MyOldFeature is deprecated. Use MyNewFeature instead.") class MyOldFeature: ...
Behavior:
Deprecated APIs should not also carry feature-stage decorators.
| Feature stage | Expected annotation | | --- | --- | | Experimental | @experimental(feature_id=ExperimentalFeature.X) | | Release candidate | @release_candidate(feature_id=ReleaseCandidateFeature.X) | | Released | No feature-stage decorator | | Deprecated | @deprecated("...") |
The feature enums are the inventory of currently staged features:
ExperimentalFeatureReleaseCandidateFeatureGuidance:
Minimal consumer guidance:
__feature_stage__ and __feature_id__ as optional staged metadata, not as stable contractsgetattr(obj, "__feature_stage__", None) and getattr(obj, "__feature_id__", None) rather than direct attribute accessExperimentalFeature.X, ReleaseCandidateFeature.X, or the continued presence of __feature_id__ after a feature moves stages or is releasedFor consumers, the enums are also re-exported from agent_framework.
For internal implementation code inside agent_framework, continue to import the enums and decorators from ._feature_stage.
Use the following rules:
@experimental(...) only for features that are intentionally still behind the package@experimental(...) or @release_candidate(...) only for features still being held backExperimentalFeature to ReleaseCandidateFeature@experimental(...) with @release_candidate(...)@experimental(...)ExperimentalFeature@release_candidate(...)ReleaseCandidateFeature@deprecated("...")Features do not have to pass through every stage.
Likewise, when a package advances, do not automatically move every feature with it.
__feature_stage__ and __feature_id__ as optional metadata; use getattr| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-06 | fail→pass | 16,716 | 6,347 | -62% | 1 | 1 | 0% | 3,123 | 2,936 | -6% | 0 | 0 | — |
case-05 | fail→pass | 15,509 | 6,714 | -57% | 1 | 1 | 0% | 2,663 | 2,994 | +12% | 0 | 0 | — |
case-01 | fail→pass | 13,030 | 19,575 | +50% | 1 | 1 | 0% | 2,386 | 3,114 | +31% | 0 | 0 | — |
case-02 | fail→pass | 17,726 | 7,044 | -60% | 1 | 1 | 0% | 3,460 | 2,968 | -14% | 0 | 0 | — |
case-03 | fail→pass | 16,815 | 7,068 | -58% | 1 | 1 | 0% | 2,957 | 3,024 | +2% | 0 | 0 | — |
case-04 | fail→pass | 13,422 | 5,455 | -59% | 1 | 1 | 0% | 2,464 | 2,778 | +13% | 0 | 0 | — |
case-07 | fail→pass | 13,069 | 6,053 | -54% | 1 | 1 | 0% | 2,389 | 2,822 | +18% | 0 | 0 | — |
case-08 | fail→pass | 11,660 | 5,892 | -49% | 1 | 1 | 0% | 2,265 | 2,856 | +26% | 0 | 0 | — |
case-09 | fail→pass | 12,859 | 5,414 | -58% | 1 | 1 | 0% | 2,095 | 2,742 | +31% | 0 | 0 | — |
case-10 | pass→pass | 11,356 | 6,764 | -40% | 1 | 1 | 0% | 2,088 | 2,891 | +38% | 0 | 0 | — |
case-11 | pass→pass | 8,489 | 5,510 | -35% | 1 | 1 | 0% | 1,491 | 2,688 | +80% | 0 | 0 | — |
case-12 | pass→pass | 8,036 | 2,543 | -68% | 1 | 1 | 0% | 1,427 | 2,148 | +51% | 0 | 0 | — |
case-13 | pass→pass | 9,050 | 5,086 | -44% | 1 | 1 | 0% | 1,533 | 2,592 | +69% | 0 | 0 | — |
case-14 | pass→pass | 5,394 | 4,503 | -17% | 1 | 1 | 0% | 927 | 2,430 | +162% | 0 | 0 | — |
case-15 | pass→pass | 8,978 | 7,177 | -20% | 1 | 1 | 0% | 1,442 | 2,992 | +107% | 0 | 0 | — |
case-16 | fail→pass | 6,636 | 2,168 | -67% | 1 | 1 | 0% | 1,034 | 2,013 | +95% | 0 | 0 | — |
case-17 | fail→pass | 9,718 | 4,526 | -53% | 1 | 1 | 0% | 1,622 | 2,517 | +55% | 0 | 0 | — |
case-18 | pass→pass | 11,364 | 5,971 | -47% | 1 | 1 | 0% | 1,681 | 2,737 | +63% | 0 | 0 | — |
case-19 | pass→pass | 14,146 | 7,811 | -45% | 1 | 1 | 0% | 2,273 | 3,059 | +35% | 0 | 0 | — |
case-20 | pass→pass | 12,916 | 9,088 | -30% | 1 | 1 | 0% | 1,873 | 3,056 | +63% | 0 | 0 | — |
case-21 | pass→pass | 6,359 | 4,849 | -24% | 1 | 1 | 0% | 1,158 | 2,570 | +122% | 0 | 0 | — |
case-22 | pass→pass | 6,317 | 3,986 | -37% | 1 | 1 | 0% | 924 | 2,457 | +166% | 0 | 0 | — |
case-23 | fail→pass | 12,060 | 7,918 | -34% | 1 | 1 | 0% | 2,216 | 2,910 | +31% | 0 | 0 | — |
case-24 | pass→pass | 8,594 | 2,902 | -66% | 1 | 1 | 0% | 1,304 | 2,049 | +57% | 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. 24 cases were attempted. The headline lift of +50 percentage points is the difference between those two pass rates over the 24 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.