-
Notifications
You must be signed in to change notification settings - Fork 2.6k
feat: add BigQuery Skills Demo with dynamic skill discovery #3852
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Add a sample agent demonstrating Anthropic's Agent Skills Pattern for dynamic capability discovery with BigQuery ML and AI functions. Key features: - Dynamic skill discovery from SKILL.md files at runtime - Progressive disclosure: skill summaries in prompt, full content on-demand - load_skill tool for agents to request detailed skill documentation - BQML skill: ML model training, evaluation, and prediction in SQL - BQ AI Operator skill: AI.CLASSIFY, AI.IF, AI.SCORE managed functions The demo is self-contained and uses existing BigQuery tools from ADK. Skills are stored as markdown files with YAML frontmatter for metadata. Reference: https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
|
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. |
Summary of ChangesHello @caohy1988, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request adds a new sample agent that demonstrates dynamic skill discovery using Anthropic's Agent Skills Pattern. The agent is designed to efficiently manage its capabilities by initially loading only summaries of available skills (BigQuery ML and AI functions) and fetching detailed documentation on-demand when relevant to a task. This approach optimizes context usage while providing access to a rich set of BigQuery data science and AI tools. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
|
Response from ADK Triaging Agent Hello @caohy1988, thank you for creating this PR! Before we can review this PR, you will need to sign the Contributor License Agreement (CLA). You can find more information at https://cla.developers.google.com/. In addition, this PR is a new feature, could you please associate a GitHub issue with this PR? If there is no existing issue, could you please create one? Finally, could you please provide logs or screenshots of the new feature in action? This will help reviewers to understand and verify your changes. This information will help reviewers to review your PR more efficiently. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces an excellent sample agent demonstrating dynamic skill discovery with BigQuery. The code is well-structured and the implementation of the Anthropic Agent Skills Pattern is clear. I have a few suggestions to improve the robustness and efficiency of the skill registry, primarily around exception handling and the creation of the load_skill tool. Additionally, I've pointed out a couple of hardcoded project IDs in one of the skill definition files that should be updated to avoid confusion for users. Overall, this is a great addition.
| def load_skill(skill_name: str) -> str: | ||
| """Load a skill from the default registry. | ||
|
|
||
| This is the function that should be added as a tool to the agent. | ||
| """ | ||
| return create_load_skill_tool(get_default_registry())(skill_name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current implementation of the load_skill function has two issues:
- Inefficiency: It calls
create_load_skill_toolon every invocation, which re-creates the underlying function object unnecessarily. - Incorrect Docstring: The
FunctionToolinagent.pywill use the docstring from this module-levelload_skillfunction, which is generic. The more descriptive docstring intended for the agent (defined insidecreate_load_skill_tool) is never used. This can negatively impact the agent's ability to understand and use the tool correctly.
A better approach is to create the tool function once at the module level.
load_skill = create_load_skill_tool(get_default_registry())| except Exception: | ||
| return None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The broad except Exception: clause catches all errors silently. This can make debugging difficult if there are issues with parsing skill files (e.g., malformed YAML, file read errors). It would be beneficial to log the exception to aid in troubleshooting, for example by adding logging.warning(f"Failed to parse skill metadata from {skill_path}: {e}") inside the except block.
| except Exception: | ||
| return None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return "\n".join(lines) | ||
|
|
||
|
|
||
| def create_load_skill_tool(registry: SkillRegistry) -> dict[str, Any]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function create_load_skill_tool is type-hinted to return dict[str, Any], but it actually returns a callable function (load_skill). The type hint should be corrected to Callable[[str], str] to reflect the actual return type. You may need to import Callable from typing.
| def create_load_skill_tool(registry: SkillRegistry) -> dict[str, Any]: | |
| def create_load_skill_tool(registry: SkillRegistry) -> "Callable[[str], str]": |
| WHERE AI.IF( | ||
| description, | ||
| 'This product is eco-friendly, sustainable, or environmentally conscious', | ||
| connection_id => 'us.my_ai_connection' -- Use your connection: test-project-0728-467323.us.my_ai_connection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The example for AI.IF contains a hardcoded project ID (test-project-0728-467323). This can be misleading for users running the sample. It should be replaced with a generic placeholder or removed to match the other examples in this file.
| connection_id => 'us.my_ai_connection' -- Use your connection: test-project-0728-467323.us.my_ai_connection | |
| connection_id => 'us.my_ai_connection' -- Replace with your connection |
| WHERE AI.IF( | ||
| review_text, | ||
| 'Content is appropriate and not spam', | ||
| connection_id => 'us.my_ai_connection' -- Use your connection: test-project-0728-467323.us.my_ai_connection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The example in the complete pipeline contains a hardcoded project ID (test-project-0728-467323). This should be replaced with a generic placeholder to avoid confusion for users.
| connection_id => 'us.my_ai_connection' -- Use your connection: test-project-0728-467323.us.my_ai_connection | |
| connection_id => 'us.my_ai_connection' -- Replace with your connection |
Replace persistent load_skill tool with ephemeral skill activation: - Skills are now injected into system prompt (not conversation history) - Add activate_skill/deactivate_skill/list_active_skills tools - Use ADK's InstructionProvider pattern for dynamic system prompt - Skills can be truly unloaded when no longer needed This mirrors Claude Code's approach where skills are loaded on-demand and can be removed to free up context space. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
…r BigQuery Skills Demo This commit enhances the BigQuery Skills Demo with: - **Callback-based auto-activation**: Skills are automatically activated based on keywords in user messages via before_model_callback, eliminating the need for explicit LLM tool calls to manage skills - **Auto-deactivation**: Skills are cleared after each turn via after_agent_callback to free up context - **list_connections and create_connection tools**: Agents can now discover existing BigQuery connections and create new ones with automatic IAM grants - **Location matching documentation**: Skills now document the critical requirement that connection location must match dataset location - **bq_remote_model skill**: New skill for remote models with Vertex AI, including Gemini 2.5 Pro as default model and task-specific parameter guidance (max_output_tokens for summarization vs classification) - **AI.SCORE tuple syntax fix**: Corrected syntax to use tuple format per official BigQuery documentation - **Keywords in SKILL.md frontmatter**: Skills now define keywords that are used for automatic detection 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
This commit fixes the 'LlmRequest' object has no attribute 'system_instruction' error by using the proper LlmRequest.append_instructions() API for skill injection. Key changes: - skill_callbacks.py: Use llm_request.append_instructions([skill_content]) instead of directly modifying llm_request.system_instruction (which doesn't exist) - README.md: Update documentation to reflect direct injection architecture - Add comprehensive ADK Skills Framework design document Technical details: - The append_instructions() method properly concatenates to config.system_instruction - This ensures skills are available in the FIRST LLM call by injecting directly into the llm_request in before_model_callback - Fixes timing issue where instruction provider runs before callback 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
Major revision (v2.0) positioning Skills as a core ADK plugin: - Frame Skills as the fourth plugin primitive alongside Tools, Callbacks, Extensions - Add "what agent KNOWS" vs "what agent can DO" distinction - Define Skill as self-contained unit of domain knowledge Key additions: - ADK Plugin Ecosystem diagram showing Skills' unique role - Skill vs Tool decision matrix with concrete examples - Multiple domain case studies: BigQuery, Kubernetes, Compliance, Internal Standards - Full API specification for SkillRegistry, SkillCallbacks, SkillExtension - Integration patterns: Toolset bundling, Multi-domain, Composition, Conditional - Detailed rollout phases (Q1-Q4 2026) - Future roadmap: Multi-modal, Executable, Federated, Learning skills Technical details: - Progressive disclosure (Level 1 metadata, Level 2 content) - Injection mechanism using llm_request.append_instructions() - Multi-turn handling with skill state management - Detection strategies comparison (Keyword, LLM, Hybrid) - Performance analysis with cost projections 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Remove author, version, and target audience metadata - Remove Q1-Q4 2026 timeline references from phase headings - Remove document footer with version info 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
Summary
load_skilltoolFiles Added
How It Works
SkillRegistryscansskills/directory for SKILL.md filesload_skill(name)for full docsTest Plan
adk run contributing/samples/bigquery_skills_demolocallyReferences
🤖 Generated with Claude Code