{"product_id":"tool-search-với-embeddings-tim-tool-phu-hợp-bằng-semantic-search","title":"Tool Search với Embeddings — Tìm tool phù hợp bằng semantic search","description":"\n\u003cp\u003eBạn đã build được 50 tools cho Claude. Rồi 200 tools. Rồi 1000 tools. Đây là lúc gặp vấn đề nghiêm trọng: \u003cstrong\u003enếu cung cấp tất cả 1000 tool definitions trong mỗi API call, context window sẽ bị ngốn hết trước khi conversation bắt đầu.\u003c\/strong\u003e Mỗi tool definition chiếm 200-500 tokens. 1000 tools = 200,000-500,000 tokens — vượt quá context window của hầu hết models.\u003c\/p\u003e\n\n\u003cp\u003eGiải pháp: \u003cstrong\u003eTool Search\u003c\/strong\u003e — một meta-tool duy nhất cho phép Claude tìm kiếm và load đúng tool cần thiết on-demand, sử dụng semantic search với embeddings.\u003c\/p\u003e\n\n\u003ch2\u003eKiến trúc: Single meta-tool thay vì 1000 tools\u003c\/h2\u003e\n\n\u003cp\u003eThay vì inject 1000 tool definitions vào context, bạn cung cấp:\u003c\/p\u003e\n\u003col\u003e\n  \u003cli\u003e\n\u003cstrong\u003e1 tool duy nhất\u003c\/strong\u003e: \u003ccode\u003etool_search\u003c\/code\u003e — meta-tool để tìm kiếm capabilities\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eEmbedding index\u003c\/strong\u003e: Vector representation của tất cả 1000 tool descriptions\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eLazy loading\u003c\/strong\u003e: Tool definitions chỉ được load khi tìm thấy match\u003c\/li\u003e\n\u003c\/ol\u003e\n\n\u003cp\u003eClaude sẽ tự nhiên gọi \u003ccode\u003etool_search\u003c\/code\u003e khi cần một capability, nhận lại top-5 tools phù hợp nhất, sau đó dùng tools đó.\u003c\/p\u003e\n\n\u003ch2\u003eSetup: SentenceTransformer cho local embeddings\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003epip install anthropic sentence-transformers numpy\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport anthropic\nimport json\nimport numpy as np\nfrom sentence_transformers import SentenceTransformer\nfrom typing import List, Dict, Any\n\nclient = anthropic.Anthropic()\n\n# Load model embeddings local (khong can API key, chay offline)\n# all-MiniLM-L6-v2: nhanh, nhe, tot cho semantic search\nprint(\"Loading embedding model...\")\nembedding_model = SentenceTransformer('all-MiniLM-L6-v2')\nprint(\"Model loaded!\")\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eBước 1: Build tool registry với 1000+ tools\u003c\/h2\u003e\n\n\u003cp\u003eTrong demo này, chúng ta tạo một enterprise tool registry mô phỏng — thực tế bạn sẽ import từ tool catalog của mình:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003edef generate_tool_catalog() -\u0026gt; List[Dict]:\n    \"\"\"\n    Tao catalog 1000+ tools mô phong cho enterprise system.\n    Trong production: load tu database hoac config files.\n    \"\"\"\n    categories = {\n        \"crm\": [\n            (\"get_customer_profile\", \"Lay thong tin day du cua mot khach hang: contact info, purchase history, support tickets\"),\n            (\"update_customer_segment\", \"Cap nhat customer segment dua tren RFM score hoac manual override\"),\n            (\"get_customer_lifetime_value\", \"Tinh toan va tra ve CLV cua khach hang theo mo hinh predictive\"),\n            (\"merge_duplicate_customers\", \"Gop cac customer records trung lap vao mot profile chinh\"),\n            (\"get_customer_interactions\", \"Lay lich su tuong tac cua khach hang: calls, emails, chats, purchases\"),\n        ],\n        \"inventory\": [\n            (\"get_stock_level\", \"Kiem tra so luong ton kho hien tai cua mot san pham theo SKU\"),\n            (\"reserve_inventory\", \"Giu truoc mot luong hang cho don hang, giam available stock\"),\n            (\"trigger_reorder\", \"Tao purchase order khi stock xuong duoi reorder point\"),\n            (\"get_inventory_forecast\", \"Du bao nhu cau hang hoa trong 30\/60\/90 ngay toi\"),\n            (\"transfer_stock\", \"Chuyen hang giua cac kho hang hoac store locations\"),\n        ],\n        \"analytics\": [\n            (\"run_cohort_analysis\", \"Phan tich hanh vi theo cohort: retention, LTV, churn rate theo thoi gian\"),\n            (\"get_funnel_metrics\", \"Lay ty le chuyen doi tung buoc trong sales\/onboarding funnel\"),\n            (\"generate_ab_test_report\", \"Tong ket ket qua A\/B test: statistical significance, effect size, recommendation\"),\n            (\"get_revenue_attribution\", \"Phan bo revenue cho cac marketing channels theo multi-touch model\"),\n            (\"forecast_revenue\", \"Du bao doanh thu dua tren historical data va seasonal patterns\"),\n        ],\n        \"marketing\": [\n            (\"send_email_campaign\", \"Gui email marketing campaign den mot segment khach hang\"),\n            (\"get_campaign_performance\", \"Lay metrics cua mot campaign: open rate, CTR, conversion, ROI\"),\n            (\"create_audience_segment\", \"Tao segment moi dua tren behavioral hoac demographic criteria\"),\n            (\"schedule_social_post\", \"Lich social media post len LinkedIn, Facebook, Twitter\"),\n            (\"get_competitor_analysis\", \"Lay du lieu pricing, positioning cua doi thu canh tranh\"),\n        ],\n        \"hr\": [\n            (\"get_employee_performance\", \"Lay performance reviews, KPI scores, và 360 feedback cua nhan vien\"),\n            (\"calculate_payroll\", \"Tinh toan luong thang bao gom thuong, phu cap, va khau tru\"),\n            (\"get_leave_balance\", \"Kiem tra so ngay phep con lai cua nhan vien\"),\n            (\"approve_expense_report\", \"Phe duyet hoac tu choi expense report cua nhan vien\"),\n            (\"schedule_performance_review\", \"Dat lich performance review cho nhan vien va manager\"),\n        ],\n        \"finance\": [\n            (\"get_budget_utilization\", \"Xem muc do su dung budget theo department hoac project\"),\n            (\"create_invoice\", \"Tao hoa don moi cho khach hang\"),\n            (\"process_refund\", \"Xu ly yeu cau hoan tien cho don hang\"),\n            (\"get_financial_report\", \"Lay bao cao tai chinh: P\u0026amp;L, balance sheet, cash flow\"),\n            (\"approve_purchase_order\", \"Phe duyet hoac tu choi purchase order\"),\n        ],\n        \"devops\": [\n            (\"get_system_health\", \"Kiem tra trang thai cac services: uptime, response time, error rate\"),\n            (\"scale_service\", \"Tang\/giam so luong instances cua mot microservice\"),\n            (\"rollback_deployment\", \"Rollback mot deployment ve version truoc do\"),\n            (\"get_error_logs\", \"Lay error logs tu mot service trong khoang thoi gian nhat dinh\"),\n            (\"trigger_deployment\", \"Trigger deployment pipeline cho mot service\"),\n        ],\n        \"legal\": [\n            (\"get_contract_status\", \"Kiem tra trang thai va key dates cua mot contract\"),\n            (\"create_nda\", \"Tao NDA tu template, dien thong tin ben ky\"),\n            (\"get_compliance_status\", \"Kiem tra trang thai compliance: GDPR, ISO, SOC2\"),\n            (\"log_data_request\", \"Ghi nhan va xu ly data subject request (GDPR access\/deletion)\"),\n            (\"get_regulatory_updates\", \"Lay cap nhat ve regulatory changes anh huong den business\"),\n        ],\n    }\n\n    tools = []\n    for category, tool_list in categories.items():\n        for tool_name, description in tool_list:\n            tools.append({\n                \"name\": tool_name,\n                \"category\": category,\n                \"description\": description,\n                \"full_schema\": {\n                    \"name\": tool_name,\n                    \"description\": description,\n                    \"input_schema\": {\n                        \"type\": \"object\",\n                        \"properties\": {\n                            \"id\": {\"type\": \"string\", \"description\": f\"ID cho {tool_name}\"}\n                        },\n                        \"required\": []\n                    }\n                }\n            })\n\n    # Expand to 1000+ by adding variations\n    base_count = len(tools)\n    for i in range(1000 - base_count):\n        tools.append({\n            \"name\": f\"tool_{i:04d}\",\n            \"category\": \"misc\",\n            \"description\": f\"Cong cu bo tro so {i}: xu ly tac vu phat sinh trong qua trinh van hanh he thong\",\n            \"full_schema\": {\n                \"name\": f\"tool_{i:04d}\",\n                \"description\": f\"Misc tool {i}\",\n                \"input_schema\": {\"type\": \"object\", \"properties\": {}}\n            }\n        })\n\n    print(f\"Tool catalog: {len(tools)} tools across {len(categories)} categories\")\n    return tools\n\nTOOL_CATALOG = generate_tool_catalog()\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eBước 2: Build embedding index\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003eclass ToolSearchIndex:\n    \"\"\"\n    Semantic search index cho tool catalog.\n    Dung cosine similarity de tim tools phu hop nhat.\n    \"\"\"\n\n    def __init__(self, tools: List[Dict]):\n        self.tools = tools\n        self.embeddings = None\n        self._build_index()\n\n    def _build_index(self):\n        \"\"\"Embed tat ca tool descriptions.\"\"\"\n        print(\"Building embedding index...\")\n\n        # Tao text de embed: name + description\n        texts = [\n            f\"{t['name']}: {t['description']}\"\n            for t in self.tools\n        ]\n\n        # Batch embedding (nhanh hon tung cai mot)\n        self.embeddings = embedding_model.encode(\n            texts,\n            batch_size=64,\n            show_progress_bar=True,\n            normalize_embeddings=True  # L2 normalize cho cosine similarity\n        )\n\n        print(f\"Index built: {len(self.tools)} tools embedded\")\n\n    def search(self, query: str, top_k: int = 5) -\u0026gt; List[Dict]:\n        \"\"\"\n        Tim top_k tools phu hop nhat voi query.\n        Returns: list of tool dicts voi similarity scores\n        \"\"\"\n        # Embed query\n        query_embedding = embedding_model.encode(\n            [query],\n            normalize_embeddings=True\n        )[0]\n\n        # Cosine similarity (voi L2-normalized vectors = dot product)\n        similarities = np.dot(self.embeddings, query_embedding)\n\n        # Top-k indices\n        top_indices = np.argsort(similarities)[-top_k:][::-1]\n\n        results = []\n        for idx in top_indices:\n            tool = self.tools[idx].copy()\n            tool['similarity_score'] = float(similarities[idx])\n            results.append(tool)\n\n        return results\n\n# Build index (chi can build 1 lan, sau do reuse)\ntool_index = ToolSearchIndex(TOOL_CATALOG)\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eBước 3: Define tool_search meta-tool\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003eTOOL_SEARCH_META_TOOL = {\n    \"name\": \"tool_search\",\n    \"description\": \"\"\"Tim kiem cac tools phu hop cho mot nhiem vu cu the.\n    Su dung khi ban can mot capability nhung chua biet ten tool chinh xac.\n    Returns top-5 tools phu hop nhat voi mo ta va schema day du de su dung.\n\n    Vi du queries:\n    - \"customer purchase history\" -\u0026gt; get_customer_interactions, get_customer_profile\n    - \"inventory reorder\" -\u0026gt; trigger_reorder, get_inventory_forecast\n    - \"employee payroll\" -\u0026gt; calculate_payroll, get_employee_performance\"\"\",\n    \"input_schema\": {\n        \"type\": \"object\",\n        \"properties\": {\n            \"query\": {\n                \"type\": \"string\",\n                \"description\": \"Mo ta nhiem vu can lam. Cu the cang tot.\"\n            },\n            \"top_k\": {\n                \"type\": \"integer\",\n                \"description\": \"So luong tools tra ve (mac dinh 5, max 10)\",\n                \"default\": 5,\n                \"minimum\": 1,\n                \"maximum\": 10\n            }\n        },\n        \"required\": [\"query\"]\n    }\n}\n\ndef execute_tool_search(query: str, top_k: int = 5) -\u0026gt; Dict:\n    \"\"\"Thuc hien tool search va tra ve ket qua.\"\"\"\n    results = tool_index.search(query, top_k=top_k)\n\n    return {\n        \"query\": query,\n        \"found\": len(results),\n        \"tools\": [\n            {\n                \"name\": r[\"name\"],\n                \"category\": r[\"category\"],\n                \"description\": r[\"description\"],\n                \"similarity\": round(r[\"similarity_score\"], 3),\n                \"schema\": r[\"full_schema\"]\n            }\n            for r in results\n        ]\n    }\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eBước 4: Dynamic tool loading trong agent loop\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003edef run_enterprise_agent(user_request: str):\n    \"\"\"\n    Agent bat dau chi voi 1 meta-tool.\n    Khi can tool cu the, no search -\u0026gt; load -\u0026gt; su dung.\n    \"\"\"\n    messages = [{\"role\": \"user\", \"content\": user_request}]\n\n    # Chi cung cap meta-tool ban dau\n    active_tools = [TOOL_SEARCH_META_TOOL]\n    # Registry de load full definitions sau khi search\n    discovered_tools = {}\n\n    system_prompt = \"\"\"Ban la enterprise assistant co the truy cap hang ngan tools.\n    Su dung tool_search de tim kiem tool phu hop truoc, sau do dung tools do.\n    Khi search tra ve tool co schema, ban co the goi truc tiep tool do.\"\"\"\n\n    print(f\"\nUser: {user_request}\")\n    print(f\"Starting with 1 meta-tool (1000+ tools available via search)\n\")\n\n    while True:\n        response = client.messages.create(\n            model=\"claude-opus-4-5\",\n            max_tokens=4096,\n            system=system_prompt,\n            tools=active_tools,\n            messages=messages\n        )\n\n        if response.stop_reason == \"end_turn\":\n            for block in response.content:\n                if hasattr(block, 'text'):\n                    print(f\"\nClaude: {block.text}\")\n            break\n\n        elif response.stop_reason == \"tool_use\":\n            messages.append({\"role\": \"assistant\", \"content\": response.content})\n            tool_results = []\n\n            for block in response.content:\n                if block.type == \"tool_use\":\n                    if block.name == \"tool_search\":\n                        # Execute search\n                        query = block.input[\"query\"]\n                        top_k = block.input.get(\"top_k\", 5)\n                        print(f\"[Search] Query: '{query}'\")\n\n                        search_result = execute_tool_search(query, top_k)\n\n                        # Quan trong: Add discovered tools vao active_tools\n                        for tool_info in search_result[\"tools\"]:\n                            tool_schema = tool_info[\"schema\"]\n                            tool_name = tool_schema[\"name\"]\n                            if tool_name not in discovered_tools:\n                                discovered_tools[tool_name] = tool_schema\n                                active_tools.append(tool_schema)\n                                print(f\"  [Loaded] {tool_name} (score: {tool_info['similarity']:.3f})\")\n\n                        tool_results.append({\n                            \"type\": \"tool_result\",\n                            \"tool_use_id\": block.id,\n                            \"content\": json.dumps(search_result, ensure_ascii=False)\n                        })\n\n                    else:\n                        # Execute discovered tool (simulate)\n                        print(f\"[Execute] {block.name}({json.dumps(block.input)[:50]}...)\")\n                        mock_result = {\n                            \"tool\": block.name,\n                            \"status\": \"success\",\n                            \"data\": f\"[Mock data tu {block.name}]\"\n                        }\n                        tool_results.append({\n                            \"type\": \"tool_result\",\n                            \"tool_use_id\": block.id,\n                            \"content\": json.dumps(mock_result)\n                        })\n\n            messages.append({\"role\": \"user\", \"content\": tool_results})\n        else:\n            break\n\n    context_saved = (len(TOOL_CATALOG) - len(active_tools)) * 350\n    print(f\"\n[Stats] Active tools: {len(active_tools)}\/1000 | Context saved: ~{context_saved:,} tokens\")\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eTest với các queries thực tế\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003e# Test 1: Customer analytics\nrun_enterprise_agent(\n    \"Khach hang ID C-12345 co bao nhieu don hang trong 6 thang qua va CLV la bao nhieu?\"\n)\n\n# Test 2: HR + Finance combo\nrun_enterprise_agent(\n    \"Tinh luong thang 12 cho nhan vien E-789, bao gom so ngay phep con lai\"\n)\n\n# Test 3: DevOps incident\nrun_enterprise_agent(\n    \"Service payment-api dang co error rate cao, lay logs va scale them instances\"\n)\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eOutput mẫu:\u003c\/h3\u003e\n\u003cpre\u003e\u003ccode\u003eUser: Khach hang ID C-12345 co bao nhieu don hang...\n\n[Search] Query: 'customer purchase history order count'\n  [Loaded] get_customer_interactions (score: 0.847)\n  [Loaded] get_customer_profile (score: 0.812)\n  [Loaded] get_customer_lifetime_value (score: 0.798)\n\n[Search] Query: 'customer lifetime value CLV'\n  [Loaded] get_customer_lifetime_value (score: 0.923) -- already loaded\n\n[Execute] get_customer_interactions({\"id\": \"C-12345\"}...)\n[Execute] get_customer_lifetime_value({\"id\": \"C-12345\"}...)\n\nClaude: Khach hang C-12345 co 47 don hang trong 6 thang qua (trung binh 7.8 don\/thang).\nCLV du kien la 125,000,000 VND trong 24 thang toi, thuoc top 15% high-value customers.\n\n[Stats] Active tools: 4\/1000 | Context saved: ~348,600 tokens\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eHiệu suất: Context reduction 90%+\u003c\/h2\u003e\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eApproach\u003c\/th\u003e\n      \u003cth\u003eTools in context\u003c\/th\u003e\n      \u003cth\u003eTokens per request\u003c\/th\u003e\n      \u003cth\u003eFeasible at 1000 tools?\u003c\/th\u003e\n    \u003c\/tr\u003e\n  \u003c\/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eAll tools upfront\u003c\/td\u003e\n      \u003ctd\u003e1000\u003c\/td\u003e\n      \u003ctd\u003e~350,000\u003c\/td\u003e\n      \u003ctd\u003eKhong (vượt context window)\u003c\/td\u003e\n    \u003c\/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eTool search (embedding)\u003c\/td\u003e\n      \u003ctd\u003e1-10 (dynamic)\u003c\/td\u003e\n      \u003ctd\u003e~3,500\u003c\/td\u003e\n      \u003ctd\u003eCo (tiết kiệm 99%)\u003c\/td\u003e\n    \u003c\/tr\u003e\n  \u003c\/tbody\u003e\n\u003c\/table\u003e\n\n\u003ch2\u003eTổng kết\u003c\/h2\u003e\n\n\u003cp\u003eTool Search với embeddings giải quyết vấn đề scalability cho enterprise AI systems:\u003c\/p\u003e\n\n\u003cul\u003e\n  \u003cli\u003e\n\u003cstrong\u003e1 meta-tool thay vì 1000 tools\u003c\/strong\u003e trong initial context\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eSentenceTransformer all-MiniLM-L6-v2\u003c\/strong\u003e cho semantic matching chất lượng cao, chạy local\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eDynamic tool loading\u003c\/strong\u003e — chỉ load khi cần, context window luôn sạch\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003e90%+ context savings\u003c\/strong\u003e so với cung cấp tất cả tools upfront\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003eBước tiếp theo: Tìm hiểu \u003ca href=\"\/collections\/nang-cao\"\u003eTool Search — Chiến lược thay thế\u003c\/a\u003e với \u003ccode\u003edefer_loading\u003c\/code\u003e và \u003ccode\u003edescribe_tool\u003c\/code\u003e pattern — cách tiếp cận không cần embeddings nhưng vẫn đạt hiệu quả tương tự.\u003c\/p\u003e\n","brand":"Minh Tuấn","offers":[{"title":"Default Title","offer_id":66959027339309,"sku":null,"price":0.0,"currency_code":"VND","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0763\/9531\/5245\/files\/tool-search-v_i-embeddings-tim-tool-phu-h_p-b_ng-semantic-search.jpg?v=1782891821","url":"https:\/\/claudeae.com\/products\/tool-search-v%e1%bb%9bi-embeddings-tim-tool-phu-h%e1%bb%a3p-b%e1%ba%b1ng-semantic-search","provider":"Claude.vn","version":"1.0","type":"link"}