-
Notifications
You must be signed in to change notification settings - Fork 53
feat: add builtin tool of llm firewall #271
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
Changes from 2 commits
4876ecd
55b3aec
bf29701
b01e7b4
90db908
6c9625b
f201b57
40d8d6d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,280 @@ | ||||||||||||||||||||||||
| # Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates. | ||||||||||||||||||||||||
| # | ||||||||||||||||||||||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||||||||||||||||||||||||
| # you may not use this file except in compliance with the License. | ||||||||||||||||||||||||
| # You may obtain a copy of the License at | ||||||||||||||||||||||||
| # | ||||||||||||||||||||||||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||||||||||||||||||||||||
| # | ||||||||||||||||||||||||
| # Unless required by applicable law or agreed to in writing, software | ||||||||||||||||||||||||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||||||||||||||||||||||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||||||||||||||||||||
| # See the License for the specific language governing permissions and | ||||||||||||||||||||||||
| # limitations under the License. | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| from typing import Optional, List | ||||||||||||||||||||||||
| from volcenginesdkllmshield import ClientV2, ModerateV2Request, MessageV2, ContentTypeV2 | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| from google.adk.plugins import BasePlugin | ||||||||||||||||||||||||
| from google.adk.agents.callback_context import CallbackContext | ||||||||||||||||||||||||
| from google.adk.models import LlmRequest, LlmResponse | ||||||||||||||||||||||||
| from google.genai import types | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| from veadk.config import getenv | ||||||||||||||||||||||||
| from veadk.utils.logger import get_logger | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| logger = get_logger(__name__) | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| class LLMFirewallPlugin(BasePlugin): | ||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||
| LLM Firewall Plugin for content moderation and security filtering. | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| This plugin integrates with Volcengine's LLM Firewall service to provide real-time | ||||||||||||||||||||||||
| content moderation for LLM requests. It analyzes user inputs for various risks | ||||||||||||||||||||||||
| including prompt injection, sensitive information, and policy violations before | ||||||||||||||||||||||||
| allowing requests to reach the language model. | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Examples: | ||||||||||||||||||||||||
| Basic usage with default settings: | ||||||||||||||||||||||||
| ```python | ||||||||||||||||||||||||
| governance = LLMFirewallPlugin() | ||||||||||||||||||||||||
| agent = Agent( | ||||||||||||||||||||||||
| before_model_callback=governance.before_model_callback | ||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| def __init__( | ||||||||||||||||||||||||
| self, max_history: int = 5, region: str = "cn-beijing", timeout: int = 50 | ||||||||||||||||||||||||
| ) -> None: | ||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||
| Initialize the LLM Firewall Plugin. | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Sets up the plugin with Volcengine LLM Firewall service configuration | ||||||||||||||||||||||||
| and initializes the moderation client. | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Args: | ||||||||||||||||||||||||
| max_history (int, optional): Maximum number of conversation turns | ||||||||||||||||||||||||
| to include in moderation context. Defaults to 5. | ||||||||||||||||||||||||
| region (str, optional): Volcengine service region. | ||||||||||||||||||||||||
| Defaults to "cn-beijing". | ||||||||||||||||||||||||
| timeout (int, optional): Request timeout in seconds. | ||||||||||||||||||||||||
| Defaults to 50. | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Raises: | ||||||||||||||||||||||||
| ValueError: If required environment variables are missing | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
| ValueError: If required environment variables are missing | |
| ValueError: If required environment variables are missing. This exception is raised by the | |
| `getenv` calls for `VOLCENGINE_ACCESS_KEY`, `VOLCENGINE_SECRET_KEY`, and | |
| `TOOL_LLM_FIREWALL_APP_ID`. |
Outdated
Copilot
AI
Oct 29, 2025
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.
Potential IndexError if parts list is empty. While line 152 checks if parts, it assumes parts[0] exists when checking hasattr(parts[0], \"text\"). If parts is a truthy but empty container, this will raise an IndexError. The condition should be if parts and len(parts) > 0 and hasattr(parts[0], \"text\") or simplified to check the length explicitly.
| if parts and hasattr(parts[0], "text"): | |
| if parts and len(parts) > 0 and hasattr(parts[0], "text"): |
Outdated
Copilot
AI
Oct 29, 2025
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 Exception catch at line 224 makes it difficult to diagnose and handle different failure scenarios. Consider catching more specific exceptions (e.g., network errors, timeout errors, API errors) and logging them with appropriate severity levels. This would also help distinguish between transient failures and configuration issues.
Outdated
Copilot
AI
Oct 29, 2025
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.
Potential exception if decision_type is None. The code calls int(decision_type) without checking if decision_type is None first. If decision_type is None (which can happen when getattr returns None), this will raise a TypeError. Consider adding a null check: if decision_type is not None and int(decision_type) == 2 and risk_info:
| if int(decision_type) == 2 and risk_info: | |
| if decision_type is not None and int(decision_type) == 2 and risk_info: |
Outdated
Copilot
AI
Oct 29, 2025
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 conversion of set to list at line 260 is unnecessary since the set is only used once for joining. You can directly join the set: reason_text = \", \".join(risk_reasons) if risk_reasons else \"security policy violation\". This simplifies the code and avoids the intermediate variable.
| risk_reasons_list = list(risk_reasons) | |
| # Generate blocking response | |
| reason_text = ( | |
| ", ".join(risk_reasons_list) | |
| if risk_reasons_list | |
| # Generate blocking response | |
| reason_text = ( | |
| ", ".join(risk_reasons) | |
| if risk_reasons |
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.
llm_firewall-》llm_shield,