diff --git a/app/agent/tools/factory.py b/app/agent/tools/factory.py index c1b92a28..c48930c5 100644 --- a/app/agent/tools/factory.py +++ b/app/agent/tools/factory.py @@ -8,9 +8,9 @@ from app.agent.tools.impl.update_subscribe import UpdateSubscribeTool from app.agent.tools.impl.search_subscribe import SearchSubscribeTool from app.agent.tools.impl.get_recommendations import GetRecommendationsTool from app.agent.tools.impl.query_downloaders import QueryDownloadersTool -from app.agent.tools.impl.query_downloads import QueryDownloadsTool -from app.agent.tools.impl.query_media_library import QueryMediaLibraryTool -from app.agent.tools.impl.query_media_latest import QueryMediaLatestTool +from app.agent.tools.impl.query_download_tasks import QueryDownloadTasksTool +from app.agent.tools.impl.query_library_exists import QueryLibraryExistsTool +from app.agent.tools.impl.query_library_latest import QueryLibraryLatestTool from app.agent.tools.impl.query_sites import QuerySitesTool from app.agent.tools.impl.update_site import UpdateSiteTool from app.agent.tools.impl.query_site_userdata import QuerySiteUserdataTool @@ -36,7 +36,7 @@ from app.agent.tools.impl.query_workflows import QueryWorkflowsTool from app.agent.tools.impl.run_workflow import RunWorkflowTool from app.agent.tools.impl.update_site_cookie import UpdateSiteCookieTool from app.agent.tools.impl.delete_download import DeleteDownloadTool -from app.agent.tools.impl.query_directories import QueryDirectoriesTool +from app.agent.tools.impl.query_directory_settings import QueryDirectorySettingsTool from app.agent.tools.impl.list_directory import ListDirectoryTool from app.agent.tools.impl.query_transfer_history import QueryTransferHistoryTool from app.agent.tools.impl.transfer_file import TransferFileTool @@ -73,7 +73,7 @@ class MoviePilotToolFactory: QueryRuleGroupsTool, QuerySubscribeHistoryTool, DeleteSubscribeTool, - QueryDownloadsTool, + QueryDownloadTasksTool, DeleteDownloadTool, QueryDownloadersTool, QuerySitesTool, @@ -82,9 +82,9 @@ class MoviePilotToolFactory: TestSiteTool, UpdateSiteCookieTool, GetRecommendationsTool, - QueryMediaLibraryTool, - QueryMediaLatestTool, - QueryDirectoriesTool, + QueryLibraryExistsTool, + QueryLibraryLatestTool, + QueryDirectorySettingsTool, ListDirectoryTool, QueryTransferHistoryTool, TransferFileTool, diff --git a/app/agent/tools/impl/list_directory.py b/app/agent/tools/impl/list_directory.py index 00450c15..85f1a6fa 100644 --- a/app/agent/tools/impl/list_directory.py +++ b/app/agent/tools/impl/list_directory.py @@ -24,7 +24,7 @@ class ListDirectoryInput(BaseModel): class ListDirectoryTool(MoviePilotTool): name: str = "list_directory" - description: str = "List contents of a file system directory. Shows files and subdirectories with their names, types, sizes, and modification times. Returns up to 20 items and the total count if there are more items." + description: str = "List actual files and folders in a file system directory (NOT configuration). Shows files and subdirectories with their names, types, sizes, and modification times. Returns up to 20 items and the total count if there are more items. Use 'query_directories' to query directory configuration settings." args_schema: Type[BaseModel] = ListDirectoryInput def get_tool_message(self, **kwargs) -> Optional[str]: diff --git a/app/agent/tools/impl/query_directories.py b/app/agent/tools/impl/query_directory_settings.py similarity index 92% rename from app/agent/tools/impl/query_directories.py rename to app/agent/tools/impl/query_directory_settings.py index b9ecf994..2754a1bf 100644 --- a/app/agent/tools/impl/query_directories.py +++ b/app/agent/tools/impl/query_directory_settings.py @@ -10,7 +10,7 @@ from app.helper.directory import DirectoryHelper from app.log import logger -class QueryDirectoriesInput(BaseModel): +class QueryDirectorySettingsInput(BaseModel): """查询系统目录设置工具的输入参数模型""" explanation: str = Field(..., description="Clear explanation of why this tool is being used in the current context") directory_type: Optional[str] = Field("all", @@ -21,10 +21,10 @@ class QueryDirectoriesInput(BaseModel): description="Filter directories by name (partial match, optional)") -class QueryDirectoriesTool(MoviePilotTool): - name: str = "query_directories" - description: str = "Query system directory configuration and list all configured directories. Shows download directories, media library directories, storage settings, transfer modes, and other directory-related configurations." - args_schema: Type[BaseModel] = QueryDirectoriesInput +class QueryDirectorySettingsTool(MoviePilotTool): + name: str = "query_directory_settings" + description: str = "Query system directory configuration settings (NOT file listings). Returns configured directory paths, storage types, transfer modes, and other directory-related settings. Use 'list_directory' to list actual files and folders in a directory." + args_schema: Type[BaseModel] = QueryDirectorySettingsInput def get_tool_message(self, **kwargs) -> Optional[str]: """根据查询参数生成友好的提示消息""" diff --git a/app/agent/tools/impl/query_downloads.py b/app/agent/tools/impl/query_download_tasks.py similarity index 98% rename from app/agent/tools/impl/query_downloads.py rename to app/agent/tools/impl/query_download_tasks.py index 47f4e690..aeefcb5c 100644 --- a/app/agent/tools/impl/query_downloads.py +++ b/app/agent/tools/impl/query_download_tasks.py @@ -11,7 +11,7 @@ from app.db.downloadhistory_oper import DownloadHistoryOper from app.log import logger -class QueryDownloadsInput(BaseModel): +class QueryDownloadTasksInput(BaseModel): """查询下载工具的输入参数模型""" explanation: str = Field(..., description="Clear explanation of why this tool is being used in the current context") downloader: Optional[str] = Field(None, @@ -22,10 +22,10 @@ class QueryDownloadsInput(BaseModel): title: Optional[str] = Field(None, description="Query download tasks by title/name (optional, supports partial match, searches all tasks if provided)") -class QueryDownloadsTool(MoviePilotTool): - name: str = "query_downloads" +class QueryDownloadTasksTool(MoviePilotTool): + name: str = "query_download_tasks" description: str = "Query download status and list download tasks. Can query all active downloads, or search for specific tasks by hash or title. Shows download progress, completion status, and task details from configured downloaders." - args_schema: Type[BaseModel] = QueryDownloadsInput + args_schema: Type[BaseModel] = QueryDownloadTasksInput def get_tool_message(self, **kwargs) -> Optional[str]: """根据查询参数生成友好的提示消息""" diff --git a/app/agent/tools/impl/query_media_library.py b/app/agent/tools/impl/query_library_exists.py similarity index 95% rename from app/agent/tools/impl/query_media_library.py rename to app/agent/tools/impl/query_library_exists.py index 249bd2e1..104c9c43 100644 --- a/app/agent/tools/impl/query_media_library.py +++ b/app/agent/tools/impl/query_library_exists.py @@ -12,7 +12,7 @@ from app.log import logger from app.schemas.types import MediaType -class QueryMediaLibraryInput(BaseModel): +class QueryLibraryExistsInput(BaseModel): """查询媒体库工具的输入参数模型""" explanation: str = Field(..., description="Clear explanation of why this tool is being used in the current context") media_type: Optional[str] = Field("all", @@ -23,10 +23,10 @@ class QueryMediaLibraryInput(BaseModel): description="Release year of the media (optional, helps narrow down search results)") -class QueryMediaLibraryTool(MoviePilotTool): - name: str = "query_media_library" +class QueryLibraryExistsTool(MoviePilotTool): + name: str = "query_library_exists" description: str = "Check if a specific media resource already exists in the media library (Plex, Emby, Jellyfin). Use this tool to verify whether a movie or TV series has been successfully processed and added to the media server before performing operations like downloading or subscribing." - args_schema: Type[BaseModel] = QueryMediaLibraryInput + args_schema: Type[BaseModel] = QueryLibraryExistsInput def get_tool_message(self, **kwargs) -> Optional[str]: """根据查询参数生成友好的提示消息""" diff --git a/app/agent/tools/impl/query_media_latest.py b/app/agent/tools/impl/query_library_latest.py similarity index 95% rename from app/agent/tools/impl/query_media_latest.py rename to app/agent/tools/impl/query_library_latest.py index c0767a9b..08e657e9 100644 --- a/app/agent/tools/impl/query_media_latest.py +++ b/app/agent/tools/impl/query_library_latest.py @@ -11,17 +11,17 @@ from app.helper.service import ServiceConfigHelper from app.log import logger -class QueryMediaLatestInput(BaseModel): +class QueryLibraryLatestInput(BaseModel): """查询媒体服务器最近入库影片工具的输入参数模型""" explanation: str = Field(..., description="Clear explanation of why this tool is being used in the current context") server: Optional[str] = Field(None, description="Media server name (optional, if not specified queries all enabled media servers)") count: Optional[int] = Field(20, description="Number of items to return (default: 20)") -class QueryMediaLatestTool(MoviePilotTool): - name: str = "query_media_latest" +class QueryLibraryLatestTool(MoviePilotTool): + name: str = "query_library_latest" description: str = "Query the latest media items added to the media server (Plex, Emby, Jellyfin). Returns recently added movies and TV series with their titles, images, links, and other metadata." - args_schema: Type[BaseModel] = QueryMediaLatestInput + args_schema: Type[BaseModel] = QueryLibraryLatestInput def get_tool_message(self, **kwargs) -> Optional[str]: """根据查询参数生成友好的提示消息""" diff --git a/app/agent/tools/impl/recognize_media.py b/app/agent/tools/impl/recognize_media.py index bb352d7a..82dea564 100644 --- a/app/agent/tools/impl/recognize_media.py +++ b/app/agent/tools/impl/recognize_media.py @@ -22,7 +22,7 @@ class RecognizeMediaInput(BaseModel): class RecognizeMediaTool(MoviePilotTool): name: str = "recognize_media" - description: str = "Recognize media information from torrent titles or file paths. Supports two modes: 1) Recognize from torrent title and optional subtitle, 2) Recognize from file path. Returns detailed media information including title, year, type, TMDB ID, overview, and other metadata." + description: str = "Extract/identify media information from torrent titles or file paths (NOT database search). Supports two modes: 1) Extract from torrent title and optional subtitle, 2) Extract from file path. Returns detailed media information. Use 'search_media' to search TMDB database, or 'scrape_metadata' to generate metadata files for existing files." args_schema: Type[BaseModel] = RecognizeMediaInput def get_tool_message(self, **kwargs) -> Optional[str]: diff --git a/app/agent/tools/impl/scrape_metadata.py b/app/agent/tools/impl/scrape_metadata.py index 3d547c5a..6101e2d1 100644 --- a/app/agent/tools/impl/scrape_metadata.py +++ b/app/agent/tools/impl/scrape_metadata.py @@ -27,7 +27,7 @@ class ScrapeMetadataInput(BaseModel): class ScrapeMetadataTool(MoviePilotTool): name: str = "scrape_metadata" - description: str = "Scrape media metadata (NFO files, posters, backgrounds, etc.) for a file or directory. Automatically recognizes media information from the file path and generates metadata files. Supports both local and remote storage." + description: str = "Generate metadata files (NFO files, posters, backgrounds, etc.) for existing media files or directories. Automatically recognizes media information from the file path and creates metadata files. Supports both local and remote storage. Use 'search_media' to search TMDB database, or 'recognize_media' to extract info from torrent titles/file paths without generating files." args_schema: Type[BaseModel] = ScrapeMetadataInput def get_tool_message(self, **kwargs) -> Optional[str]: diff --git a/app/agent/tools/impl/search_media.py b/app/agent/tools/impl/search_media.py index 3e80db53..63ee3243 100644 --- a/app/agent/tools/impl/search_media.py +++ b/app/agent/tools/impl/search_media.py @@ -24,7 +24,7 @@ class SearchMediaInput(BaseModel): class SearchMediaTool(MoviePilotTool): name: str = "search_media" - description: str = "Search for media resources including movies, TV shows, anime, etc. Supports searching by title, year, type, and other criteria. Returns detailed media information from TMDB database." + description: str = "Search TMDB database for media resources (movies, TV shows, anime, etc.) by title, year, type, and other criteria. Returns detailed media information from TMDB. Use 'recognize_media' to extract info from torrent titles/file paths, or 'scrape_metadata' to generate metadata files." args_schema: Type[BaseModel] = SearchMediaInput def get_tool_message(self, **kwargs) -> Optional[str]: diff --git a/tool_analysis_report.md b/tool_analysis_report.md new file mode 100644 index 00000000..e6feacd8 --- /dev/null +++ b/tool_analysis_report.md @@ -0,0 +1,150 @@ +# 工具命名和功能混淆分析报告 + +## 一、潜在混淆点分析 + +### 1. 媒体相关工具(高风险混淆) + +#### 1.1 `search_media` vs `recognize_media` vs `scrape_metadata` +**当前状态:** +- `search_media`: 在TMDB数据库中搜索媒体(按标题、年份等条件搜索) +- `recognize_media`: 从种子标题或文件路径识别媒体信息 +- `scrape_metadata`: 为文件或目录刮削元数据(生成NFO文件等) + +**混淆风险:** ⚠️ **中等** +- 三个工具都涉及"媒体",但功能完全不同 +- `search_media` 是数据库搜索,`recognize_media` 是信息识别,`scrape_metadata` 是文件操作 +- 描述已区分,但命名可能让智能体混淆 + +**建议:** +- ✅ 描述已清晰区分,无需修改 +- 可考虑在描述中更明确强调差异: + - `search_media`: "Search for media in TMDB database by title/year/type" + - `recognize_media`: "Extract/identify media info from torrent titles or file paths" + - `scrape_metadata`: "Generate metadata files (NFO, posters) for existing media files" + +### 2. 目录相关工具(高风险混淆) + +#### 2.1 `query_directories` vs `list_directory` +**当前状态:** +- `query_directories`: 查询系统目录配置(配置信息,如下载目录、媒体库目录的设置) +- `list_directory`: 列出文件系统目录内容(实际文件和文件夹) + +**混淆风险:** ⚠️⚠️ **高** +- 两个工具都涉及"目录",但一个是配置查询,一个是文件列表 +- 命名相似,容易混淆 + +**建议:** +- 考虑重命名 `query_directories` 为 `query_directory_config` 或 `query_directory_settings` +- 或者在描述中更明确: + - `query_directories`: "Query directory **configuration settings** (download/library paths, storage types, etc.)" + - `list_directory`: "List **actual files and folders** in a file system directory" + +### 3. 媒体库查询工具(低风险) + +#### 3.1 `query_media_library` vs `query_media_latest` +**当前状态:** +- `query_media_library`: 检查特定媒体是否存在于媒体库中 +- `query_media_latest`: 查询媒体服务器最近入库的影片列表 + +**混淆风险:** ✅ **低** +- 命名清晰,功能区分明确 +- 描述已明确说明差异 + +### 4. 订阅相关工具(低风险) + +#### 4.1 `search_subscribe` vs `query_subscribes` +**当前状态:** +- `search_subscribe`: 搜索订阅的缺失剧集(执行搜索和下载操作) +- `query_subscribes`: 查询订阅状态和列表(只查询,不执行操作) + +**混淆风险:** ✅ **低** +- `search` vs `query` 已明确区分操作类型 +- 描述清晰 + +#### 4.2 多个订阅查询工具 +- `query_subscribes`: 查询所有订阅 +- `query_subscribe_history`: 查询订阅历史 +- `query_subscribe_shares`: 查询共享订阅 +- `query_popular_subscribes`: 查询热门订阅 + +**混淆风险:** ✅ **低** +- 命名清晰,通过后缀区分功能 + +### 5. 下载相关工具(低风险) + +#### 5.1 `query_downloads` vs `query_downloaders` +**当前状态:** +- `query_downloads`: 查询下载任务状态 +- `query_downloaders`: 查询下载器配置 + +**混淆风险:** ✅ **低** +- 命名清晰,单复数已区分 + +### 6. 调度器/工作流工具(低风险) + +#### 6.1 `query_schedulers` vs `run_scheduler` +**当前状态:** +- `query_schedulers`: 查询调度器任务列表 +- `run_scheduler`: 运行调度器任务 + +**混淆风险:** ✅ **低** +- `query` vs `run` 已明确区分 + +#### 6.2 `query_workflows` vs `run_workflow` +**当前状态:** +- `query_workflows`: 查询工作流列表 +- `run_workflow`: 运行工作流 + +**混淆风险:** ✅ **低** +- `query` vs `run` 已明确区分 + +## 二、命名规范分析 + +### 命名模式总结: +1. **Search类** (`search_*`): 执行搜索操作 + - `search_media`, `search_person`, `search_torrents`, `search_subscribe`, `search_web` + +2. **Query类** (`query_*`): 查询信息(只读) + - `query_*`: 各种查询工具 + +3. **Add/Update/Delete类**: 执行操作 + - `add_*`, `update_*`, `delete_*` + +4. **Run类**: 执行任务 + - `run_scheduler`, `run_workflow` + +### 命名一致性:✅ 良好 +- 命名模式统一,易于理解 +- 动词选择恰当(search/query/add/update/delete/run) + +## 三、建议优化 + +### 高优先级(建议修改) + +1. **`query_directories` 重命名或增强描述** + - 建议:在描述中明确强调是"配置查询"而非"文件列表" + - 或考虑重命名为 `query_directory_config` + +### 中优先级(可选优化) + +1. **`search_media`、`recognize_media`、`scrape_metadata` 的描述增强** + - 在描述开头明确说明数据源/操作类型 + - 例如:`search_media`: "Search TMDB database for media..." + - 例如:`recognize_media`: "Extract media info from torrent titles or file paths..." + - 例如:`scrape_metadata`: "Generate metadata files for existing media files..." + +### 低优先级(当前已足够清晰) + +- 其他工具命名和描述已足够清晰,无需修改 + +## 四、总结 + +**总体评价:** ✅ **良好** + +大部分工具的命名和描述已经足够清晰,只有少数几个地方存在潜在的混淆风险: + +1. **`query_directories` vs `list_directory`** - 需要更明确的区分 +2. **媒体相关三个工具** - 描述可以更明确强调差异 + +建议优先处理 `query_directories` 的描述或命名,其他工具当前状态已足够清晰。 +