{"id":394,"date":"2026-05-07T20:49:15","date_gmt":"2026-05-07T12:49:15","guid":{"rendered":"https:\/\/flycloud.io\/?p=394"},"modified":"2026-10-07T20:50:04","modified_gmt":"2026-10-07T12:50:04","slug":"%e4%bd%bf%e7%94%a8-rag-%e4%b8%8e-mcp-%e4%bc%98%e5%8c%96%e4%bc%81%e4%b8%9a-ai-agent-%e7%9a%84%e5%b7%a5%e5%85%b7%e8%b0%83%e7%94%a8%e6%95%88%e7%8e%87","status":"publish","type":"post","link":"https:\/\/flycloud.io\/en\/2026\/05\/07\/%e4%bd%bf%e7%94%a8-rag-%e4%b8%8e-mcp-%e4%bc%98%e5%8c%96%e4%bc%81%e4%b8%9a-ai-agent-%e7%9a%84%e5%b7%a5%e5%85%b7%e8%b0%83%e7%94%a8%e6%95%88%e7%8e%87\/","title":{"rendered":"\u4f7f\u7528 RAG \u4e0e MCP \u4f18\u5316\u4f01\u4e1a AI Agent \u7684\u5de5\u5177\u8c03\u7528\u6548\u7387"},"content":{"rendered":"<p><strong>\u80cc\u666f<\/strong><\/p>\n\n\n\n<p>\u5927\u8bed\u8a00\u6a21\u578b\uff08LLM\uff09\u5728\u81ea\u7136\u8bed\u8a00\u5904\u7406\u3001\u4efb\u52a1\u81ea\u52a8\u5316\u548c\u667a\u80fd\u51b3\u7b56\u7b49\u9886\u57df\u5c55\u73b0\u4e86\u975e\u51e1\u7684\u6f5c\u529b\u3002\u7136\u800c\uff0c\u5176\u6709\u9650\u7684\u4e0a\u4e0b\u6587\u7a97\u53e3\u5e38\u5e38\u6210\u4e3a\u590d\u6742\u4efb\u52a1\u7684\u74f6\u9888\u3002\u7279\u522b\u662f\u5728\u9700\u8981\u8c03\u7528\u5927\u91cf\u5916\u90e8\u5de5\u5177\u65f6\uff0c\u4f8b\u5982\u901a\u8fc7\u6a21\u578b\u4e0a\u4e0b\u6587\u534f\u8bae\uff08MCP\uff09\u7ba1\u7406\u7684\u5de5\u5177\uff0c\u5c06\u6240\u6709\u5de5\u5177\u63cf\u8ff0\u5d4c\u5165\u63d0\u793a\u8bcd\u4f1a\u5bfc\u81f4\u201c\u63d0\u793a\u8bcd\u81a8\u80c0\u201d\uff08Prompt Bloat\uff09\u3002\u8fd9\u4e0d\u4ec5\u6324\u5360\u4e86\u5b9d\u8d35\u7684\u4e0a\u4e0b\u6587\u7a7a\u95f4\uff0c\u9650\u5236\u6a21\u578b\u63a8\u7406\u80fd\u529b\uff0c\u8fd8\u589e\u52a0\u4e86\u5de5\u5177\u9009\u62e9\u7684\u51b3\u7b56\u590d\u6742\u6027\uff0c\u964d\u4f4e\u51c6\u786e\u6027\u548c\u6027\u80fd\u3002<\/p>\n\n\n\n<p>AWS Bedrock Knowledge Bases \u901a\u8fc7\u7ed3\u5408\u68c0\u7d22\u589e\u5f3a\u751f\u6210\uff08RAG\uff09\u548c\u6a21\u578b\u4e0a\u4e0b\u6587\u534f\u8bae\uff08MCP\uff09\uff0c\u63d0\u4f9b\u4e86\u4e00\u79cd\u4f18\u96c5\u7684\u89e3\u51b3\u65b9\u6848\u3002RAG-MCP \u67b6\u6784\u5c06\u5de5\u5177\u63cf\u8ff0\u5b58\u50a8\u5728\u5411\u91cf\u6570\u636e\u5e93\u4e2d\uff0c\u5229\u7528\u8bed\u4e49\u68c0\u7d22\u52a8\u6001\u9009\u62e9\u6700\u76f8\u5173\u7684\u5de5\u5177\uff0c\u4ece\u800c\u5927\u5e45\u51cf\u5c11\u63d0\u793a\u8bcd\u957f\u5ea6\uff0c\u63d0\u5347\u63a8\u7406\u6548\u7387\u548c\u5de5\u5177\u8c03\u7528\u7684\u7cbe\u51c6\u6027\u3002\u672c\u6587\u5c06\u6df1\u5165\u63a2\u8ba8 RAG-MCP \u7684\u67b6\u6784\u8bbe\u8ba1\u3001 Ascendancy \u5b9e\u73b0\u6b65\u9aa4\u3001\u6027\u80fd\u4f18\u52bf\u3001\u5b9e\u9645\u6848\u4f8b\u548c\u6545\u969c\u6392\u9664\u6307\u5357\uff0c\u4e3a\u5f00\u53d1\u8005\u548c\u67b6\u6784\u5e08\u63d0\u4f9b\u5168\u9762\u7684\u5b9e\u8df5\u53c2\u8003\u3002<\/p>\n\n\n\n<p>\u672c\u5b9e\u73b0\u57fa\u4e8e\u201dRAG-MCP\uff1a\u901a\u8fc7\u68c0\u7d22\u589e\u5f3a\u751f\u6210\u7f13\u89e3 LLM \u5de5\u5177\u9009\u62e9\u4e2d\u7684\u63d0\u793a\u81a8\u80c0\u201d\u8bba\u6587\u4e2d\u63cf\u8ff0\u7684\u65b9\u6cd5\uff0c\u8be5\u65b9\u6cd5\u89e3\u51b3\u4e86 LLMs \u8bbf\u95ee\u4f17\u591a\u5de5\u5177\u65f6\u9762\u4e34\u7684\u201d\u63d0\u793a\u81a8\u80c0\u201d\u6311\u6218\u3002<\/p>\n\n\n\n<p><strong>RAG \u4e0e MCP \u7684\u6838\u5fc3\u6982\u5ff5<\/strong><\/p>\n\n\n\n<p><strong>\u68c0\u7d22\u589e\u5f3a\u751f\u6210\uff08RAG\uff09<\/strong><\/p>\n\n\n\n<p>RAG \u662f\u4e00\u79cd\u901a\u8fc7\u68c0\u7d22\u5916\u90e8\u77e5\u8bc6\u5e93\u589e\u5f3a\u5927\u8bed\u8a00\u6a21\u578b\u751f\u6210\u80fd\u529b\u7684\u6846\u67b6\u3002\u5b83\u5c06\u7528\u6237\u67e5\u8be2\u4e0e\u5b58\u50a8\u5728\u5411\u91cf\u6570\u636e\u5e93\u4e2d\u7684\u77e5\u8bc6\u8fdb\u884c\u8bed\u4e49\u5339\u914d\uff0c\u63d0\u53d6\u6700\u76f8\u5173\u7684\u5185\u5bb9\u4f5c\u4e3a\u4e0a\u4e0b\u6587\uff0c\u4ece\u800c\u63d0\u5347\u6a21\u578b\u751f\u6210\u7ed3\u679c\u7684\u51c6\u786e\u6027\u548c\u76f8\u5173\u6027\u3002\u5728 Amazon Bedrock \u4e2d\uff0cKnowledge Bases\u63d0\u4f9b\u4e86\u5b8c\u5168\u6258\u7ba1\u7684 RAG \u529f\u80fd\uff0c\u652f\u6301\u9ad8\u6548\u7684\u5411\u91cf\u5b58\u50a8\u548c\u68c0\u7d22\u3002<\/p>\n\n\n\n<p><strong>\u6a21\u578b\u4e0a\u4e0b\u6587\u534f\u8bae\uff08MCP\uff09<\/strong><\/p>\n\n\n\n<p>MCP\uff08Model Context Protocol\uff09\u662f\u4e00\u79cd\u6807\u51c6\u5316\u534f\u8bae\uff0c\u7528\u4e8e\u7ba1\u7406\u5927\u8bed\u8a00\u6a21\u578b\u4e0e\u5916\u90e8\u5de5\u5177\u7684\u4ea4\u4e92\u3002\u5b83\u901a\u8fc7\u5b9a\u4e49\u5de5\u5177\u7684\u5143\u6570\u636e\uff08\u5982\u540d\u79f0\u3001\u63cf\u8ff0\u3001\u53c2\u6570\uff09\u5b9e\u73b0\u6a21\u578b\u4e0e\u5de5\u5177\u7684\u65e0\u7f1d\u96c6\u6210\u3002MCP Server \u8d1f\u8d23\u63d0\u4f9b\u5de5\u5177\u5217\u8868\u548c\u6267\u884c\u5de5\u5177\u8c03\u7528\uff0c\u800c MCP Client \u5219\u8d1f\u8d23\u4e0e\u670d\u52a1\u5668\u4ea4\u4e92\u5e76\u5c06\u5de5\u5177\u4fe1\u606f\u4f20\u9012\u7ed9\u6a21\u578b\u3002<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><img loading=\"lazy\" decoding=\"async\" width=\"554\" height=\"277\" src=\"blob:https:\/\/flycloud.io\/e200554a-00d8-47d4-8804-c89578b02456\"><a href=\"https:\/\/d2908q01vomqb2.cloudfront.net\/472b07b9fcf2c2451e8781e944bf5f77cd8457c8\/2025\/07\/01\/combining-rag-and-mcp-in-amazon-bedrock-to-effectively-alleviate-prompt-bloat1.png\"><\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><strong>\u4ec0\u4e48\u662f MCP Tools<\/strong><\/p>\n\n\n\n<p>MCP Server \u4e2d Tools \u662f\u5141\u8bb8 Servers \u66b4\u9732\u53ef\u6267\u884c\u51fd\u6570\uff0c\u8fd9\u4e9b\u51fd\u6570\u53ef\u4ee5\u88ab Clients \u8c03\u7528\uff0c\u5e76\u88ab LLMs \u7528\u4e8e\u6267\u884c\u64cd\u4f5c\u3002Tools \u7684\u5173\u952e\u65b9\u9762\u5305\u62ec\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Discovery\uff08\u53d1\u73b0\uff09\uff1aClients \u53ef\u4ee5\u901a\u8fc7 tools\/list endpoint \u5217\u51fa\u53ef\u7528\u7684 tools<\/li>\n\n\n\n<li>Invocation\uff08\u8c03\u7528\uff09\uff1aTools \u4f7f\u7528 tools\/call endpoint \u8c03\u7528\uff0c\u5176\u4e2d servers \u6267\u884c\u8bf7\u6c42\u7684\u64cd\u4f5c\u5e76\u8fd4\u56de\u7ed3\u679c<\/li>\n\n\n\n<li>Flexibility\uff08\u7075\u6d3b\u6027\uff09\uff1aTools \u7684\u8303\u56f4\u53ef\u4ee5\u4ece\u7b80\u5355\u7684\u8ba1\u7b97\u5230\u590d\u6742\u7684 API \u4ea4\u4e92<\/li>\n\n\n\n<li>Tool \u5b9a\u4e49\u7ed3\u6784\uff1a\u6bcf\u4e2a Tool \u90fd\u4f7f\u7528\u4ee5\u4e0b\u7ed3\u6784\u5b9a\u4e49\uff0c\u4ece\u7ed3\u6784\u5b9a\u4e49\u4e2d\u53ef\u4ee5\u770b\u5230\uff0cdescription \u548c inputSchema \u90fd\u53ef\u80fd\u5305\u542b\u5927\u91cf\u7684\u6587\u672c\u63d0\u4f9b\u7ed9\u5927\u8bed\u8a00\u6a21\u578b\uff0c\u4ee5\u65b9\u4fbf\u5927\u8bed\u8a00\u6a21\u578b\u66f4\u7cbe\u786e\u5730\u627e\u5230\u9700\u8981\u8c03\u7528\u7684 Tool \u548c\u4f20\u9012\u7684\u53c2\u6570<\/li>\n\n\n\n<li>{<\/li>\n\n\n\n<li>\u00a0 name: string;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ Tool \u7684\u552f\u4e00\u6807\u8bc6\u7b26<\/li>\n\n\n\n<li>\u00a0 description?: string;\u00a0 \/\/ \u4f9b\u4eba\u9605\u8bfb\u7684\u63cf\u8ff0<\/li>\n\n\n\n<li>\u00a0 inputSchema: {\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ Tool \u53c2\u6570\u7684 JSON Schema<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 type: &#8220;object&#8221;,<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 properties: { &#8230; }\u00a0 \/\/ Tool \u7279\u5b9a\u7684\u53c2\u6570<\/li>\n\n\n\n<li>\u00a0 }<\/li>\n<\/ul>\n\n\n\n<p>}<\/p>\n\n\n\n<p>\u4e0b\u9762\u6211\u4eec\u9009\u53d6\u4e00\u4e2a MCP Server \u5e76\u83b7\u53d6\u5230\u5b83\u7684 Tools \u8fdb\u884c\u67e5\u770b\u3002<\/p>\n\n\n\n<p><strong>Filesystem MCP Server<\/strong> \u662f\u4e00\u4e2a\u7528\u6765\u7ba1\u7406\u672c\u5730\u6587\u4ef6\u5939\u7684 MCP Server\uff0c\u6211\u4eec\u901a\u8fc7\u5217\u51fa\u6765\u5176\u4e2d\u7684 Tools \u53ef\u4ee5\u53d1\u73b0\uff0c\u4e00\u4e2a MCP Server \u4e2d\u7684 Tools \u5982\u679c\u4e0d\u8fdb\u884c\u9884\u7b5b\u9009\u800c\u76f4\u63a5\u53d1\u9001\u7ed9\u5927\u8bed\u8a00\u6a21\u578b\u9700\u8981\u8017\u8d39\u5927\u91cf\u7684 Token\uff0c\u5982\u679c Tool Use \u8fc7\u7a0b\u51fa\u73b0\u591a\u6b21\uff0c\u90a3\u4e48\u6bcf\u6b21\u7684 Token \u82b1\u8d39\u4f1a\u6210\u500d\u6570\u589e\u957f\u3002<\/p>\n\n\n\n<p>=== All Available Tools (11 tools) ===<\/p>\n\n\n\n<p>1. ? get_file_info<\/p>\n\n\n\n<p>&nbsp;&nbsp; Description: Retrieve detailed metadata about a file or directory. Returns comprehensive information including size, creation time, last modified time, permissions, and type. This tool is perfect for understanding file characteristics without reading the actual content. Only works within allowed directories.<\/p>\n\n\n\n<p>&nbsp;&nbsp; Parameters: path<\/p>\n\n\n\n<p>2. ? write_file<\/p>\n\n\n\n<p>&nbsp;&nbsp; Description: Create a new file or completely overwrite an existing file with new content. Use with caution as it will overwrite existing files without warning. Handles text content with proper encoding. Only works within allowed directories.<\/p>\n\n\n\n<p>&nbsp;&nbsp; Parameters: path, content<\/p>\n\n\n\n<p>3. ? move_file<\/p>\n\n\n\n<p>&nbsp;&nbsp; Description: Move or rename files and directories. Can move files between directories and rename them in a single operation. If the destination exists, the operation will fail. Works across different directories and can be used for simple renaming within the same directory. Both source and destination must be within allowed directories.<\/p>\n\n\n\n<p>&nbsp;&nbsp; Parameters: source, destination<\/p>\n\n\n\n<p>4. ? edit_file<\/p>\n\n\n\n<p>&nbsp;&nbsp; Description: Make line-based edits to a text file. Each edit replaces exact line sequences with new content. Returns a git-style diff showing the changes made. Only works within allowed directories.<\/p>\n\n\n\n<p>&nbsp;&nbsp; Parameters: path, edits, dryRun<\/p>\n\n\n\n<p>5. ? read_multiple_files<\/p>\n\n\n\n<p>&nbsp;&nbsp; Description: Read the contents of multiple files simultaneously. This is more efficient than reading files one by one when you need to analyze or compare multiple files. Each file&#8217;s content is returned with its path as a reference. Failed reads for individual files won&#8217;t stop the entire operation. Only works within allowed directories.<\/p>\n\n\n\n<p>&nbsp;&nbsp; Parameters: paths<\/p>\n\n\n\n<p>6. ? create_directory<\/p>\n\n\n\n<p>&nbsp;&nbsp; Description: Create a new directory or ensure a directory exists. Can create multiple nested directories in one operation. If the directory already exists, this operation will succeed silently. Perfect for setting up directory structures for projects or ensuring required paths exist. Only works within allowed directories.<\/p>\n\n\n\n<p>&nbsp;&nbsp; Parameters: path<\/p>\n\n\n\n<p>7. ? read_file<\/p>\n\n\n\n<p>&nbsp;&nbsp; Description: Read the complete contents of a file from the file system. Handles various text encodings and provides detailed error messages if the file cannot be read. Use this tool when you need to examine the contents of a single file. Only works within allowed directories.<\/p>\n\n\n\n<p>&nbsp;&nbsp; Parameters: path<\/p>\n\n\n\n<p>8. ? directory_tree<\/p>\n\n\n\n<p>&nbsp;&nbsp; Description: Get a recursive tree view of files and directories as a JSON structure. Each entry includes &#8216;name&#8217;, &#8216;type&#8217; (file\/directory), and &#8216;children&#8217; for directories. Files have no children array, while directories always have a children array (which may be empty). The output is formatted with 2-space indentation for readability. Only works within allowed directories.<\/p>\n\n\n\n<p>&nbsp;&nbsp; Parameters: path<\/p>\n\n\n\n<p>9. ? list_allowed_directories<\/p>\n\n\n\n<p>&nbsp;&nbsp; Description: Returns the list of directories that this server is allowed to access. Use this to understand which directories are available before trying to access files.<\/p>\n\n\n\n<p>10. ? search_files<\/p>\n\n\n\n<p>&nbsp;&nbsp; Description: Recursively search for files and directories matching a pattern. Searches through all subdirectories from the starting path. The search is case-insensitive and matches partial names. Returns full paths to all matching items. Great for finding files when you don&#8217;t know their exact location. Only searches within allowed directories.<\/p>\n\n\n\n<p>&nbsp;&nbsp; Parameters: path, pattern, excludePatterns<\/p>\n\n\n\n<p>11. ? list_directory<\/p>\n\n\n\n<p>&nbsp;&nbsp; Description: Get a detailed listing of all files and directories in a specified path. Results clearly distinguish between files and directories with [FILE] and [DIR] prefixes. This tool is essential for understanding directory structure and finding specific files within a directory. Only works within allowed directories.<\/p>\n\n\n\n<p>&nbsp;&nbsp; Parameters: path<\/p>\n\n\n\n<p>Total 11 tools<\/p>\n\n\n\n<p><strong>RAG-MCP \u7684\u534f\u540c\u4f5c\u7528<\/strong><\/p>\n\n\n\n<p>\u901a\u8fc7\u7ed3\u5408 RAG \u548c MCP\uff0c\u6211\u4eec\u53ef\u4ee5\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u52a8\u6001\u5de5\u5177\u68c0\u7d22\uff1a\u5c06 MCP \u5de5\u5177\u63cf\u8ff0\u5b58\u50a8\u5728\u5411\u91cf\u6570\u636e\u5e93\u4e2d\uff0c\u4ec5\u68c0\u7d22\u4e0e\u7528\u6237\u67e5\u8be2\u8bed\u4e49\u6700\u76f8\u5173\u7684\u5de5\u5177\uff0c\u51cf\u5c11\u63d0\u793a\u8bcd\u4e2d\u7684\u5197\u4f59\u4fe1\u606f\u3002<\/li>\n\n\n\n<li>\u4e0a\u4e0b\u6587\u589e\u5f3a\uff1a\u901a\u8fc7\u68c0\u7d22\u5230\u7684\u5de5\u5177\u63cf\u8ff0\u6784\u5efa\u589e\u5f3a\u63d0\u793a\uff08Augmented Prompt\uff09\uff0c\u4e3a\u6a21\u578b\u63d0\u4f9b\u7cbe\u51c6\u7684\u4e0a\u4e0b\u6587\uff0c\u63d0\u5347\u63a8\u7406\u80fd\u529b\u3002<\/li>\n\n\n\n<li>\u53ef\u6269\u5c55\u6027\uff1a\u652f\u6301\u5927\u89c4\u6a21\u5de5\u5177\u96c6\uff0c\u65e0\u9700\u9891\u7e41\u4fee\u6539\u63d0\u793a\u8bcd\u7ed3\u6784\uff0c\u9002\u5408\u52a8\u6001\u66f4\u65b0\u7684\u5de5\u5177\u73af\u5883\u3002<\/li>\n<\/ul>\n\n\n\n<p><strong>\u63d0\u793a\u8bcd\u81a8\u80c0\u7684\u6311\u6218<\/strong><\/p>\n\n\n\n<p>\u63d0\u793a\u8bcd\u81a8\u80c0\u662f\u6307\u5728\u63d0\u793a\u8bcd\u4e2d\u5d4c\u5165\u8fc7\u591a\u4fe1\u606f\uff0c\u5bfc\u81f4\u4e0a\u4e0b\u6587\u7a97\u53e3\u88ab\u8fc7\u5ea6\u5360\u7528\u3002\u4e3b\u8981\u6311\u6218\u5305\u62ec\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u4e0a\u4e0b\u6587\u7a97\u53e3\u9650\u5236\uff1a\u5927\u8bed\u8a00\u6a21\u578b\u7684\u4e0a\u4e0b\u6587\u7a97\u53e3\u901a\u5e38\u5728\u51e0\u5343\u5230\u51e0\u5341\u4e07 Token \u4e4b\u95f4\u3002\u5d4c\u5165\u6240\u6709\u5de5\u5177\u63cf\u8ff0\u4f1a\u663e\u8457\u51cf\u5c11\u6a21\u578b\u5904\u7406\u4efb\u52a1\u7684\u53ef\u7528\u7a7a\u95f4\u3002<\/li>\n\n\n\n<li>\u51b3\u7b56\u5f00\u9500\uff1a\u5f53\u5de5\u5177\u6570\u91cf\u8f83\u591a\u65f6\uff0c\u6a21\u578b\u9700\u8981\u4ece\u5927\u91cf\u9009\u9879\u4e2d\u9009\u62e9\u5408\u9002\u7684\u5de5\u5177\uff0c\u589e\u52a0\u8ba1\u7b97\u590d\u6742\u5ea6\u548c\u9519\u8bef\u7387\u3002<\/li>\n\n\n\n<li>\u6027\u80fd\u4e0b\u964d\uff1a\u8fc7\u957f\u7684\u63d0\u793a\u8bcd\u53ef\u80fd\u5bfc\u81f4\u63a8\u7406\u901f\u5ea6\u53d8\u6162\uff0c\u751a\u81f3\u56e0\u4e0a\u4e0b\u6587\u6ea2\u51fa\u800c\u65e0\u6cd5\u5904\u7406\u590d\u6742\u4efb\u52a1\u3002<\/li>\n\n\n\n<li>\u7ef4\u62a4\u590d\u6742\u6027\uff1a\u5de5\u5177\u96c6\u9891\u7e41\u66f4\u65b0\u65f6\uff0c\u9700\u8981\u624b\u52a8\u8c03\u6574\u63d0\u793a\u8bcd\uff0c\u589e\u52a0\u4e86\u5f00\u53d1\u548c\u7ef4\u62a4\u6210\u672c\u3002<\/li>\n<\/ul>\n\n\n\n<p>RAG-MCP \u901a\u8fc7\u52a8\u6001\u68c0\u7d22\u548c\u4e0a\u4e0b\u6587\u589e\u5f3a\u89e3\u51b3\u4e86\u8fd9\u4e9b\u95ee\u9898\uff0c\u4f7f\u5f97\u6a21\u578b\u80fd\u591f\u4e13\u6ce8\u4e8e\u63a8\u7406\u800c\u975e\u5de5\u5177\u9009\u62e9\u3002<\/p>\n\n\n\n<p>\u4e0b\u9762\u7684\u56fe\u7247\u8be6\u7ec6\u63cf\u8ff0\u4e86 RAG-MCP \u5728\u4f7f\u7528\u8fc7\u7a0b\u4e2d\u548c\u4f20\u7edf\u7684 MCP \u4f7f\u7528\u7684\u533a\u522b\uff1a<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><img loading=\"lazy\" decoding=\"async\" width=\"554\" height=\"319\" src=\"blob:https:\/\/flycloud.io\/8205c298-bf6f-46a7-bf1e-969a8dcbd607\"><a href=\"https:\/\/d2908q01vomqb2.cloudfront.net\/472b07b9fcf2c2451e8781e944bf5f77cd8457c8\/2025\/06\/27\/RAG_MCP.jpg\"><\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>\u7ed3\u5408 Amazon Bedrock Knowledge Bases\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06\u4e0a\u9762\u7684\u67b6\u6784\u8bbe\u8ba1\u5177\u8c61\u5316\u6210\u4e0b\u9762\u7684\u53ef\u6267\u884c\u6d41\u7a0b\uff1a<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><img loading=\"lazy\" decoding=\"async\" width=\"554\" height=\"197\" src=\"blob:https:\/\/flycloud.io\/3e283b0c-dab7-4ad2-95fe-574514182a8d\"><a href=\"https:\/\/d2908q01vomqb2.cloudfront.net\/472b07b9fcf2c2451e8781e944bf5f77cd8457c8\/2025\/07\/01\/combining-rag-and-mcp-in-amazon-bedrock-to-effectively-alleviate-prompt-bloat3.png\"><\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>\u6839\u636e\u4e0a\u9762\u7684\u6d41\u7a0b\uff0c\u603b\u7ed3\u51fa\u5982\u4e0b\u7684\u6b65\u9aa4\uff1a<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li>MCP client \u8bfb\u53d6\u6240\u6709\u5df2\u542f\u7528\u7684 MCP Server \u7684 tools\uff0c\u5e76\u5c06 tools \u4fdd\u5b58\u6210 jsonl\uff08JSON Lines\uff09\u6587\u4ef6<\/li>\n\n\n\n<li>\u5c06\u751f\u6210\u7684 jsonl \u6587\u4ef6\u4e0a\u4f20\u5230 Knowledge Bases \u7684 Data Source \u4e2d<\/li>\n\n\n\n<li>\u4f7f\u7528\u81ea\u5b9a\u4e49\u7684 Chunking \u65b9\u5f0f\uff0c\u5c06 jsonl \u6587\u4ef6\u5207\u5206\u6210 chunk \u6587\u4ef6<\/li>\n\n\n\n<li>\u63d0\u53d6\u7684\u6570\u636e\u88ab\u5206\u5272\u6210\u81ea\u5b9a\u4e49\u5757\uff08Custom Chunks\uff09\uff0c\u4ee5\u4fbf\u4e8e\u540e\u7eed\u7684\u5d4c\u5165\uff08Embedding\uff09\u5904\u7406<\/li>\n\n\n\n<li>\u6570\u636e\u5757\u901a\u8fc7\u5d4c\u5165\u6a21\u578b\uff08Embeddings Model\uff09\u8f6c\u6362\u4e3a\u5411\u91cf\u8868\u793a\uff08Embeddings\uff09\u3002\u8fd9\u4e00\u8fc7\u7a0b\u5c06\u6587\u672c\u6216\u5176\u4ed6\u6570\u636e\u6620\u5c04\u4e3a\u9ad8\u7ef4\u5411\u91cf\uff0c\u4e3a\u540e\u7eed\u7684\u8bed\u4e49\u641c\u7d22\u6216\u5339\u914d\u5960\u5b9a\u57fa\u7840<\/li>\n\n\n\n<li>\u7528\u6237\u53d1\u8d77 Tools \u68c0\u7d22\uff0c\u68c0\u7d22\u4fe1\u606f\u4f1a\u8f93\u5165\u7ed9\u5d4c\u5165\u6a21\u578b\uff08Embeddings Model\uff09<\/li>\n\n\n\n<li>\u5d4c\u5165\u6a21\u578b\uff08Embeddings Model\uff09\u5c06\u68c0\u7d22\u5185\u5bb9\u8f6c\u6362\u6210\u9ad8\u7ef4\u5411\u91cf\u8868\u793a<\/li>\n\n\n\n<li>\u7cfb\u7edf\u6839\u636e\u7528\u6237\u8f93\u5165\u7684\u8bed\u4e49\u7279\u5f81\uff0c\u4ece\u5411\u91cf\u6570\u636e\u5e93\u4e2d\u68c0\u7d22\u51fa\u4e0e\u8f93\u5165\u6700\u76f8\u4f3c\u7684\u5d4c\u5165\u5411\u91cf\u3002\u8fd9\u4e00\u8fc7\u7a0b\u901a\u8fc7\u5411\u91cf\u76f8\u4f3c\u6027\u8ba1\u7b97\u5b8c\u6210\uff0c\u786e\u4fdd\u68c0\u7d22\u5230\u7684\u5185\u5bb9\u5728\u8bed\u4e49\u4e0a\u4e0e\u7528\u6237\u9700\u6c42\u9ad8\u5ea6\u76f8\u5173<\/li>\n\n\n\n<li>\u6839\u636e\u68c0\u7d22\u5230\u7684\u5d4c\u5165\u5411\u91cf\uff0c\u7cfb\u7edf\u6784\u5efa\u4e0a\u4e0b\u6587\uff08Context\uff09\uff0c\u4e3a\u540e\u7eed\u7684\u63d0\u793a\uff08Prompt\uff09\u751f\u6210\u63d0\u4f9b\u80cc\u666f\u4fe1\u606f<\/li>\n\n\n\n<li>\u7cfb\u7edf\u57fa\u4e8e\u4e0a\u4e0b\u6587\u5bf9\u63d0\u793a\u8fdb\u884c\u589e\u5f3a\uff08Augmented Prompt\uff09\uff0c\u4e5f\u5c31\u662f\u5c06\u68c0\u7d22\u5230\u7684 Tools \u5f53\u505a\u63d0\u793a\u8bcd\u53d1\u9001\u7ed9\u5927\u8bed\u8a00\u6a21\u578b\uff0c\u4ee5\u63d0\u9ad8\u5927\u8bed\u8a00\u6a21\u578b\u7684\u7406\u89e3\u548c\u751f\u6210\u80fd\u529b<\/li>\n\n\n\n<li>\u589e\u5f3a\u540e\u7684\u63d0\u793a\u8f93\u5165\u5230\u5927\u8bed\u8a00\u6a21\u578b\u4e2d\uff0c\u8be5\u6a21\u578b\u6839\u636e\u8f93\u5165\u9009\u62e9\u662f\u5426\u6709\u80fd\u591f\u8c03\u7528\u7684 Tool<\/li>\n\n\n\n<li>\u5927\u8bed\u8a00\u6a21\u578b\u751f\u6210\u7684\u54cd\u5e94\u8fd4\u56de\u7ed9\u5ba2\u6237\u7aef\u5de5\u5177<\/li>\n<\/ol>\n\n\n\n<p>\u5728\u4e0a\u9762\u7684\u6b65\u9aa4\u4e2d\uff0c6-12 \u4f1a\u6839\u636e\u6267\u884c\u7ed3\u679c\u9009\u62e9\u662f\u5426\u8c03\u7528\u591a\u6b21\u3002<\/p>\n\n\n\n<p><strong>\u9010\u6b65\u6307\u5357\uff1aMCP Server Tools RAG \u68c0\u7d22<\/strong><\/p>\n\n\n\n<p>\u4ee5\u4e0b\u662f\u5728 Amazon Bedrock \u4e2d\u5b9e\u73b0 RAG-MCP \u5de5\u5177\u68c0\u7d22\u529f\u80fd\u7684\u5b8c\u6574\u6d41\u7a0b\uff0c\u6db5\u76d6\u73af\u5883\u51c6\u5907\u3001\u6570\u636e\u5904\u7406\u3001\u914d\u7f6e\u548c\u68c0\u7d22\u4f18\u5316\u3002<\/p>\n\n\n\n<p><strong>\u524d\u63d0\u6761\u4ef6<\/strong><\/p>\n\n\n\n<p>1. \u6280\u672f\u80cc\u666f\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u719f\u6089 MCP \u534f\u8bae\u53ca\u5176\u67b6\u6784\uff0c\u53c2\u8003 Model Context Protocol \u6587\u6863\u3002<\/li>\n\n\n\n<li>\u4e86\u89e3 AWS Lambda\u3001S3 \u548c Bedrock Knowledge Bases \u7684\u57fa\u672c\u64cd\u4f5c\u3002<\/li>\n\n\n\n<li>\u719f\u6089 AWS \u7ba1\u7406\u63a7\u5236\u53f0\u548cAWS CLI\u3002<\/li>\n<\/ul>\n\n\n\n<p>2. \u73af\u5883\u51c6\u5907\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u914d\u7f6e AWS \u8d26\u6237\u5e76\u6388\u4e88 Bedrock\u3001S3\u3001Lambda \u548c OpenSearch Serverless \u7684\u6743\u9650\u3002<\/li>\n\n\n\n<li>\u5b89\u88c5 Python 3.8+\u53ca\u76f8\u5173\u5e93\uff08\u5982 boto3\u3001mcp\uff09\u3002<\/li>\n\n\n\n<li>\u914d\u7f6e MCP Server \u5e76\u786e\u4fdd\u53ef\u8bbf\u95ee\u3002<\/li>\n<\/ul>\n\n\n\n<p>3. \u5de5\u5177\u4e0e\u4f9d\u8d56\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>AWS SDK for Python\uff08boto3\uff09\uff1a\u7528\u4e8e\u4e0e AWS \u670d\u52a1\u4ea4\u4e92\u3002<\/li>\n\n\n\n<li>MCP Python SDK\uff1a\u7528\u4e8e\u4e0e MCP Server \u901a\u4fe1\u3002<\/li>\n\n\n\n<li>Logging \u5e93\uff1a\u7528\u4e8e\u8bb0\u5f55\u64cd\u4f5c\u65e5\u5fd7\u3002<\/li>\n<\/ul>\n\n\n\n<p><strong>1. \u83b7\u53d6 MCP \u5de5\u5177\u5217\u8868<\/strong><\/p>\n\n\n\n<p>\u4f7f\u7528 MCP Client \u4ece MCP Server \u83b7\u53d6\u5de5\u5177\u5217\u8868\uff0c\u5e76\u5c06\u5176\u8f6c\u6362\u4e3a JSON Lines\uff08JSONL\uff09\u683c\u5f0f\u5b58\u50a8\u81f3\u672c\u5730\u4e34\u65f6\u6587\u4ef6\u3002JSONL \u683c\u5f0f\u6bcf\u884c\u5305\u542b\u4e00\u4e2a\u72ec\u7acb\u7684 JSON \u5bf9\u8c61\uff0c\u9002\u5408\u5927\u89c4\u6a21\u6570\u636e\u5904\u7406\u3002\u786e\u4fdd\u5de5\u5177\u63cf\u8ff0\u5305\u542b\u5173\u952e\u5143\u6570\u636e\uff0c\u5982\u5de5\u5177\u540d\u79f0\u3001\u529f\u80fd\u3001\u53c2\u6570\u548c\u8c03\u7528\u65b9\u5f0f\u3002<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u6ce8\u610f\u4e8b\u9879\uff1a\u9a8c\u8bc1 MCP Server \u7684\u8fde\u63a5\u72b6\u6001\uff0c\u786e\u4fdd\u8fd4\u56de\u7684\u5de5\u5177\u5217\u8868\u5b8c\u6574\u4e14\u7b26\u5408 JSON Schema \u89c4\u8303\u3002<\/li>\n\n\n\n<li>\u5efa\u8bae\uff1a\u8bb0\u5f55\u5de5\u5177\u83b7\u53d6\u65e5\u5fd7\uff0c\u4fbf\u4e8e\u8c03\u8bd5\u548c\u76d1\u63a7\u3002<\/li>\n\n\n\n<li>&#8220;&#8221;&#8221;<\/li>\n\n\n\n<li>MCP (Model Context Protocol) client for tool integration.<\/li>\n\n\n\n<li>&#8220;&#8221;&#8221;<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>import logging<\/li>\n\n\n\n<li>from typing import Dict, List, Any, Optional<\/li>\n\n\n\n<li>from mcp import ClientSession, StdioServerParameters<\/li>\n\n\n\n<li>from mcp.client.stdio import stdio_client<\/li>\n\n\n\n<li>from mcp.types import TextContent<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>from .config import MCPConfig<\/li>\n\n\n\n<li>from .exceptions import MCPToolError<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>logger = logging.getLogger(__name__)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>class MCPClient:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 &#8220;&#8221;&#8221;MCP client for handling tool interactions.&#8221;&#8221;&#8221;<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 def __init__(self, config: MCPConfig):<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;&#8221;&#8221;Initialize MCP client with configuration.&#8221;&#8221;&#8221;<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 self.config = config<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 self._session = None<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 self._tools = None<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 async def __aenter__(self):<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;&#8221;&#8221;Async context manager entry.&#8221;&#8221;&#8221;<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 await self.connect()<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return self<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 async def __aexit__(self, exc_type, exc_val, exc_tb):<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;&#8221;&#8221;Async context manager exit.&#8221;&#8221;&#8221;<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 await self.disconnect()<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 async def connect(self):<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;&#8221;&#8221;Connect to MCP server.&#8221;&#8221;&#8221;<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 try:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 server_params = StdioServerParameters(<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 command=self.config.command,<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 args=self.config.args,<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 env=self.config.env<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 )<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 self._stdio_context = stdio_client(server_params)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 self._read, self._write = await self._stdio_context.__aenter__()<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 self._session_context = ClientSession(self._read, self._write)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 self._session = await self._session_context.__aenter__()<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Initialize the connection<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 await self._session.initialize()<\/li>\n\n\n\n<li>logger.info(&#8220;Successfully connected to MCP server&#8221;)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 except Exception as e:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 logger.error(f&#8221;Failed to connect to MCP server: {str(e)}&#8221;)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 raise MCPToolError(f&#8221;Failed to connect to MCP server: {str(e)}&#8221;)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 async def disconnect(self):<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;&#8221;&#8221;Disconnect from MCP server.&#8221;&#8221;&#8221;<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 try:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Close session first<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if hasattr(self, &#8216;_session_context&#8217;) and self._session_context:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 try:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 await self._session_context.__aexit__(None, None, None)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 except Exception as session_error:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 logger.warning(f&#8221;Error closing session: {str(session_error)}&#8221;)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 finally:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 self._session_context = None<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 self._session = None<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Then close stdio connection<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if hasattr(self, &#8216;_stdio_context&#8217;) and self._stdio_context:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 try:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Use asyncio.wait_for to add timeout protection<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 import asyncio<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 await asyncio.wait_for(<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 self._stdio_context.__aexit__(None, None, None),<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 timeout=5.0\u00a0 # 5 second timeout<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 )<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 except asyncio.TimeoutError:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 logger.warning(&#8220;MCP stdio disconnect timed out&#8221;)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 except Exception as stdio_error:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 logger.warning(f&#8221;Error closing stdio: {str(stdio_error)}&#8221;)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 finally:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 self._stdio_context = None<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>logger.info(&#8220;Disconnected from MCP server&#8221;)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 except Exception as e:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 logger.warning(f&#8221;Error during MCP disconnect: {str(e)}&#8221;)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 async def list_tools(self):<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;&#8221;&#8221;List available tools from MCP server.&#8221;&#8221;&#8221;<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if not self._session:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 raise MCPToolError(&#8220;MCP session not initialized&#8221;)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 try:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 tools_response = await self._session.list_tools()<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 self._tools = tools_response.toolslogger.info(f&#8221;Retrieved {len(self._tools)} tools from MCP server&#8221;)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return tools_response<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 except Exception as e:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 logger.error(f&#8221;Failed to list MCP tools: {str(e)}&#8221;)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 raise MCPToolError(f&#8221;Failed to list MCP tools: {str(e)}&#8221;)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 async def call_tool(self, tool_name: str, arguments: Dict[str, Any]):<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;&#8221;&#8221;<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Call a specific tool with given arguments.<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Args:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 tool_name: Name of the tool to call<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 arguments: Arguments to pass to the tool<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Returns:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Tool execution result<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Raises:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 MCPToolError: If tool call fails<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;&#8221;&#8221;<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if not self._session:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 raise MCPToolError(&#8220;MCP session not initialized&#8221;)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 try:<\/li>\n\n\n\n<li>logger.info(f&#8221;Calling tool {tool_name} with arguments: {arguments}&#8221;)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 result = await self._session.call_tool(tool_name, arguments=arguments)<\/li>\n\n\n\n<li>logger.info(f&#8221;Tool {tool_name} result: {result}&#8221;)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if result.isError:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 error_msg = f&#8221;Tool {tool_name} execution failed&#8221;<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 logger.error(error_msg)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 raise MCPToolError(error_msg)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return result<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 except Exception as e:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0logger.error(f&#8221;Failed to call tool {tool_name}: {str(e)}&#8221;)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 raise MCPToolError(f&#8221;Failed to call tool {tool_name}: {str(e)}&#8221;)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 def convert_tools_to_bedrock_format(self, tools: List[Any]) -> Dict[str, Any]:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;&#8221;&#8221;<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Convert MCP tools to Bedrock toolSpec format.<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Args:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 tools: List of MCP tools<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Returns:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Bedrock-compatible tool configuration<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Raises:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 MCPToolError: If conversion fails<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;&#8221;&#8221;<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 try:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0bedrock_tools = []<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 for tool in tools:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 tool_spec = {<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;toolSpec&#8221;: {<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;name&#8221;:tool.name,<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;description&#8221;: tool.description,<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;inputSchema&#8221;: {<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;json&#8221;: tool.inputSchema<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 bedrock_tools.append(tool_spec)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return {&#8220;tools&#8221;: bedrock_tools}<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 except Exception as e:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 logger.error(f&#8221;Failed to convert tools to Bedrock format: {str(e)}&#8221;)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 raise MCPToolError(f&#8221;Failed to convert tools to Bedrock format: {str(e)}&#8221;)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 def extract_text_content(self, result) -> Optional[str]:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;&#8221;&#8221;<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Extract text content from MCP tool result.<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Args:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 result: MCP tool result<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Returns:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Extracted text content or None<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;&#8221;&#8221;<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 for content in result.content:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if isinstance(content, TextContent):<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return content.text<\/li>\n<\/ul>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return None<\/p>\n\n\n\n<p><strong>2. \u4e0a\u4f20\u5de5\u5177\u6570\u636e\u81f3 Amazon S3<\/strong><\/p>\n\n\n\n<p>\u5c06 jsonl \u6587\u4ef6\u4e0a\u4f20\u81f3 Amazon S3\uff0c\u4f5c\u4e3a Amazon Bedrock Knowledge Bases \u7684\u6570\u636e\u6e90\u3002\u914d\u7f6e S3 \u5b58\u50a8\u6876\u4ee5\u652f\u6301\u52a0\u5bc6\uff08\u4f7f\u7528 AWS Key Management Service\uff0cKMS\uff09\u548c\u6700\u5c0f\u6743\u9650\u8bbf\u95ee\uff08\u901a\u8fc7 IAM \u7b56\u7565\uff09\u3002\u4e0a\u4f20\u5b8c\u6210\u540e\uff0c\u542f\u52a8 Knowledge Bases \u7684\u6570\u636e\u63d0\u53d6\u4efb\u52a1\uff0c\u5c06\u5de5\u5177\u6570\u636e\u5bfc\u5165\u5411\u91cf\u6570\u636e\u5e93\u3002<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u6ce8\u610f\u4e8b\u9879\uff1a\u786e\u4fdd S3 \u5b58\u50a8\u6876\u7684 URI \u683c\u5f0f\u6b63\u786e\uff08s3:\/\/&lt;bucket-name>\/&lt;prefix>\/&lt;object>\uff09\uff0c\u5e76\u68c0\u67e5 IAM \u6743\u9650\u4ee5\u5141\u8bb8 Bedrock \u8bbf\u95ee\u3002<\/li>\n\n\n\n<li>\u5efa\u8bae\uff1a\u4e3a\u6570\u636e\u6e90\u6dfb\u52a0\u5143\u6570\u636e\u6587\u4ef6\uff08\u5982\u5de5\u5177\u7c7b\u522b\u3001\u4f18\u5148\u7ea7\uff09\uff0c\u4ee5\u589e\u5f3a\u540e\u7eed\u68c0\u7d22\u6548\u679c\u3002<\/li>\n\n\n\n<li>def write_tools_to_knowledge_base(self, tools_data: Dict[str, Any]) -> IngestionJobResult:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;&#8221;&#8221;<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Clear Knowledge Base and write new tools data.<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Args:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 tools_data: Dictionary containing tool definitions in format {&#8220;tools&#8221;: [&#8230;]}<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Returns:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 IngestionJobResult with job information<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Raises:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 KnowledgeBaseError: If writing fails<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ValueError: If tools_data format is invalid<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;&#8221;&#8221;<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Validate input<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if not isinstance(tools_data, dict) or &#8220;tools&#8221; not in tools_data:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 raise ValueError(&#8220;Invalid tools_data format: must contain &#8216;tools&#8217; key&#8221;)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if not tools_data[&#8220;tools&#8221;]:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 raise ValueError(&#8220;Invalid tools_data format: &#8216;tools&#8217; list cannot be empty&#8221;)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 try:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Clear existing chunks<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if not self.clear_knowledge_base_chunks():<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 raise KnowledgeBaseError(&#8220;Failed to clear Knowledge Base chunks&#8221;)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Create temporary JSONL file<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 temp_file_path = self._create_temp_jsonl_file(tools_data[&#8220;tools&#8221;])<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0try:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Upload to S3<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 s3_key = self._upload_to_s3(temp_file_path)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Start ingestion job<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 response = self._start_ingestion_job()<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ingestion_job_id = response[&#8220;ingestionJob&#8221;][&#8220;ingestionJobId&#8221;]<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>logger.info(f&#8221;Started ingestion job: {ingestion_job_id}&#8221;)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Wait for completion<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 status = self.wait_for_ingestion_job(ingestion_job_id)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return IngestionJobResult(<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 job_id=ingestion_job_id,<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 status=status,<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 response=response<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 )<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 finally:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Clean up temporary file<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 self._cleanup_temp_file(temp_file_path)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 except Exception as e:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 logger.error(f&#8221;Error writing tools to Knowledge Base: {str(e)}&#8221;)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 raise KnowledgeBaseError(f&#8221;Failed to write tools to Knowledge Base: {str(e)}&#8221;)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0 def _start_ingestion_job(self) -> Dict[str, Any]:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;&#8221;&#8221;Start an ingestion job.&#8221;&#8221;&#8221;<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 try:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 response = self.bedrock_agent_client.start_ingestion_job(<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 knowledgeBaseId=self.knowledge_base_id,<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 dataSourceId=self.data_source_id<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 )<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return response<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 except Exception as e:<\/li>\n<\/ul>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; raise KnowledgeBaseError(f&#8221;Failed to start ingestion job: {str(e)}&#8221;)<\/p>\n\n\n\n<p><strong>3. \u914d\u7f6e Amazon Bedrock Knowledge Bases<\/strong><\/p>\n\n\n\n<p>\u5728 Amazon Bedrock \u7ba1\u7406\u63a7\u5236\u53f0\u4e2d\u521b\u5efa\u5e76\u914d\u7f6e Knowledge Base\uff0c\u786e\u4fdd\u5de5\u5177\u6570\u636e\u6b63\u786e\u5b58\u50a8\u548c\u5411\u91cf\u5316\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5411\u91cf\u5b58\u50a8\u9009\u62e9\uff1a\u63a8\u8350\u4f7f\u7528 Amazon OpenSearch Serverless\uff0c\u652f\u6301\u9ad8\u5e76\u53d1\u548c\u4f4e\u5ef6\u8fdf\uff0c\u9002\u5408\u751f\u4ea7\u73af\u5883\u3002\u4e5f\u53ef\u9009\u62e9 Amazon Aurora with pgvector \u4ee5\u964d\u4f4e\u6210\u672c\uff0c\u9002\u7528\u4e8e\u5c0f\u578b\u9879\u76ee\u3002<\/li>\n\n\n\n<li>\u6570\u636e\u6e90\u914d\u7f6e\uff1a\u6307\u5b9a S3 \u5b58\u50a8\u6876\u7684 URI\uff0c\u5e76\u786e\u4fdd\u6587\u4ef6\u8def\u5f84\u6b63\u786e\u3002\u53ef\u9009\uff1a\u4e0a\u4f20\u5143\u6570\u636e\u6587\u4ef6\u4ee5\u652f\u6301\u9ad8\u7ea7\u68c0\u7d22\u3002\n<ul class=\"wp-block-list\">\n<li>\u89e3\u6790\u7b56\u7565\uff1a\u9ed8\u8ba4\u89e3\u6790\u5668\uff1a\u9002\u7528\u4e8e jsonl \u7b49\u7eaf\u6587\u672c\u6570\u636e\uff0c\u7b80\u5355\u9ad8\u6548\u3002<\/li>\n\n\n\n<li>\u81ea\u5b9a\u4e49\u89e3\u6790\u5668\uff1a\u901a\u8fc7 AWS Lambda \u5b9e\u73b0\u7279\u5b9a\u683c\u5f0f\u7684\u89e3\u6790\u903b\u8f91\uff0c\u9002\u5408\u5b9a\u5236\u5316\u9700\u6c42\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>\u5411\u91cf\u5316\u914d\u7f6e\uff1a\n<ul class=\"wp-block-list\">\n<li>\u9009\u62e9\u5d4c\u5165\u6a21\u578b\uff08\u5982 Amazon Titan Text Embeddings V2\uff09\u5c06\u5de5\u5177\u63cf\u8ff0\u8f6c\u6362\u4e3a\u9ad8\u7ef4\u5411\u91cf\u3002<\/li>\n\n\n\n<li>\u914d\u7f6e\u5206\u5757\u7b56\u7565\uff0c\u4f7f\u7528\u81ea\u5b9a\u4e49 Chunk\uff0c\u5e73\u8861\u68c0\u7d22\u7cbe\u5ea6\u548c\u6027\u80fd\u3002<\/li>\n\n\n\n<li>\u53ef\u9009\uff1a\u542f\u7528\u6df7\u5408\u68c0\u7d22\uff08\u8bed\u4e49+\u5173\u952e\u8bcd\uff09\u4ee5\u63d0\u9ad8\u590d\u6742\u67e5\u8be2\u7684\u51c6\u786e\u6027\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u6ce8\u610f\u4e8b\u9879\uff1a\u9a8c\u8bc1\u5d4c\u5165\u6a21\u578b\u662f\u5426\u9002\u914d\u5de5\u5177\u63cf\u8ff0\u7684\u8bed\u8a00\u7279\u6027\uff08\u5982\u4e2d\u6587\u652f\u6301\uff09\u3002<\/li>\n\n\n\n<li>\u5efa\u8bae\uff1a\u4f7f\u7528 Amazon CloudWatch \u76d1\u63a7\u6570\u636e\u63d0\u53d6\u4efb\u52a1\u7684\u72b6\u6001\u548c\u6027\u80fd\u3002<\/li>\n<\/ul>\n\n\n\n<p>\u4e0b\u9762\u662f\u521b\u5efa\u622a\u56fe\uff1a<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><img loading=\"lazy\" decoding=\"async\" width=\"554\" height=\"220\" src=\"blob:https:\/\/flycloud.io\/443ae992-e9b4-4126-a877-40e6eda67a3a\"><a href=\"https:\/\/d2908q01vomqb2.cloudfront.net\/472b07b9fcf2c2451e8781e944bf5f77cd8457c8\/2025\/07\/01\/combining-rag-and-mcp-in-amazon-bedrock-to-effectively-alleviate-prompt-bloat4.png\"><\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5728\u9009\u62e9\u6570\u636e\u6e90\u4e2d\uff0c\u6211\u4eec\u4f7f\u7528 S3 \u505a\u4e3a\u6570\u636e\u6e90<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><img loading=\"lazy\" decoding=\"async\" width=\"554\" height=\"244\" src=\"blob:https:\/\/flycloud.io\/fdb3826c-1833-458d-9a7b-9355320982d0\"><a href=\"https:\/\/d2908q01vomqb2.cloudfront.net\/472b07b9fcf2c2451e8781e944bf5f77cd8457c8\/2025\/07\/01\/combining-rag-and-mcp-in-amazon-bedrock-to-effectively-alleviate-prompt-bloat5.png\"><\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u63a5\u4e0b\u6765\u9009\u62e9\u914d\u7f6e\u6570\u636e\u6e90\uff0c\u9009\u62e9\u914d\u7f6e\u597d\u7684 S3 bucket<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><img loading=\"lazy\" decoding=\"async\" width=\"554\" height=\"66\" src=\"blob:https:\/\/flycloud.io\/ee2ef558-cf50-4a7a-85c9-da4b1d45330b\"><a href=\"https:\/\/d2908q01vomqb2.cloudfront.net\/472b07b9fcf2c2451e8781e944bf5f77cd8457c8\/2025\/07\/01\/combining-rag-and-mcp-in-amazon-bedrock-to-effectively-alleviate-prompt-bloat6.png\"><\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u9009\u62e9\u8f6c\u6362\u7b56\u7565\uff0c\u5728\u8fd9\u91cc\uff0c\u6211\u4eec\u9009\u62e9\u9ed8\u8ba4\u7684\u8f6c\u6362\u7b56\u7565\uff0c\u56e0\u4e3a\u6211\u4eec\u4e0a\u4f20\u7684\u90fd\u662f\u6587\u672c\uff0c\u5982\u679c\u6709\u5bf9\u591a\u6a21\u6001\u7684\u9700\u6c42\uff0c\u53ef\u4ee5\u8be6\u7ec6\u67e5\u770b Data Automation \u7684\u529f\u80fd<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><img loading=\"lazy\" decoding=\"async\" width=\"554\" height=\"137\" src=\"blob:https:\/\/flycloud.io\/72464fe8-ce3d-42c7-a0ba-efd576903b08\"><a href=\"https:\/\/d2908q01vomqb2.cloudfront.net\/472b07b9fcf2c2451e8781e944bf5f77cd8457c8\/2025\/07\/01\/combining-rag-and-mcp-in-amazon-bedrock-to-effectively-alleviate-prompt-bloat7.png\"><\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u63a5\u4e0b\u6765\uff0c\u5728 Chunking strategy \u4e2d\uff0c\u6211\u4eec\u9009\u62e9 No chunking\uff0c\u76ee\u7684\u662f\u4e3a\u4e86\u4f7f\u7528\u81ea\u5b9a\u4e49\u7684 chunking \u7b56\u7565<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><img loading=\"lazy\" decoding=\"async\" width=\"554\" height=\"66\" src=\"blob:https:\/\/flycloud.io\/f6f2badc-8475-4c4d-94f2-e692e17312fb\"><a href=\"https:\/\/d2908q01vomqb2.cloudfront.net\/472b07b9fcf2c2451e8781e944bf5f77cd8457c8\/2025\/07\/01\/combining-rag-and-mcp-in-amazon-bedrock-to-effectively-alleviate-prompt-bloat8.png\"><\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u9009\u62e9\u81ea\u5b9a\u4e49 Chunking \u7684 Lambda\uff0c\u8fd9\u6837\u6211\u4eec\u53ef\u4ee5\u81ea\u5b9a\u4e49 Chunking \u540e\u7684\u7ed3\u679c\uff0c\u76ee\u7684\u662f\u5c06\u6bcf\u4e00\u4e2a Tool \u4f5c\u4e3a\u4e00\u4e2a Chunk \u8fdb\u884c\u5b58\u50a8\uff0c\u67e5\u8be2\u7684\u65f6\u5019\u80fd\u591f\u67e5\u5230\u4e00\u4e2a\u5b8c\u6574\u7684 Tool<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><img loading=\"lazy\" decoding=\"async\" width=\"554\" height=\"171\" src=\"blob:https:\/\/flycloud.io\/e8b18362-059a-4e8a-bbec-3f48120a4298\"><a href=\"https:\/\/d2908q01vomqb2.cloudfront.net\/472b07b9fcf2c2451e8781e944bf5f77cd8457c8\/2025\/07\/01\/combining-rag-and-mcp-in-amazon-bedrock-to-effectively-alleviate-prompt-bloat9.png\"><\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u81ea\u5b9a\u4e49 Chunking\uff0c\u4f7f\u7528 Lambda \u8fdb\u884c\u5207\u5206\uff0c\u5e76\u5c06\u5207\u5206\u5757\u8fdb\u884c\u4fdd\u5b58\uff0c\u5728\u4e0b\u9762\u7684\u4ee3\u7801\u4e2d\uff0c\u6211\u4eec\u901a\u8fc7\u83b7\u53d6 Tools \u5217\u8868\uff0c\u5e76\u5c06\u6240\u6709\u7684 Tools \u4fdd\u5b58\u6210\u4e00\u4e2a jsonl \u6587\u4ef6\uff0c\u6bcf\u4e2a tool \u4e00\u884c\uff0c\u8fd9\u6837\u6211\u4eec\u4f1a\u5728 Lambda \u4e2d\u6839\u636e\u6362\u884c\u7b26\u8fdb\u884c\u5207\u5206\uff0c\u6bcf\u4e00\u4e2a Tool \u4f5c\u4e3a\u4e00\u4e2a Chunk<\/li>\n\n\n\n<li>import json<\/li>\n\n\n\n<li>from abc import abstractmethod, ABC<\/li>\n\n\n\n<li>from typing import List<\/li>\n\n\n\n<li>import boto3<\/li>\n\n\n\n<li>import logging<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>logger = logging.getLogger()<\/li>\n\n\n\n<li>logger.setLevel(logging.DEBUG)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>class Chunker(ABC):<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 @abstractmethod<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 def chunk(self, text: str) -> List[str]:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 raise NotImplementedError()<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>class SimpleChunker(Chunker):<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 def chunk(self, text: str) -> List[str]:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Split text by newline and filter out empty lines<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return [line for line in text.split(&#8216;\\n&#8217;) if line.strip()]<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>def lambda_handler(event, context):<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 logger.debug(&#8216;input={}&#8217;.format(json.dumps(event, ensure_ascii=False)))<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 s3 = boto3.client(&#8216;s3&#8217;)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 # Extract relevant information from the input event<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 input_files = event.get(&#8216;inputFiles&#8217;)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 input_bucket = event.get(&#8216;bucketName&#8217;)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 if not all([input_files, input_bucket]):<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 raise ValueError(&#8220;Missing required input parameters&#8221;)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 output_files = []<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 chunker = SimpleChunker()<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 for input_file in input_files:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 content_batches = input_file.get(&#8216;contentBatches&#8217;, [])<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 file_metadata = input_file.get(&#8216;fileMetadata&#8217;, {})<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 original_file_location = input_file.get(&#8216;originalFileLocation&#8217;, {})<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 processed_batches = []<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 for batch in content_batches:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 input_key = batch.get(&#8216;key&#8217;)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if not input_key:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 raise ValueError(&#8220;Missing uri in content batch&#8221;)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Read file from S3<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 file_content = read_s3_file(s3, input_bucket, input_key)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Process content (chunking)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 chunked_content = process_content(file_content, chunker)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 output_key = f&#8221;Output\/{input_key}&#8221;<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Write processed content back to S3<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 write_to_s3(s3, input_bucket, output_key, chunked_content)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Add processed batch information<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 processed_batches.append({<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8216;key&#8217;: output_key<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 })<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Prepare output file information<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 output_file = {<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8216;originalFileLocation&#8217;: original_file_location,<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8216;fileMetadata&#8217;: file_metadata,<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8216;contentBatches&#8217;: processed_batches<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 output_files.append(output_file)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 result = {&#8216;outputFiles&#8217;: output_files}<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 logger.debug(&#8216;output={}&#8217;.format(json.dumps(result, ensure_ascii=False)))<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 return result<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>def read_s3_file(s3_client, bucket, key):<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 try:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 response = s3_client.get_object(Bucket=bucket, Key=key)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 content = response[&#8216;Body&#8217;].read().decode(&#8216;utf-8&#8217;)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Try to parse as JSON first (for structured JSON input)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 try:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return json.loads(content)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 except json.JSONDecodeError:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # If not valid JSON, assume JSONL or plain text and return as-is<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return {&#8216;fileContents&#8217;: [{&#8216;contentBody&#8217;: content, &#8216;contentType&#8217;: &#8216;text\/plain&#8217;, &#8216;contentMetadata&#8217;: {}}]}<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 except Exception as e:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 logger.error(f&#8221;Error reading S3 file {bucket}\/{key}: {str(e)}&#8221;)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 raise<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>def write_to_s3(s3_client, bucket, key, content):<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 try:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 s3_client.put_object(Bucket=bucket, Key=key, Body=json.dumps(content, ensure_ascii=False).encode(&#8216;utf-8&#8217;))<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 except Exception as e:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 logger.error(f&#8221;Error writing to S3 {bucket}\/{key}: {str(e)}&#8221;)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 raise<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>def process_content(file_content: dict, chunker: Chunker) -> dict:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 chunked_content = {<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8216;fileContents&#8217;: []<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 }<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0 for content in file_content.get(&#8216;fileContents&#8217;, []):<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 content_body = content.get(&#8216;contentBody&#8217;, &#8221;)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 content_type = content.get(&#8216;contentType&#8217;, &#8216;text\/plain&#8217;)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 content_metadata = content.get(&#8216;contentMetadata&#8217;, {})<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 # Chunk the content body by newlines<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 chunks = chunker.chunk(content_body)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 for chunk in chunks:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 chunked_content[&#8216;fileContents&#8217;].append({<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8216;contentType&#8217;: content_type,<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8216;contentMetadata&#8217;: content_metadata,<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8216;contentBody&#8217;: chunk<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 })<\/li>\n\n\n\n<li>\u00a0<\/li>\n<\/ul>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; return chunked_content<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u521b\u5efa\u5b8c\u6210\u540e\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u4fdd\u5b58\u5e76\u8c03\u7528\u4e86<\/li>\n<\/ul>\n\n\n\n<p><strong>4. \u8bed\u4e49\u68c0\u7d22\u4e0e\u63d0\u793a\u589e\u5f3a<\/strong><\/p>\n\n\n\n<p>\u5c06\u7528\u6237\u67e5\u8be2\u901a\u8fc7\u5d4c\u5165\u6a21\u578b\u8f6c\u6362\u4e3a\u5411\u91cf\uff0c\u5728\u5411\u91cf\u6570\u636e\u5e93\u4e2d\u68c0\u7d22\u6700\u76f8\u5173\u7684\u5de5\u5177\u63cf\u8ff0\u3002\u68c0\u7d22\u7ed3\u679c\u7528\u4e8e\u6784\u5efa\u589e\u5f3a\u63d0\u793a\uff08Augmented Prompt\uff09\uff0c\u5e76\u53d1\u9001\u81f3\u5927\u8bed\u8a00\u6a21\u578b\u8fdb\u884c\u63a8\u7406\u3002\u63a8\u8350\u8bbe\u7f6e\u6700\u5927\u68c0\u7d22\u7ed3\u679c\u4e3a 5-10 \u4e2a\uff0c\u4ee5\u4f18\u5316\u63d0\u793a\u8bcd\u957f\u5ea6\u548c\u63a8\u7406\u6548\u7387\u3002<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u6ce8\u610f\u4e8b\u9879\uff1a\u786e\u4fdd\u67e5\u8be2\u8bed\u8a00\u4e0e\u5d4c\u5165\u6a21\u578b\u517c\u5bb9\uff0c\u907f\u514d\u8bed\u4e49\u504f\u5dee\u3002<\/li>\n\n\n\n<li>\u5efa\u8bae\uff1a\u542f\u7528\u6df7\u5408\u68c0\u7d22\u4ee5\u63d0\u9ad8\u590d\u6742\u67e5\u8be2\u7684\u8986\u76d6\u7387\uff0c\u5e76\u8bb0\u5f55\u68c0\u7d22\u65e5\u5fd7\u4ee5\u5206\u6790\u7ed3\u679c\u76f8\u5173\u6027\u3002\uff08\u5728\u4e0b\u9762\u4ee3\u7801\u4e2d\u6211\u4eec\u4f7f\u7528\u7684\u662f\u8bed\u610f\u68c0\u7d22\uff0c\u6df7\u5408\u68c0\u7d22\u8bf7\u53c2\u8003\u6587\u6863\uff09\u3002<\/li>\n\n\n\n<li>def query_semantic(self, query_text: str, max_results: int = 10) -> QueryResult:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;&#8221;&#8221;<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Perform semantic query on the Knowledge Base.<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Args:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 query_text: Semantic query text, e.g., &#8220;get weather in Suzhou&#8221;<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 max_results: Maximum number of results to return (top-k)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Returns:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 QueryResult containing matching tool definitions and metadata<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Raises:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 KnowledgeBaseError: If query fails<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;&#8221;&#8221;<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 try:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 logger.info(f&#8221;Performing semantic query: {query_text[:100]}&#8230;&#8221;)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 response = self.bedrock_client.retrieve(<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 knowledgeBaseId=self.knowledge_base_id,<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 retrievalQuery={&#8220;text&#8221;: query_text},<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 retrievalConfiguration={<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8220;vectorSearchConfiguration&#8221;: {&#8220;numberOfResults&#8221;: max_results}<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 )<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 results = []<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 for result in response[&#8220;retrievalResults&#8221;]:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 try:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 content = json.loads(result[&#8220;content&#8221;][&#8220;text&#8221;])<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 results.append(content)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 logger.debug(f&#8221;Parsed query result: {content.get(&#8216;toolSpec&#8217;, {}).get(&#8216;name&#8217;, &#8216;unknown&#8217;)}&#8221;)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 except json.JSONDecodeError as e:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 logger.warning(<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 f&#8221;Failed to parse result content: {result[&#8216;content&#8217;][&#8216;text&#8217;][:100]}&#8230; &#8220;<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 f&#8221;Error: {e}&#8221;<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 )<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 continue<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 logger.info(f&#8221;Query returned {len(results)} valid results&#8221;)<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return QueryResult(<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 tools=results,<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 total_results=len(results)<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 )<\/li>\n\n\n\n<li>\u00a0<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 except Exception as e:<\/li>\n\n\n\n<li>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 logger.error(f&#8221;Error querying Knowledge Base: {str(e)}&#8221;)<\/li>\n<\/ul>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; raise KnowledgeBaseError(f&#8221;Failed to query Knowledge Base: {str(e)}&#8221;)<\/p>\n\n\n\n<p>\u81f3\u6b64\uff0c\u6211\u4eec\u53ef\u4ee5\u5c06 Tools \u5b58\u50a8\u5230 RAG \u4e2d\uff0c\u5e76\u901a\u8fc7 SDK \u8bfb\u53d6 Tools \u7684\u6d41\u7a0b\u68b3\u7406\u6e05\u695a\uff0c\u8be6\u7ec6\u4ee3\u7801\u8bf7\u53c2\u8003 <a href=\"https:\/\/github.com\/memoverflow\/rag-mcp\">https:\/\/github.com\/memoverflow\/rag-mcp<\/a>\u3002<\/p>","protected":false},"excerpt":{"rendered":"<p>\u80cc\u666f \u5927\u8bed\u8a00\u6a21\u578b\uff08LLM\uff09\u5728\u81ea\u7136\u8bed\u8a00\u5904\u7406\u3001\u4efb\u52a1\u81ea\u52a8\u5316\u548c\u667a\u80fd\u51b3\u7b56\u7b49\u9886\u57df\u5c55\u73b0\u4e86\u975e\u51e1\u7684\u6f5c\u529b\u3002\u7136\u800c\uff0c\u5176\u6709\u9650\u7684\u4e0a\u4e0b\u6587\u7a97\u53e3\u5e38\u5e38\u6210\u4e3a\u590d\u6742\u4efb\u52a1\u7684\u74f6\u9888\u3002\u7279\u522b\u662f\u5728\u9700\u8981\u8c03\u7528\u5927\u91cf\u5916\u90e8\u5de5\u5177\u65f6\uff0c\u4f8b\u5982\u901a\u8fc7\u6a21\u578b\u4e0a\u4e0b\u6587\u534f\u8bae\uff08MCP\uff09\u7ba1\u7406\u7684\u5de5\u5177\uff0c\u5c06\u6240\u6709\u5de5\u5177\u63cf\u8ff0\u5d4c\u5165\u63d0\u793a\u8bcd\u4f1a\u5bfc\u81f4\u201c\u63d0\u793a\u8bcd\u81a8\u80c0\u201d\uff08Prompt Bloat\uff09\u3002\u8fd9\u4e0d\u4ec5\u6324\u5360\u4e86\u5b9d\u8d35\u7684\u4e0a\u4e0b\u6587\u7a7a\u95f4\uff0c\u9650\u5236\u6a21\u578b\u63a8\u7406\u80fd\u529b\uff0c\u8fd8\u589e\u52a0\u4e86\u5de5\u5177\u9009\u62e9\u7684\u51b3\u7b56\u590d\u6742\u6027\uff0c\u964d\u4f4e\u51c6\u786e\u6027\u548c\u6027\u80fd\u3002 AWS Bedro&hellip;<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,4],"tags":[],"class_list":["post-394","post","type-post","status-publish","format-standard","hentry","category-ai","category-aws"],"_links":{"self":[{"href":"https:\/\/flycloud.io\/en\/wp-json\/wp\/v2\/posts\/394","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/flycloud.io\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/flycloud.io\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/flycloud.io\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/flycloud.io\/en\/wp-json\/wp\/v2\/comments?post=394"}],"version-history":[{"count":1,"href":"https:\/\/flycloud.io\/en\/wp-json\/wp\/v2\/posts\/394\/revisions"}],"predecessor-version":[{"id":395,"href":"https:\/\/flycloud.io\/en\/wp-json\/wp\/v2\/posts\/394\/revisions\/395"}],"wp:attachment":[{"href":"https:\/\/flycloud.io\/en\/wp-json\/wp\/v2\/media?parent=394"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/flycloud.io\/en\/wp-json\/wp\/v2\/categories?post=394"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/flycloud.io\/en\/wp-json\/wp\/v2\/tags?post=394"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}