Skip to content

Commit 4285f85

Browse files
wukathcopybara-github
authored andcommitted
fix: Include list of skills in every message and remove list_skills tool from system instruction
The list_skills method is not for model tool listing, but for giving the developer flexibility to load the skill name/description at runtime (from discussion in go/orcas-rfc-555) Co-authored-by: Kathy Wu <wukathy@google.com> PiperOrigin-RevId: 871406905
1 parent ea03487 commit 4285f85

2 files changed

Lines changed: 36 additions & 4 deletions

File tree

src/google/adk/tools/skill_toolset.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from __future__ import annotations
1818

1919
from typing import Any
20+
from typing import TYPE_CHECKING
2021

2122
from google.genai import types
2223

@@ -29,6 +30,9 @@
2930
from .base_toolset import BaseToolset
3031
from .tool_context import ToolContext
3132

33+
if TYPE_CHECKING:
34+
from ..models.llm_request import LlmRequest
35+
3236
DEFAULT_SKILL_SYSTEM_INSTRUCTION = """You can use specialized 'skills' to help you with complex tasks. You MUST use the skill tools to interact with these skills.
3337
3438
Skills are folders of instructions and resources that extend your capabilities for specialized tasks. Each skill folder contains:
@@ -38,10 +42,9 @@
3842
3943
This is very important:
4044
41-
1. Use the `list_skills` tool to discover available skills.
42-
2. If a skill seems relevant to the current user query, you MUST use the `load_skill` tool with `name="<SKILL_NAME>"` to read its full instructions before proceeding.
43-
3. Once you have read the instructions, follow them exactly as documented before replying to the user. For example, If the instruction lists multiple steps, please make sure you complete all of them in order.
44-
4. The `load_skill_resource` tool is for viewing files within a skill's directory (e.g., `references/*`, `assets/*`). Do NOT use other tools to access these files.
45+
1. If a skill seems relevant to the current user query, you MUST use the `load_skill` tool with `name="<SKILL_NAME>"` to read its full instructions before proceeding.
46+
2. Once you have read the instructions, follow them exactly as documented before replying to the user. For example, If the instruction lists multiple steps, please make sure you complete all of them in order.
47+
3. The `load_skill_resource` tool is for viewing files within a skill's directory (e.g., `references/*`, `assets/*`). Do NOT use other tools to access these files.
4548
"""
4649

4750

@@ -241,3 +244,11 @@ def _get_skill(self, name: str) -> models.Skill | None:
241244
def _list_skills(self) -> list[models.Frontmatter]:
242245
"""Lists the frontmatter of all available skills."""
243246
return [s.frontmatter for s in self._skills.values()]
247+
248+
async def process_llm_request(
249+
self, *, tool_context: ToolContext, llm_request: LlmRequest
250+
) -> None:
251+
"""Processes the outgoing LLM request to include available skills."""
252+
skill_frontmatters = self._list_skills()
253+
skills_xml = prompt.format_skills_as_xml(skill_frontmatters)
254+
llm_request.append_instructions([skills_xml])

tests/unittests/tools/test_skill_toolset.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
from unittest import mock
1616

17+
from google.adk.models import llm_request as llm_request_model
1718
from google.adk.skills import models
1819
from google.adk.tools import skill_toolset
1920
from google.adk.tools import tool_context
@@ -249,3 +250,23 @@ async def test_load_resource_run_async(
249250
tool = skill_toolset.LoadSkillResourceTool(toolset)
250251
result = await tool.run_async(args=args, tool_context=tool_context_instance)
251252
assert result == expected_result
253+
254+
255+
@pytest.mark.asyncio
256+
async def test_process_llm_request(
257+
mock_skill1, mock_skill2, tool_context_instance
258+
):
259+
toolset = skill_toolset.SkillToolset([mock_skill1, mock_skill2])
260+
llm_req = mock.create_autospec(llm_request_model.LlmRequest, instance=True)
261+
262+
await toolset.process_llm_request(
263+
tool_context=tool_context_instance, llm_request=llm_req
264+
)
265+
266+
llm_req.append_instructions.assert_called_once()
267+
args, _ = llm_req.append_instructions.call_args
268+
instructions = args[0]
269+
assert len(instructions) == 1
270+
assert "<available_skills>" in instructions[0]
271+
assert "skill1" in instructions[0]
272+
assert "skill2" in instructions[0]

0 commit comments

Comments
 (0)