feat(skills): add SkillDiscoveryMode to skip the discovery turn - #7093
thomaslprr wants to merge 4 commits into
Conversation
Expose a public flag so the L1 catalog can be injected into the system instruction without mutating SkillToolset._tools. Fixes google#7092
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
|
Hi @thomaslprr, thanks for the PR! We like the idea of skipping the discovery turn, but we reshaped it slightly to use an enum (discovery_mode=SkillDiscoveryMode.EAGER vs LAZY) since omitting list_skills has the major side effect of injecting the catalog into the system prompt. We kept your core logic and all your tests -- would this approach work for you? |
Hi @wukath, yes, that works for me - Would you like me to update this PR to the enum API, or will you land the reshaped version on your side? I already have the changes ready locally if you'd like me to push them. |
Use discovery_mode=EAGER|LAZY so the API names the coupled behavior (hide list_skills + inject <available_skills>). Reject non-enum values with TypeError. Fixes google#7092
|
@wukath, I pushed the enum reshape as discussed:
Core logic and tests are updated (159 passed locally). I also set up a local ADK sample based on Thanks! |
… is disclosed Merge #7093 By default, SkillToolset provides the `list_skills` tool, which requires the model to spend an extra turn discovering available skills before calling `load_skill`. For small, static skill sets, this discovery turn adds latency and token overhead. This change introduces `SkillDiscoveryMode` to control catalog disclosure: - `LAZY` (default): Retains the `list_skills` tool so skills are discovered on demand. The system instruction remains free of skill listings. - `EAGER`: Omits `list_skills` and injects the local catalog directly into the system instruction as `<available_skills>` XML, allowing the model to call `load_skill` immediately. Additionally, deprecates using `tool_filter` to hide `list_skills` as a way to trigger prompt injection. Filtering tools should not implicitly rewrite the system prompt; callers should pass `discovery_mode=SkillDiscoveryMode.EAGER` instead. Fixes #7092 Co-authored-by: Thomas Lapierre <thomaslapierre.dev@gmail.com> Co-authored-by: Kathy Wu <wukathy@google.com> PiperOrigin-RevId: 981254533
|
Thank you @thomaslprr for your contribution! 🎉 Your changes have been successfully imported and merged via Copybara in commit 3d3c1d9. Closing this PR as the changes are now in the main branch. |
Link to Issue or Description of Change
1. Link to an existing issue (if applicable):
Problem:
There is no public way to inject the L1 skill catalog into the system instruction. Hiding
list_skillsrequired mutating_tools.Solution:
Add
SkillToolset(discovery_mode=SkillDiscoveryMode.EAGER|LAZY).LAZY(default): exposelist_skills.EAGER: hidelist_skillsand inject<available_skills>XML so the model can callload_skilldirectly.Non-enum values raise
TypeError.Testing Plan
Unit Tests:
Manual End-to-End (E2E) Tests:
contributing/samples/environment_and_skills/skills_agentwithdiscovery_mode=SkillDiscoveryMode.EAGER:list_skillstool<available_skills>present in the system instruction (greeting-skill,weather-skill)load_skilldirectlyLAZYstill exposeslist_skills.search_skillsremains available inEAGER.Checklist