AGENT SKILL

experiments

Use when adding, changing, or reviewing a VS Code A/B experiment, either an experiment-controlled setting or a treatment read with the assignment service, and when deciding whether and where to log an `experimentTrigger` event for a triggered ExP scorecard.

License 许可
MIT
所属仓库
microsoft/vscode
最近更新
2026-11-11
Stars
★ 20w
Forks
4.4w

01 前言 Front Matter

name
experiments
description
Use when adding, changing, or reviewing a VS Code A/B experiment, either an experiment-controlled setting or a treatment read with the assignment service, and when deciding whether and where to log an `experimentTrigger` event for a triggered ExP scorecard.

03 SKILL.md 正文

Experiments

Controlling behavior

  • Experiment-controlled setting: add experiment: { mode: 'auto' } to the setting's schema, or mode: 'startup' to only pick up changed assignments on startup. ExP then sets the setting's default through the treatment config.<setting id> (or experiment.name), and code reads the setting with IConfigurationService as usual. Values that users set themselves still win. Use this when users could reasonably choose the behavior themselves.
  • Keyed object setting: treatments can't be objects, so to let separate experiments control separate keys of an object setting, such as one experiment per extension, add keyed: true to its experiment. ExP then sets each key's default through the treatment config.<setting id>.<key>, and the mode applies to each key separately. Treatments can't be enumerated, so a key is only resolved once code requests it with IExperimentalSettingsService.requestKeys. Values that users set for a key still win.
  • Treatment: read a value with IWorkbenchAssignmentService.getTreatment<T>(name). It resolves to undefined without an assignment, so keep a fallback, and read it again on onDidRefetchAssignments. Use this for values that are not user preferences, such as copy or variant names.

To try an assignment locally, set experiments.override.<treatment name> in your user settings, for example "experiments.override.config.chat.mySetting.enabled": true.

Trigger events for triggered scorecards

A triggered scorecard only compares users who reached the moment where control and treatment behave differently, so users that the experiment never affected don't dilute the result. Log that moment with the helpers in experimentTrigger.ts:

logSettingExperimentTrigger(telemetryService, MY_SETTING_ID); // experiment-controlled setting
logSettingKeyExperimentTrigger(telemetryService, MY_SETTING_ID, key); // key of a keyed object setting
logExperimentTrigger(telemetryService, 'myTreatment'); // treatment

They log the shared experimentTrigger event with the treatment name as treatmentName, at most once per window or process, so they can run on every evaluation. Base the scorecard's trigger on that event (monacoworkbench/experimentTrigger) and its treatmentName. Don't add feature-specific trigger events.

When to use one

Use a trigger when only some assigned users are affected, at an identifiable moment: an action, a surface that only appears in some situations, or a code path that only some sessions reach. Don't use one when:

  • nearly every assigned user is affected anyway, like a changed default in a common view;
  • no single moment precedes every effect, like a feature switch that also changes commands or agent tools before anything is visible (chat.agentMerge.enabled);
  • the population is already limited: onboarding experiments (IOnboardingScenario.experiment) only attach their assignment context to telemetry from the moment the tour would show.

Prefer no trigger over an approximate one. Dilution only costs statistical power, while a biased trigger gives wrong results.

When to fire it

Fire it where the code decides between control and treatment behavior, before they differ, under a condition that is the same in every arm.

The treatment… Fire when…
changes what an action does the action runs
adds UI that control lacks the UI would render, checked in every arm
changes copy or an icon that UI renders
changes a delay the countdown starts, not when the delayed UI shows
changes a default that users can override the default is visible and no user choice is stored
changes background behavior the diverging code path runs
// Checking the setting first would only trigger the treatment arm.
if (isBannerRelevant(context)) {
	logSettingExperimentTrigger(telemetryService, MY_SETTING_ID);
	if (configurationService.getValue<boolean>(MY_SETTING_ID)) {
		showBanner();
	}
}

Common pitfalls:

  • State only the treatment writes, like dismissed or seen flags. Ignore it until the trigger has fired.
  • Data only the treatment computes, like CI status that is only polled for an indicator. Use an arm-independent superset, or compute it in every arm until the trigger has fired.
  • Missed exposure, like accessible labels, menus, or features that the setting suppresses. Find every place where the setting or treatment changes behavior, because a user affected before their first trigger biases the result.

Excluding users who can't be affected, such as reduced-motion users for an animation, is fine when the condition is the same in every arm. Agent host telemetry only carries the assignment context once the workbench has forwarded it, so hold earlier triggers until then (see AgentHostGitStateService).

Test each trigger in every arm with TestExperimentTriggerTelemetryService. After adding or moving a trigger, start a new experiment iteration, because earlier exposures have no trigger events.

Reporting results

Scorecard results are internal data. A pull request, commit or issue that ships, changes, graduates or removes an experiment describes only the code change. Don't explain the change with the experiment, its rollout or its results, even without numbers, such as "the treatment improved the primary metric" or "the experiment showed no regression"; link its tracking issue instead (see "Public Content" in copilot-instructions.md).

04 同仓库更多 Skills

microsoft
microsoft/vscode

sweeper-query

Answer natural-language questions about the VS Code Sweeper's published issue index (index-<name>.json for microsoft/vscode and the enrolled family repos) — which issues are agent-ready to implement or plan, what the sweeper proposed for an assignee or area, whether the sweeper knows a report as a duplicate, the highest-value open bugs in a lane — and, for one issue, the review's full record (evidence with file citations, fix brief, proposed comment). Use ONLY when the request explicitly names the sweeper — "sweeper", "vscodesweeper", "sweeper-query", a sweeper verdict, record, brief or index, an agent-ready issue — or asks what "the sweeper" found, proposed or knows. Do NOT use for general questions about issues, duplicates, priorities or ranking that do not mention the sweeper. Read-only; discovery only.

★ 20w
microsoft
microsoft/vscode

update-skills

Create or update repository skills and instructions when major learnings are discovered during a session. Use when the user says "learn!", when a significant pattern or pitfall is identified, or when reusable domain knowledge should be captured for future sessions.

★ 20w
microsoft
microsoft/vscode

update-pr

Update the pull request for the current session. Use when the user wants to push new changes to an existing PR.

★ 20w
microsoft
microsoft/vscode

sync

Sync the current session branch with its upstream branch, or publish the current session branch to a remote. Use when the user asks to sync a branch, pull latest changes, rebase onto upstream, push current branch, publish branch, or set upstream.

★ 20w
microsoft
microsoft/vscode

sync-upstream

Update a stale session branch by rebasing onto the latest origin. Use when the upstream has moved significantly and the session needs to catch up, resolving conflicts by preserving upstream changes and adapting session work to fit.

★ 20w
microsoft
microsoft/vscode

merge

Merge changes from the topic branch to the merge base branch. Use when the user wants to merge their session's work back to the base branch.

★ 20w