Nâng caoKỹ thuậtClaude APINguồn: Anthropic

Tool Search với Embeddings — Tìm tool phù hợp bằng semantic search

Nghe bài viết
00:00

Điểm nổi bật

Nhấn để đến mục tương ứng

  1. 1 Khai thác tối đa công cụ AI: Thay vì inject 1000 tool definitions vào context, bạn cung cấp: 1 tool duy nhất : toolsearch — meta-tool để tìm kiếm. Bí quyết nằm ở cách bạn cấu trúc yêu cầu — prompt càng rõ ràng, output càng sát nhu cầu thực tế.
  2. 2 Một điều ít người đề cập: pip install anthropic sentence-transformers numpy import anthropic import json import numpy as np from. Hiểu rõ bối cảnh áp dụng sẽ quyết định 80% thành công khi triển khai.
  3. 3 Điểm nhấn quan trọng: class ToolSearchIndex: """ Semantic search index cho tool catalog. Đây là phần mang lại giá trị thực tiễn cao nhất trong toàn bài viết.
  4. 4 Công cụ AI sẽ thay đổi cách bạn làm việc: Returns top-5 tools phu hop nhat voi mo ta va schema day du de su dung. Điểm mấu chốt là biết cách đặt prompt đúng để nhận kết quả có thể sử dụng ngay.
  5. 5 Thành thật mà nói: Test 1: Customer analytics runenterpriseagent "Khach hang ID C-12345 co bao nhieu don hang trong 6 thang qua va CLV la. Phương pháp này hiệu quả trong hầu hết trường hợp, nhưng bạn cần điều chỉnh cho phù hợp ngữ cảnh riêng.
an abstract image of a network of dots

Bạ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: nế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. 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.

Giải pháp: Tool Search — 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.

Kiến trúc: Single meta-tool thay vì 1000 tools

Thay vì inject 1000 tool definitions vào context, bạn cung cấp:

  1. 1 tool duy nhất: tool_search — meta-tool để tìm kiếm capabilities
  2. Embedding index: Vector representation của tất cả 1000 tool descriptions
  3. Lazy loading: Tool definitions chỉ được load khi tìm thấy match

Claude sẽ tự nhiên gọi tool_search khi cần một capability, nhận lại top-5 tools phù hợp nhất, sau đó dùng tools đó.

Setup: SentenceTransformer cho local embeddings

pip install anthropic sentence-transformers numpy
import anthropic
import json
import numpy as np
from sentence_transformers import SentenceTransformer
from typing import List, Dict, Any

client = anthropic.Anthropic()

# Load model embeddings local (khong can API key, chay offline)
# all-MiniLM-L6-v2: nhanh, nhe, tot cho semantic search
print("Loading embedding model...")
embedding_model = SentenceTransformer('all-MiniLM-L6-v2')
print("Model loaded!")

Bước 1: Build tool registry với 1000+ tools

Trong 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:

def generate_tool_catalog() -> List[Dict]:
    """
    Tao catalog 1000+ tools mô phong cho enterprise system.
    Trong production: load tu database hoac config files.
    """
    categories = {
        "crm": [
            ("get_customer_profile", "Lay thong tin day du cua mot khach hang: contact info, purchase history, support tickets"),
            ("update_customer_segment", "Cap nhat customer segment dua tren RFM score hoac manual override"),
            ("get_customer_lifetime_value", "Tinh toan va tra ve CLV cua khach hang theo mo hinh predictive"),
            ("merge_duplicate_customers", "Gop cac customer records trung lap vao mot profile chinh"),
            ("get_customer_interactions", "Lay lich su tuong tac cua khach hang: calls, emails, chats, purchases"),
        ],
        "inventory": [
            ("get_stock_level", "Kiem tra so luong ton kho hien tai cua mot san pham theo SKU"),
            ("reserve_inventory", "Giu truoc mot luong hang cho don hang, giam available stock"),
            ("trigger_reorder", "Tao purchase order khi stock xuong duoi reorder point"),
            ("get_inventory_forecast", "Du bao nhu cau hang hoa trong 30/60/90 ngay toi"),
            ("transfer_stock", "Chuyen hang giua cac kho hang hoac store locations"),
        ],
        "analytics": [
            ("run_cohort_analysis", "Phan tich hanh vi theo cohort: retention, LTV, churn rate theo thoi gian"),
            ("get_funnel_metrics", "Lay ty le chuyen doi tung buoc trong sales/onboarding funnel"),
            ("generate_ab_test_report", "Tong ket ket qua A/B test: statistical significance, effect size, recommendation"),
            ("get_revenue_attribution", "Phan bo revenue cho cac marketing channels theo multi-touch model"),
            ("forecast_revenue", "Du bao doanh thu dua tren historical data va seasonal patterns"),
        ],
        "marketing": [
            ("send_email_campaign", "Gui email marketing campaign den mot segment khach hang"),
            ("get_campaign_performance", "Lay metrics cua mot campaign: open rate, CTR, conversion, ROI"),
            ("create_audience_segment", "Tao segment moi dua tren behavioral hoac demographic criteria"),
            ("schedule_social_post", "Lich social media post len LinkedIn, Facebook, Twitter"),
            ("get_competitor_analysis", "Lay du lieu pricing, positioning cua doi thu canh tranh"),
        ],
        "hr": [
            ("get_employee_performance", "Lay performance reviews, KPI scores, và 360 feedback cua nhan vien"),
            ("calculate_payroll", "Tinh toan luong thang bao gom thuong, phu cap, va khau tru"),
            ("get_leave_balance", "Kiem tra so ngay phep con lai cua nhan vien"),
            ("approve_expense_report", "Phe duyet hoac tu choi expense report cua nhan vien"),
            ("schedule_performance_review", "Dat lich performance review cho nhan vien va manager"),
        ],
        "finance": [
            ("get_budget_utilization", "Xem muc do su dung budget theo department hoac project"),
            ("create_invoice", "Tao hoa don moi cho khach hang"),
            ("process_refund", "Xu ly yeu cau hoan tien cho don hang"),
            ("get_financial_report", "Lay bao cao tai chinh: P&L, balance sheet, cash flow"),
            ("approve_purchase_order", "Phe duyet hoac tu choi purchase order"),
        ],
        "devops": [
            ("get_system_health", "Kiem tra trang thai cac services: uptime, response time, error rate"),
            ("scale_service", "Tang/giam so luong instances cua mot microservice"),
            ("rollback_deployment", "Rollback mot deployment ve version truoc do"),
            ("get_error_logs", "Lay error logs tu mot service trong khoang thoi gian nhat dinh"),
            ("trigger_deployment", "Trigger deployment pipeline cho mot service"),
        ],
        "legal": [
            ("get_contract_status", "Kiem tra trang thai va key dates cua mot contract"),
            ("create_nda", "Tao NDA tu template, dien thong tin ben ky"),
            ("get_compliance_status", "Kiem tra trang thai compliance: GDPR, ISO, SOC2"),
            ("log_data_request", "Ghi nhan va xu ly data subject request (GDPR access/deletion)"),
            ("get_regulatory_updates", "Lay cap nhat ve regulatory changes anh huong den business"),
        ],
    }

    tools = []
    for category, tool_list in categories.items():
        for tool_name, description in tool_list:
            tools.append({
                "name": tool_name,
                "category": category,
                "description": description,
                "full_schema": {
                    "name": tool_name,
                    "description": description,
                    "input_schema": {
                        "type": "object",
                        "properties": {
                            "id": {"type": "string", "description": f"ID cho {tool_name}"}
                        },
                        "required": []
                    }
                }
            })

    # Expand to 1000+ by adding variations
    base_count = len(tools)
    for i in range(1000 - base_count):
        tools.append({
            "name": f"tool_{i:04d}",
            "category": "misc",
            "description": f"Cong cu bo tro so {i}: xu ly tac vu phat sinh trong qua trinh van hanh he thong",
            "full_schema": {
                "name": f"tool_{i:04d}",
                "description": f"Misc tool {i}",
                "input_schema": {"type": "object", "properties": {}}
            }
        })

    print(f"Tool catalog: {len(tools)} tools across {len(categories)} categories")
    return tools

TOOL_CATALOG = generate_tool_catalog()

Bước 2: Build embedding index

class ToolSearchIndex:
    """
    Semantic search index cho tool catalog.
    Dung cosine similarity de tim tools phu hop nhat.
    """

    def __init__(self, tools: List[Dict]):
        self.tools = tools
        self.embeddings = None
        self._build_index()

    def _build_index(self):
        """Embed tat ca tool descriptions."""
        print("Building embedding index...")

        # Tao text de embed: name + description
        texts = [
            f"{t['name']}: {t['description']}"
            for t in self.tools
        ]

        # Batch embedding (nhanh hon tung cai mot)
        self.embeddings = embedding_model.encode(
            texts,
            batch_size=64,
            show_progress_bar=True,
            normalize_embeddings=True  # L2 normalize cho cosine similarity
        )

        print(f"Index built: {len(self.tools)} tools embedded")

    def search(self, query: str, top_k: int = 5) -> List[Dict]:
        """
        Tim top_k tools phu hop nhat voi query.
        Returns: list of tool dicts voi similarity scores
        """
        # Embed query
        query_embedding = embedding_model.encode(
            [query],
            normalize_embeddings=True
        )[0]

        # Cosine similarity (voi L2-normalized vectors = dot product)
        similarities = np.dot(self.embeddings, query_embedding)

        # Top-k indices
        top_indices = np.argsort(similarities)[-top_k:][::-1]

        results = []
        for idx in top_indices:
            tool = self.tools[idx].copy()
            tool['similarity_score'] = float(similarities[idx])
            results.append(tool)

        return results

# Build index (chi can build 1 lan, sau do reuse)
tool_index = ToolSearchIndex(TOOL_CATALOG)

Bước 3: Define tool_search meta-tool

TOOL_SEARCH_META_TOOL = {
    "name": "tool_search",
    "description": """Tim kiem cac tools phu hop cho mot nhiem vu cu the.
    Su dung khi ban can mot capability nhung chua biet ten tool chinh xac.
    Returns top-5 tools phu hop nhat voi mo ta va schema day du de su dung.

    Vi du queries:
    - "customer purchase history" -> get_customer_interactions, get_customer_profile
    - "inventory reorder" -> trigger_reorder, get_inventory_forecast
    - "employee payroll" -> calculate_payroll, get_employee_performance""",
    "input_schema": {
        "type": "object",
        "properties": {
            "query": {
                "type": "string",
                "description": "Mo ta nhiem vu can lam. Cu the cang tot."
            },
            "top_k": {
                "type": "integer",
                "description": "So luong tools tra ve (mac dinh 5, max 10)",
                "default": 5,
                "minimum": 1,
                "maximum": 10
            }
        },
        "required": ["query"]
    }
}

def execute_tool_search(query: str, top_k: int = 5) -> Dict:
    """Thuc hien tool search va tra ve ket qua."""
    results = tool_index.search(query, top_k=top_k)

    return {
        "query": query,
        "found": len(results),
        "tools": [
            {
                "name": r["name"],
                "category": r["category"],
                "description": r["description"],
                "similarity": round(r["similarity_score"], 3),
                "schema": r["full_schema"]
            }
            for r in results
        ]
    }

Bước 4: Dynamic tool loading trong agent loop

def run_enterprise_agent(user_request: str):
    """
    Agent bat dau chi voi 1 meta-tool.
    Khi can tool cu the, no search -> load -> su dung.
    """
    messages = [{"role": "user", "content": user_request}]

    # Chi cung cap meta-tool ban dau
    active_tools = [TOOL_SEARCH_META_TOOL]
    # Registry de load full definitions sau khi search
    discovered_tools = {}

    system_prompt = """Ban la enterprise assistant co the truy cap hang ngan tools.
    Su dung tool_search de tim kiem tool phu hop truoc, sau do dung tools do.
    Khi search tra ve tool co schema, ban co the goi truc tiep tool do."""

    print(f"
User: {user_request}")
    print(f"Starting with 1 meta-tool (1000+ tools available via search)
")

    while True:
        response = client.messages.create(
            model="claude-opus-4-5",
            max_tokens=4096,
            system=system_prompt,
            tools=active_tools,
            messages=messages
        )

        if response.stop_reason == "end_turn":
            for block in response.content:
                if hasattr(block, 'text'):
                    print(f"
Claude: {block.text}")
            break

        elif response.stop_reason == "tool_use":
            messages.append({"role": "assistant", "content": response.content})
            tool_results = []

            for block in response.content:
                if block.type == "tool_use":
                    if block.name == "tool_search":
                        # Execute search
                        query = block.input["query"]
                        top_k = block.input.get("top_k", 5)
                        print(f"[Search] Query: '{query}'")

                        search_result = execute_tool_search(query, top_k)

                        # Quan trong: Add discovered tools vao active_tools
                        for tool_info in search_result["tools"]:
                            tool_schema = tool_info["schema"]
                            tool_name = tool_schema["name"]
                            if tool_name not in discovered_tools:
                                discovered_tools[tool_name] = tool_schema
                                active_tools.append(tool_schema)
                                print(f"  [Loaded] {tool_name} (score: {tool_info['similarity']:.3f})")

                        tool_results.append({
                            "type": "tool_result",
                            "tool_use_id": block.id,
                            "content": json.dumps(search_result, ensure_ascii=False)
                        })

                    else:
                        # Execute discovered tool (simulate)
                        print(f"[Execute] {block.name}({json.dumps(block.input)[:50]}...)")
                        mock_result = {
                            "tool": block.name,
                            "status": "success",
                            "data": f"[Mock data tu {block.name}]"
                        }
                        tool_results.append({
                            "type": "tool_result",
                            "tool_use_id": block.id,
                            "content": json.dumps(mock_result)
                        })

            messages.append({"role": "user", "content": tool_results})
        else:
            break

    context_saved = (len(TOOL_CATALOG) - len(active_tools)) * 350
    print(f"
[Stats] Active tools: {len(active_tools)}/1000 | Context saved: ~{context_saved:,} tokens")

Test với các queries thực tế

# Test 1: Customer analytics
run_enterprise_agent(
    "Khach hang ID C-12345 co bao nhieu don hang trong 6 thang qua va CLV la bao nhieu?"
)

# Test 2: HR + Finance combo
run_enterprise_agent(
    "Tinh luong thang 12 cho nhan vien E-789, bao gom so ngay phep con lai"
)

# Test 3: DevOps incident
run_enterprise_agent(
    "Service payment-api dang co error rate cao, lay logs va scale them instances"
)

Output mẫu:

User: Khach hang ID C-12345 co bao nhieu don hang...

[Search] Query: 'customer purchase history order count'
  [Loaded] get_customer_interactions (score: 0.847)
  [Loaded] get_customer_profile (score: 0.812)
  [Loaded] get_customer_lifetime_value (score: 0.798)

[Search] Query: 'customer lifetime value CLV'
  [Loaded] get_customer_lifetime_value (score: 0.923) -- already loaded

[Execute] get_customer_interactions({"id": "C-12345"}...)
[Execute] get_customer_lifetime_value({"id": "C-12345"}...)

Claude: Khach hang C-12345 co 47 don hang trong 6 thang qua (trung binh 7.8 don/thang).
CLV du kien la 125,000,000 VND trong 24 thang toi, thuoc top 15% high-value customers.

[Stats] Active tools: 4/1000 | Context saved: ~348,600 tokens

Hiệu suất: Context reduction 90%+

Approach Tools in context Tokens per request Feasible at 1000 tools?
All tools upfront 1000 ~350,000 Khong (vượt context window)
Tool search (embedding) 1-10 (dynamic) ~3,500 Co (tiết kiệm 99%)

Tổng kết

Tool Search với embeddings giải quyết vấn đề scalability cho enterprise AI systems:

  • 1 meta-tool thay vì 1000 tools trong initial context
  • SentenceTransformer all-MiniLM-L6-v2 cho semantic matching chất lượng cao, chạy local
  • Dynamic tool loading — chỉ load khi cần, context window luôn sạch
  • 90%+ context savings so với cung cấp tất cả tools upfront

Bước tiếp theo: Tìm hiểu Tool Search — Chiến lược thay thế với defer_loadingdescribe_tool pattern — cách tiếp cận không cần embeddings nhưng vẫn đạt hiệu quả tương tự.

Tính năng liên quan:Tool SearchEmbeddingsSemantic SearchScaling

Bai viet co huu ich khong?

Bản quyền thuộc về tác giả. Vui lòng dẫn nguồn khi chia sẻ.

Bình luận (0)
Ảnh đại diện
Đăng nhập để bình luận...
Đăng nhập để bình luận
  • Đang tải bình luận...

Đăng ký nhận bản tin

Nhận bài viết hay nhất về sản phẩm và vận hành, gửi thẳng vào hộp thư của bạn.

Bảo mật thông tin. Hủy đăng ký bất cứ lúc nào. Chính sách bảo mật.