使用嵌入向量的工具搜索:将Claude扩展到数千个工具

本教程面向有编程基础的开发者,深入讲解如何利用语义嵌入实现工具搜索,将Claude应用从数十个工具扩展到数千个。通过将工具定义转换为向量,并实现动态发现机制,可减少90%以上的上下文使用量。教程涵盖环境搭建、工具库定义、嵌入生成、搜索实现、对话循环构建等完整流程,并提供模拟执行、常见错误排查及生产优化建议,帮助开发者构建高效、可扩展的AI工程应用。

技术背景

随着Claude应用集成越来越多的专业工具,将所有工具定义预先加载到上下文中会迅速消耗上下文窗口,增加延迟和成本,并降低模型选择正确工具的准确性。当工具数量超过约100个时,这种方法变得不切实际。语义工具搜索通过将工具视为可发现的资源,按需返回相关功能,解决了这一瓶颈。它适用于工具库庞大且持续增长、需要支持领域特定API(如数据库操作、内部微服务)以及追求成本和延迟优化的场景。主要限制包括依赖嵌入模型质量、首次嵌入计算开销,以及需要维护工具元数据以提升搜索准确性。

核心原理

核心原理是利用语义嵌入将工具定义和自然语言查询映射到同一向量空间,通过余弦相似度衡量语义接近程度。工具定义被转换为包含名称、描述和参数信息的文本,使用SentenceTransformer模型(如all-MiniLM-L6-v2)生成384维向量。搜索时,将用户查询嵌入为向量,计算与所有工具向量的点积(归一化后即余弦相似度),返回Top-K最相似的工具。Claude通过一个元工具tool_search按需调用搜索,并在工具结果中接收tool_reference内容块,从而动态发现并立即使用新工具。

架构分析

系统架构分为三层:工具库层、嵌入与搜索层、对话管理层。工具库层定义所有可用工具(JSON Schema格式),并支持动态扩展。嵌入与搜索层负责将工具定义转换为文本并生成嵌入向量,实现search_tools函数进行语义检索。对话管理层初始化时仅向Claude提供tool_search工具,在对话循环中处理Claude的tool_use请求:若为tool_search则执行搜索并返回工具引用,否则执行实际工具(本教程用模拟函数)。关键设计决策包括:使用tool_reference而非完整定义以减少上下文占用;利用anthropic-beta: advanced-tool-use-2025-11-20头启用工具结果中的工具定义;采用轻量嵌入模型平衡速度与准确性。

完整实战教程

使用嵌入向量的工具搜索:将Claude扩展到数千个工具

构建包含数十个专业工具的Claude应用很快就会遇到瓶颈:预先提供所有工具定义会消耗上下文窗口,增加延迟和成本,并使Claude更难找到正确的工具。当工具数量超过约100个时,这种方法变得不切实际。

语义工具搜索通过将工具视为可发现的资源来解决这个问题。您无需预先加载数百个定义,而是为Claude提供一个tool_search工具,该工具按需返回相关功能,将上下文使用量减少90%以上,同时使应用能够扩展到数千个工具。

阅读完本教程后,您将能够:

此模式已被管理大型工具生态系统的团队在生产环境中使用,这些团队对上下文效率要求很高。虽然为了清晰起见,我们将使用一小部分工具进行演示,但相同的方法可以无缝扩展到包含数百或数千个工具的库。

先决条件

在遵循本指南之前,请确保您具备:

所需知识

所需工具

设置

首先,安装所需的依赖项:

# Note: we use -q to avoid printing too much to stdout
# Use --only-binary to avoid build issues with pythran
%pip install --only-binary :all: -q anthropic sentence-transformers numpy python-dotenv

确保你的 .env 文件包含以下内容:

ANTHROPIC_API_KEY=your_key_here

加载你的环境变量并配置客户端:

import json
import random
from datetime import datetime, timedelta
from typing import Any

import anthropic
import numpy as np
from dotenv import load_dotenv
from sentence_transformers import SentenceTransformer

# Load environment variables from .env file
load_dotenv()

# Define model constant for easy updates
MODEL = "claude-sonnet-4-6"

# Initialize Claude client (API key loaded from environment)
claude_client = anthropic.Anthropic()

# Load the SentenceTransformer model
# all-MiniLM-L6-v2 is a lightweight model with 384 dimensional embeddings
# It will be downloaded from HuggingFace on first use
print("Loading SentenceTransformer model...")
embedding_model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")

print("✓ Clients initialized successfully")

定义工具库

在实现语义搜索之前,我们需要有可供搜索的工具。我们将创建一个包含8个工具的工具库,涵盖两个类别:天气和金融。

在生产应用中,你可能需要管理内部API、数据库操作或第三方集成中的数百甚至数千个工具。语义搜索方法无需修改即可扩展到这些更大的库——我们在这里使用一个小型集合纯粹是为了演示清晰。

# Define our tool library with 2 domains
TOOL_LIBRARY = [
    # Weather Tools
    {
        "name": "get_weather",
        "description": "Get the current weather in a given location",
        "input_schema": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "The city and state, e.g. San Francisco, CA",
                },
                "unit": {
                    "type": "string",
                    "enum": ["celsius", "fahrenheit"],
                    "description": "The unit of temperature",
                },
            },
            "required": ["location"],
        },
    },
    {
        "name": "get_forecast",
        "description": "Get the weather forecast for multiple days ahead",
        "input_schema": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "The city and state",
                },
                "days": {
                    "type": "number",
                    "description": "Number of days to forecast (1-10)",
                },
            },
            "required": ["location", "days"],
        },
    },
    {
        "name": "get_timezone",
        "description": "Get the current timezone and time for a location",
        "input_schema": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "City name or timezone identifier",
                }
            },
            "required": ["location"],
        },
    },
    {
        "name": "get_air_quality",
        "description": "Get current air quality index and pollutant levels for a location",
        "input_schema": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "City name or coordinates",
                }
            },
            "required": ["location"],
        },
    },
    # Finance Tools
    {
        "name": "get_stock_price",
        "description": "Get the current stock price and market data for a given ticker symbol",
        "input_schema": {
            "type": "object",
            "properties": {
                "ticker": {
                    "type": "string",
                    "description": "Stock ticker symbol (e.g., AAPL, GOOGL)",
                },
                "include_history": {
                    "type": "boolean",
                    "description": "Include historical data",
                },
            },
            "required": ["ticker"],
        },
    },
    {
        "name": "convert_currency",
        "description": "Convert an amount from one currency to another using current exchange rates",
        "input_schema": {
            "type": "object",
            "properties": {
                "amount": {
                    "type": "number",
                    "description": "Amount to convert",
                },
                "from_currency": {
                    "type": "string",
                    "description": "Source currency code (e.g., USD)",
                },
                "to_currency": {
                    "type": "string",
                    "description": "Target currency code (e.g., EUR)",
                },
            },
            "required": ["amount", "from_currency", "to_currency"],
        },
    },
    {
        "name": "calculate_compound_interest",
        "description": "Calculate compound interest for investments over time",
        "input_schema": {
            "type": "object",
            "properties": {
                "principal": {
                    "type": "number",
                    "description": "Initial investment amount",
                },
                "rate": {
                    "type": "number",
                    "description": "Annual interest rate (as percentage)",
                },
                "years": {"type": "number", "description": "Number of years"},
                "frequency": {
                    "type": "string",
                    "enum": ["daily", "monthly", "quarterly", "annually"],
                    "description": "Compounding frequency",
                },
            },
            "required": ["principal", "rate", "years"],
        },
    },
    {
        "name": "get_market_news",
        "description": "Get recent financial news and market updates for a specific company or sector",
        "input_schema": {
            "type": "object",
            "properties": {
                "query": {
                    "type": "string",
                    "description": "Company name, ticker symbol, or sector",
                },
                "limit": {
                    "type": "number",
                    "description": "Maximum number of news articles to return",
                },
            },
            "required": ["query"],
        },
    },
]

print(f"✓ Defined {len(TOOL_LIBRARY)} tools in the library")

创建工具嵌入

语义搜索通过比较文本的*含义*来工作,而不仅仅是搜索关键词。为了实现这一点,我们需要将每个工具定义转换为一个嵌入向量,以捕获其语义含义。

由于我们的工具定义是带有名称、描述和参数的结构化 JSON 对象,我们首先将每个工具转换为人类可读的文本表示,然后使用 SentenceTransformer 的 all-MiniLM-L6-v2 模型生成嵌入向量。

我们选择这个模型是因为它:

让我们首先创建一个将工具定义转换为可搜索文本的函数:

def tool_to_text(tool: dict[str, Any]) -> str:
    """
    Convert a tool definition into a text representation for embedding.
    Combines the tool name, description, and parameter information.
    """
    text_parts = [
        f"Tool: {tool['name']}",
        f"Description: {tool['description']}",
    ]

    # Add parameter information
    if "input_schema" in tool and "properties" in tool["input_schema"]:
        params = tool["input_schema"]["properties"]
        param_descriptions = []
        for param_name, param_info in params.items():
            param_desc = param_info.get("description", "")
            param_type = param_info.get("type", "")
            param_descriptions.append(f"{param_name} ({param_type}): {param_desc}")

        if param_descriptions:
            text_parts.append("Parameters: " + ", ".join(param_descriptions))

    return "\n".join(text_parts)


# Test with one tool
sample_text = tool_to_text(TOOL_LIBRARY[0])
print("Sample tool text representation:")
print(sample_text)

现在让我们为所有工具创建嵌入向量:

# Create embeddings for all tools
print("Creating embeddings for all tools...")

tool_texts = [tool_to_text(tool) for tool in TOOL_LIBRARY]

# Embed all tools at once using SentenceTransformer
# The model returns normalized embeddings by default
tool_embeddings = embedding_model.encode(tool_texts, convert_to_numpy=True)

print(f"✓ Created embeddings with shape: {tool_embeddings.shape}")
print(f"  - {tool_embeddings.shape[0]} tools")
print(f"  - {tool_embeddings.shape[1]} dimensions per embedding")

实现工具搜索

将工具嵌入为向量后,我们现在可以实现语义搜索。如果两段文本含义相似,它们的嵌入向量在向量空间中会彼此接近。我们使用余弦相似度来衡量这种“接近程度”。

搜索过程:

  1. 嵌入查询:将Claude的自然语言搜索请求转换到与工具相同的向量空间
  2. 计算相似度:计算查询向量与每个工具向量之间的余弦相似度
  3. 排序并返回:按相似度分数对工具排序,并返回前N个匹配项

借助语义搜索,Claude可以使用自然语言进行搜索,例如“我需要查看天气”或“计算投资回报”,而无需使用确切的工具名称。

让我们实现搜索函数,并用一个示例查询进行测试:

def search_tools(query: str, top_k: int = 5) -> list[dict[str, Any]]:
    """
    Search for tools using semantic similarity.

    Args:
        query: Natural language description of what tool is needed
        top_k: Number of top tools to return

    Returns:
        List of tool definitions most relevant to the query
    """
    # Embed the query using SentenceTransformer
    query_embedding = embedding_model.encode(query, convert_to_numpy=True)

    # Calculate cosine similarity using dot product
    # SentenceTransformer returns normalized embeddings, so dot product = cosine similarity
    similarities = np.dot(tool_embeddings, query_embedding)

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

    # Return the corresponding tools with their scores
    results = []
    for idx in top_indices:
        results.append({"tool": TOOL_LIBRARY[idx], "similarity_score": float(similarities[idx])})

    return results


# Test the search function
test_query = "I need to check the weather"
test_results = search_tools(test_query, top_k=3)

print(f"Search query: '{test_query}'\n")
print("Top 3 matching tools:")
for i, result in enumerate(test_results, 1):
    tool_name = result["tool"]["name"]
    score = result["similarity_score"]
    print(f"{i}. {tool_name} (similarity: {score:.3f})")

定义 tool_search 工具

现在我们将实现元工具,它允许 Claude 按需发现其他工具。当 Claude 需要它不具备的能力时,它会使用这个 tool_search 工具进行搜索,在结果中接收工具定义,并可以立即使用这些新发现的工具。

这是我们最初提供给 Claude 的唯一工具:

# The tool_search tool definition
TOOL_SEARCH_DEFINITION = {
    "name": "tool_search",
    "description": "Search for available tools that can help with a task. Returns tool definitions for matching tools. Use this when you need a tool but don't have it available yet.",
    "input_schema": {
        "type": "object",
        "properties": {
            "query": {
                "type": "string",
                "description": "Natural language description of what kind of tool you need (e.g., 'weather information', 'currency conversion', 'stock prices')",
            },
            "top_k": {
                "type": "number",
                "description": "Number of tools to return (default: 5)",
            },
        },
        "required": ["query"],
    },
}

print("✓ Tool search definition created")

现在让我们实现处理来自Claude的tool_search调用的处理器,并返回发现的工具:

def handle_tool_search(query: str, top_k: int = 5) -> list[dict[str, Any]]:
    """
    Handle a tool_search invocation and return tool references.

    Returns a list of tool_reference content blocks for discovered tools.
    """
    # Search for relevant tools
    results = search_tools(query, top_k=top_k)

    # Create tool_reference objects instead of full definitions
    tool_references = [
        {"type": "tool_reference", "tool_name": result["tool"]["name"]} for result in results
    ]

    print(f"\n🔍 Tool search: '{query}'")
    print(f"   Found {len(tool_references)} tools:")
    for i, result in enumerate(results, 1):
        print(f"   {i}. {result['tool']['name']} (similarity: {result['similarity_score']:.3f})")

    return tool_references


# Test the handler
test_result = handle_tool_search("stock market data", top_k=3)
print(f"\nReturned {len(test_result)} tool references:")
for ref in test_result:
    print(f"  {ref}")

模拟工具执行

为了演示,我们将为工具执行创建模拟响应。在实际应用中,这些将调用真实的 API 或服务:

def mock_tool_execution(tool_name: str, tool_input: dict[str, Any]) -> str:
    """
    Generate realistic mock responses for tool executions.

    Args:
        tool_name: Name of the tool being executed
        tool_input: Input parameters for the tool

    Returns:
        Mock response string appropriate for the tool
    """
    # Weather tools
    if tool_name == "get_weather":
        location = tool_input.get("location", "Unknown")
        unit = tool_input.get("unit", "fahrenheit")
        temp = random.randint(15, 30) if unit == "celsius" else random.randint(60, 85)
        conditions = random.choice(["sunny", "partly cloudy", "cloudy", "rainy"])
        return json.dumps(
            {
                "location": location,
                "temperature": temp,
                "unit": unit,
                "conditions": conditions,
                "humidity": random.randint(40, 80),
                "wind_speed": random.randint(5, 20),
            }
        )

    elif tool_name == "get_forecast":
        location = tool_input.get("location", "Unknown")
        days = int(tool_input.get("days", 5))
        forecast = []
        for i in range(days):
            date = (datetime.now() + timedelta(days=i)).strftime("%Y-%m-%d")
            forecast.append(
                {
                    "date": date,
                    "high": random.randint(20, 30),
                    "low": random.randint(10, 20),
                    "conditions": random.choice(["sunny", "cloudy", "rainy", "partly cloudy"]),
                }
            )
        return json.dumps({"location": location, "forecast": forecast})

    elif tool_name == "get_timezone":
        location = tool_input.get("location", "Unknown")
        return json.dumps(
            {
                "location": location,
                "timezone": "UTC+9",
                "current_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                "utc_offset": "+09:00",
            }
        )

    elif tool_name == "get_air_quality":
        location = tool_input.get("location", "Unknown")
        aqi = random.randint(20, 150)
        categories = {
            (0, 50): "Good",
            (51, 100): "Moderate",
            (101, 150): "Unhealthy for Sensitive Groups",
        }
        category = next(cat for (low, high), cat in categories.items() if low <= aqi <= high)
        return json.dumps(
            {
                "location": location,
                "aqi": aqi,
                "category": category,
                "pollutants": {
                    "pm25": random.randint(5, 50),
                    "pm10": random.randint(10, 100),
                    "o3": random.randint(20, 80),
                },
            }
        )

    # Finance tools
    elif tool_name == "get_stock_price":
        ticker = tool_input.get("ticker", "UNKNOWN")
        return json.dumps(
            {
                "ticker": ticker,
                "price": round(random.uniform(100, 500), 2),
                "change": round(random.uniform(-5, 5), 2),
                "change_percent": round(random.uniform(-2, 2), 2),
                "volume": random.randint(1000000, 10000000),
                "market_cap": f"${random.randint(100, 1000)}B",
            }
        )

    elif tool_name == "convert_currency":
        amount = tool_input.get("amount", 0)
        from_currency = tool_input.get("from_currency", "USD")
        to_currency = tool_input.get("to_currency", "EUR")
        # Mock exchange rate
        rate = random.uniform(0.8, 1.2)
        converted = round(amount * rate, 2)
        return json.dumps(
            {
                "original_amount": amount,
                "from_currency": from_currency,
                "to_currency": to_currency,
                "exchange_rate": round(rate, 4),
                "converted_amount": converted,
            }
        )

    elif tool_name == "calculate_compound_interest":
        principal = tool_input.get("principal", 0)
        rate = tool_input.get("rate", 0)
        years = tool_input.get("years", 0)
        frequency = tool_input.get("frequency", "monthly")

        # Calculate compound interest
        n_map = {"daily": 365, "monthly": 12, "quarterly": 4, "annually": 1}
        n = n_map.get(frequency, 12)
        final_amount = principal * (1 + rate / 100 / n) ** (n * years)
        interest_earned = final_amount - principal

        return json.dumps(
            {
                "principal": principal,
                "rate": rate,
                "years": years,
                "compounding_frequency": frequency,
                "final_amount": round(final_amount, 2),
                "interest_earned": round(interest_earned, 2),
            }
        )

    elif tool_name == "get_market_news":
        query = tool_input.get("query", "")
        limit = tool_input.get("limit", 5)
        news = []
        for i in range(min(limit, 5)):
            news.append(
                {
                    "title": f"{query} - News Article {i + 1}",
                    "source": random.choice(
                        [
                            "Bloomberg",
                            "Reuters",
                            "Financial Times",
                            "Wall Street Journal",
                        ]
                    ),
                    "published": (datetime.now() - timedelta(hours=random.randint(1, 24))).strftime(
                        "%Y-%m-%d %H:%M"
                    ),
                    "summary": f"Latest developments regarding {query}...",
                }
            )
        return json.dumps({"query": query, "articles": news, "count": len(news)})

    # Default fallback
    else:
        return json.dumps(
            {
                "status": "executed",
                "tool": tool_name,
                "message": f"Tool {tool_name} executed successfully with input: {json.dumps(tool_input)}",
            }
        )


print("✓ Mock tool execution function created")

实现对话循环

现在让我们把所有内容整合在一起!我们将创建一个对话循环,处理完整的工具搜索工作流程。

对话流程:

  1. Claude 开始时只有 tool_search 工具可用
  2. 当 Claude 调用 tool_search 时,我们运行语义搜索并返回匹配的工具定义
  3. Claude 随后可以立即使用发现的工具
  4. 当 Claude 调用发现的工具时,我们执行它(本演示使用模拟响应)
  5. 循环持续进行,直到 Claude 给出最终答案
def run_tool_search_conversation(user_message: str, max_turns: int = 5) -> None:
    """
    Run a conversation with Claude using the tool search pattern.

    Args:
        user_message: The initial user message
        max_turns: Maximum number of conversation turns
    """
    print(f"\n{'=' * 80}")
    print(f"USER: {user_message}")
    print(f"{'=' * 80}\n")

    # Initialize conversation with only tool_search available
    messages = [{"role": "user", "content": user_message}]

    for turn in range(max_turns):
        print(f"\n--- Turn {turn + 1} ---")

        # Call Claude with current message history
        response = claude_client.messages.create(
            model=MODEL,
            max_tokens=1024,
            tools=TOOL_LIBRARY + [TOOL_SEARCH_DEFINITION],
            messages=messages,
            # IMPORTANT: This beta header enables tool definitions in tool results
            extra_headers={"anthropic-beta": "advanced-tool-use-2025-11-20"},
        )

        # Add assistant's response to messages
        messages.append({"role": "assistant", "content": response.content})

        # Check if we're done
        if response.stop_reason == "end_turn":
            print("\n✓ Conversation complete\n")
            # Print final response
            for block in response.content:
                if block.type == "text":
                    print(f"ASSISTANT: {block.text}")
            break

        # Handle tool uses
        if response.stop_reason == "tool_use":
            tool_results = []

            for block in response.content:
                if block.type == "text":
                    print(f"\nASSISTANT: {block.text}")

                elif block.type == "tool_use":
                    tool_name = block.name
                    tool_input = block.input
                    tool_use_id = block.id

                    print(f"\n🔧 Tool invocation: {tool_name}")
                    print(f"   Input: {json.dumps(tool_input, indent=2)}")

                    if tool_name == "tool_search":
                        # Handle tool search
                        query = tool_input["query"]
                        top_k = tool_input.get("top_k", 5)

                        # Get tool references
                        tool_references = handle_tool_search(query, top_k)

                        # Create tool result with tool_reference content blocks
                        tool_results.append(
                            {
                                "type": "tool_result",
                                "tool_use_id": tool_use_id,
                                "content": tool_references,
                            }
                        )
                    else:
                        # Execute the discovered tool with mock data
                        mock_result = mock_tool_execution(tool_name, tool_input)

                        # Print a preview of the result
                        if len(mock_result) > 150:
                            print(f"   ✅ Mock result: {mock_result[:150]}...")
                        else:
                            print(f"   ✅ Mock result: {mock_result}")

                        tool_results.append(
                            {
                                "type": "tool_result",
                                "tool_use_id": tool_use_id,
                                "content": mock_result,
                            }
                        )

            # Add tool results to messages
            if tool_results:
                messages.append({"role": "user", "content": tool_results})
        else:
            print(f"\nUnexpected stop reason: {response.stop_reason}")
            break

    print(f"\n{'=' * 80}\n")


print("✓ Conversation loop implemented")

示例 1:天气查询

让我们用一个简单的天气问题来测试。Claude 应该:

  1. 调用 tool_search 来查找天气工具
  2. 在结果中接收天气工具的定义
  3. 使用其中一个发现的工具
run_tool_search_conversation("What's the weather like in Tokyo?")

示例 2:金融查询

让我们尝试一个金融计算查询,该查询需要发现并使用金融工具:

run_tool_search_conversation(
    "If I invest $10,000 at 5% annual interest for 10 years with monthly compounding, how much will I have?"
)

结论

在本教程中,我们实现了一个客户端工具搜索系统,使Claude能够高效地处理大型工具库。我们涵盖了:

将这种方法应用于你的项目

在以下情况下考虑使用工具搜索:

后续步骤

要进一步推进此实现:

  1. 持久化嵌入:将嵌入缓存到磁盘,避免每次会话重新计算,减少启动时间
  2. 提高搜索质量:尝试不同的嵌入模型(例如,更大的模型如all-mpnet-base-v2)或实现结合语义和关键词匹配(BM25)的混合搜索
  3. 扩展到更大的库:使用数百或数千个工具进行测试,看看该模式在生产规模下的表现
  4. 添加工具元数据:在搜索排名中包含使用统计、成本信息或可靠性评分
  5. 实现缓存:缓存常用工具定义以减少重复搜索

进一步阅读

常见问题

常见错误:1) 未安装依赖或版本不兼容,导致导入失败,应使用pip install --only-binary :all: -q anthropic sentence-transformers numpy python-dotenv。2) .env文件缺失或API Key错误,导致认证失败,需确保文件存在且格式正确。3) 嵌入模型首次下载失败,检查网络或手动下载模型。4) 搜索返回不相关工具,可尝试更换更大模型(如all-mpnet-base-v2)或结合BM25混合搜索。5) 对话循环中未处理tool_use停止原因,导致死循环,需正确判断stop_reason。6) 工具结果格式错误,需确保tool_result内容为tool_reference列表或字符串。排查方法:打印响应内容、检查嵌入形状、验证相似度分数。生产优化:缓存嵌入到磁盘、使用向量数据库(如FAISS)、实现工具使用统计以调整排名。

企业应用扩展

进一步优化方向:1) 持久化嵌入:将工具嵌入保存为.npy文件,避免每次启动重新计算。2) 混合搜索:结合BM25关键词匹配与语义搜索,提升精确度。3) 扩展至大规模库:使用FAISS或Annoy进行高效近邻搜索。4) 添加工具元数据:在搜索排名中纳入使用频率、成本、可靠性评分。5) 实现缓存:缓存常用工具定义,减少重复搜索。6) 动态更新:支持工具库热更新,自动重新嵌入新增工具。7) 多模态扩展:若工具涉及图像或音频,可考虑多模态嵌入模型。

总结

本教程面向有编程基础的开发者,深入讲解如何利用语义嵌入实现工具搜索,将Claude应用从数十个工具扩展到数千个。通过将工具定义转换为向量,并实现动态发现机制,可减少90%以上的上下文使用量。教程涵盖环境搭建、工具库定义、嵌入生成、搜索实现、对话循环构建等完整流程,并提供模拟执行、常见错误排查及生产优化建议,帮助开发者构建高效、可扩展的AI工程应用。

内容来源与验证

继续系统学习

站内还有更多完整实战教程

加入会员,解锁全部教程、完整代码与持续更新内容。

加入会员
查看全部RAG 与知识库教程