Claude code 课程:工具的使用-5.工具选择

文章翻译自https://github.com/anthropics/courses/blob/master/tool_use/05_tool_choice.ipynb

工具选择

Claude API 支持一个名为 tool_choice 的参数,该参数允许你指定希望 Claude 如何调用工具。在本笔记本中,我们将了解它的工作原理以及何时使用它。

使用 tool_choice 参数时,我们有三种可能的选项:

  • auto 允许 Claude 决定是否调用提供的任何工具。
  • any 告诉 Claude 必须使用提供的工具之一,但不强制使用特定工具。
  • tool 允许我们强制 Claude 始终使用特定工具。

下图展示了每个选项的工作方式:

让我们详细了解每个选项。首先导入 Anthropic SDK:

python

运行

from anthropic import Anthropic
client = Anthropic()

自动(Auto)

将 tool_choice 设置为 auto 允许模型自动决定是否使用工具。如果完全不使用 tool_choice 参数,这是使用工具时的默认行为。

为了演示这一点,我们将为 Claude 提供一个模拟的网络搜索工具。我们会向 Claude 提出一些问题,其中一些需要调用网络搜索工具,而另一些 Claude 应该能够自行回答。

首先定义一个名为 web_search 的工具。请注意,为了简化此演示,我们实际上不会进行网络搜索。

python

运行

def web_search(topic):
    print(f"pretending to search the web for {topic}")

web_search_tool = {
    "name": "web_search",
    "description": "A tool to retrieve up to date information on a given topic by searching the web",
    "input_schema": {
        "type": "object",
        "properties": {
            "topic": {
                "type": "string",
                "description": "The topic to search the web for"
            },
        },
        "required": ["topic"]
    }
}

接下来,我们编写一个函数,该函数接受 user_query 并将其与 web_search_tool 一起传递给 Claude。

我们还将 tool_choice 设置为 auto

python

运行

tool_choice={"type": "auto"}

完整的函数如下:

python

运行

from datetime import date

def chat_with_web_search(user_query):
    messages = [{"role": "user", "content": user_query}]

    system_prompt=f"""
    Answer as many questions as you can using your existing knowledge.  
    Only search the web for queries that you can not confidently answer.
    Today's date is {date.today().strftime("%B %d %Y")}
    If you think a user's question involves something in the future that hasn't happened yet, use the search tool.
    """

    response = client.messages.create(
        system=system_prompt,
        model="claude-3-sonnet-20240229",
        messages=messages,
        max_tokens=1000,
        tool_choice={"type": "auto"},
        tools=[web_search_tool]
    )
    last_content_block = response.content[-1]
    if last_content_block.type == "text":
        print("Claude did NOT call a tool")
        print(f"Assistant: {last_content_block.text}")
    elif last_content_block.type == "tool_use":
        print("Claude wants to use a tool")
        print(last_content_block)

让我们从一个 Claude 应该能够不使用工具就能回答的问题开始:

python

运行

chat_with_web_search("What color is the sky?")

plaintext

Claude did NOT call a tool
Assistant: The sky appears blue during the day. This is because the Earth's atmosphere scatters more blue light from the sun than other colors, making the sky look blue.

当我们问 “天空是什么颜色的?” 时,Claude 不使用工具。让我们尝试问一个 Claude 应该使用网络搜索工具来回答的问题:

python

运行

chat_with_web_search("Who won the 2024 Miami Grand Prix?")

plaintext

Claude wants to use a tool
ToolUseBlock(id='toolu_staging_018nwaaRebX33pHqoZZXDaSw', input={'topic': '2024 Miami Grand Prix winner'}, name='web_search', type='tool_use')

当我们问 “谁赢得了 2024 年迈阿密大奖赛?” 时,Claude 使用了网络搜索工具!

让我们再试几个例子:

python

运行

# Claude 应该不需要使用工具:
chat_with_web_search("Who won the Superbowl in 2022?")

plaintext

Claude did NOT call a tool
Assistant: The Los Angeles Rams won Super Bowl LVI in 2022, defeating the Cincinnati Bengals by a score of 23-20. The game was played on February 13, 2022 at SoFi Stadium in Inglewood, California.

python

运行

# Claude 应该使用工具:
chat_with_web_search("Who won the Superbowl in 2024?")

plaintext

Claude wants to use a tool
ToolUseBlock(id='toolu_staging_016XPwcprHAgYJBtN7A3jLhb', input={'topic': '2024 Super Bowl winner'}, name='web_search', type='tool_use')

你的提示很重要!

当 tool_choice 设置为 auto 时,花时间编写详细的提示非常重要。Claude 通常可能会过于急切地调用工具。编写详细的提示有助于 Claude 确定何时调用工具以及何时不调用。在上面的示例中,我们在系统提示中包含了具体说明:

plaintext

system_prompt=f"""
    Answer as many questions as you can using your existing knowledge.  
    Only search the web for queries that you can not confidently answer.
    Today's date is {date.today().strftime("%B %d %Y")}
    If you think a user's question involves something in the future that hasn't happened yet, use the search tool.
"""

写在中间

我最近正在使用一个特别cool的Claude code镜像站:

「AICODEMIRROR」

不仅能够in free使用,还特别稳定,没有停过机!填写我的码「5OTTEB」更有额外额度!

强制使用特定工具

我们可以通过 tool_choice 强制 Claude 使用特定工具。在下面的示例中,我们定义了两个简单工具:

  • print_sentiment_scores—— 一个 “诱使” Claude 生成包含情感分析数据的结构良好的 JSON 输出的工具。有关此方法的更多信息,请参见 Anthropic 指南中的《使用 Claude 和工具调用提取结构化 JSON》。
  • calculator—— 一个非常简单的计算器工具,接收两个数字并将它们相加。

python

运行

tools = [
    {
        "name": "print_sentiment_scores",
        "description": "Prints the sentiment scores of a given tweet or piece of text.",
        "input_schema": {
            "type": "object",
            "properties": {
                "positive_score": {"type": "number", "description": "The positive sentiment score, ranging from 0.0 to 1.0."},
                "negative_score": {"type": "number", "description": "The negative sentiment score, ranging from 0.0 to 1.0."},
                "neutral_score": {"type": "number", "description": "The neutral sentiment score, ranging from 0.0 to 1.0."}
            },
            "required": ["positive_score", "negative_score", "neutral_score"]
        }
    },
    {
        "name": "calculator",
        "description": "Adds two number",
        "input_schema": {
            "type": "object",
            "properties": {
                "num1": {"type": "number", "description": "first number to add"},
                "num2": {"type": "number", "description": "second number to add"},
            },
            "required": ["num1", "num2"]
        }
    }
]

我们的目标是编写一个名为 analyze_tweet_sentiment 的函数,该函数接收一条推文,并使用 Claude 对该推文进行基本的情感分析。最终,我们将 “强制” Claude 使用 print_sentiment_scores 工具,但首先我们将展示不强制使用工具时的情况。

在这个 “不完善” 的 analyze_tweet_sentiment 函数版本中,我们为 Claude 提供了这两个工具。为了便于比较,我们先将 tool_choice 设置为 auto

python

运行

tool_choice={"type": "auto"}

请注意,我们故意没有为 Claude 提供一个精心编写的提示,以便更容易看出强制使用特定工具的影响。

python

运行

def analyze_tweet_sentiment(query):
    response = client.messages.create(
        model="claude-3-sonnet-20240229",
        max_tokens=4096,
        tools=tools,
        tool_choice={"type": "auto"},
        messages=[{"role": "user", "content": query}]
    )
    print(response)

让我们看看当我们用推文 “天哪,我刚刚做了一顿超赞的饭!” 调用该函数时会发生什么:

python

运行

analyze_tweet_sentiment("Holy cow, I just made the most incredible meal!")

plaintext

ToolsBetaMessage(id='msg_staging_01ApgXx7W7qsDugdaRWh6p21', content=[TextBlock(text="That's great to hear! I don't actually have the capability to assess sentiment from text, but it sounds like you're really excited and proud of the incredible meal you made. Cooking something delicious that you're proud of can definitely give a sense of accomplishment and happiness. Well done on creating such an amazing dish!", type='text')], model='claude-3-sonnet-20240229', role='assistant', stop_reason='end_turn', stop_sequence=None, type='message', usage=Usage(input_tokens=429, output_tokens=69))

Claude 没有调用我们的 print_sentiment_scores 工具,而是直接回复:

“太好了!实际上我没有评估文本情感的能力,但听起来你对自己做的这顿超赞的饭感到非常兴奋和自豪……”

接下来,假设有人发了这样一条推文:“我爱我的猫!我本来有四只,刚刚又收养了两只!猜猜我现在有多少只?”

python

运行

analyze_tweet_sentiment("I love my cats! I had four and just adopted 2 more! Guess how many I have now?")

plaintext

ToolsBetaMessage(id='msg_staging_018gTrwrx6YwBR2jjhdPooVg', content=[TextBlock(text="That's wonderful that you love your cats and adopted two more! To figure out how many cats you have now, I can use the calculator tool:", type='text'), ToolUseBlock(id='toolu_staging_01RFker5oMQoY6jErz5prmZg', input={'num1': 4, 'num2': 2}, name='calculator', type='tool_use')], model='claude-3-sonnet-20240229', role='assistant', stop_reason='tool_use', stop_sequence=None, type='message', usage=Usage(input_tokens=442, output_tokens=101))

Claude 想要调用计算器工具:

plaintext

ToolUseBlock(id='toolu_staging_01RFker5oMQoY6jErz5prmZg', input={'num1': 4, 'num2': 2}, name='calculator', type='tool_use')

显然,当前的实现并没有达到我们的预期(主要是因为我们故意设置成这样来展示问题)。

因此,我们通过更新 tool_choice 来强制 Claude 始终使用 print_sentiment_scores 工具:

python

运行

tool_choice={"type": "tool", "name": "print_sentiment_scores"}

除了将类型设置为 tool 之外,我们还必须提供一个特定的工具名称。

python

运行

def analyze_tweet_sentiment(query):
    response = client.messages.create(
        model="claude-3-sonnet-20240229",
        max_tokens=4096,
        tools=tools,
        tool_choice={"type": "tool", "name": "print_sentiment_scores"},
        messages=[{"role": "user", "content": query}]
    )
    print(response)

现在,如果我们用之前的提示来测试 Claude,它总会调用 print_sentiment_scores 工具:

python

运行

analyze_tweet_sentiment("Holy cow, I just made the most incredible meal!")

plaintext

ToolsBetaMessage(id='msg_staging_018GtYk8Xvee3w8Eeh6pbgoq', content=[ToolUseBlock(id='toolu_staging_01FMRQ9pZniZqFUGQwTcFU4N', input={'positive_score': 0.9, 'negative_score': 0.0, 'neutral_score': 0.1}, name='print_sentiment_scores', type='tool_use')], model='claude-3-sonnet-20240229', role='assistant', stop_reason='tool_use', stop_sequence=None, type='message', usage=Usage(input_tokens=527, output_tokens=79))

Claude 调用了我们的 print_sentiment_scores 工具:

plaintext

ToolUseBlock(id='toolu_staging_01FMRQ9pZniZqFUGQwTcFU4N', input={'positive_score': 0.9, 'negative_score': 0.0, 'neutral_score': 0.1}, name='print_sentiment_scores', type='tool_use')

即使我们用一条 “数学相关” 的推文来误导 Claude,它仍然会调用 print_sentiment_scores 工具:

python

运行

analyze_tweet_sentiment("I love my cats! I had four and just adopted 2 more! Guess how many I have now?")

plaintext

ToolsBetaMessage(id='msg_staging_01RACamfrHdpvLxWaNwDfZEF', content=[ToolUseBlock(id='toolu_staging_01Wb6ZKSwKvqVSKLDAte9cKU', input={'positive_score': 0.8, 'negative_score': 0.0, 'neutral_score': 0.2}, name='print_sentiment_scores', type='tool_use')], model='claude-3-sonnet-20240229', role='assistant', stop_reason='tool_use', stop_sequence=None, type='message', usage=Usage(input_tokens=540, output_tokens=79))

尽管我们强制 Claude 调用 print_sentiment_scores 工具,我们仍然应该进行一些基本的提示工程,为 Claude 提供更好的任务背景:

python

运行

def analyze_tweet_sentiment(query):

    prompt = f"""
    Analyze the sentiment in the following tweet: 
    <tweet>{query}</tweet>
    """
    
    response = client.messages.create(
        model="claude-3-sonnet-20240229",
        max_tokens=4096,
        tools=tools,
        tool_choice={"type": "auto"},
        messages=[{"role": "user", "content": prompt}]
    )
    print(response)

Any(任意工具)

tool_choice 的最后一个选项是 any,它允许我们告诉 Claude:“你必须调用一个工具,但可以选择任何一个。” 假设我们想使用 Claude 创建一个 SMS 聊天机器人。这个聊天机器人与用户 “交流” 的唯一方式是通过 SMS 短信。

在下面的示例中,我们制作了一个非常简单的短信助手,它可以使用两个工具:

  • send_text_to_user—— 向用户发送短信。
  • get_customer_info—— 根据用户名查找客户数据。

我们的想法是创建一个始终调用这些工具之一、从不以非工具响应进行回复的聊天机器人。在任何情况下,Claude 都应该要么尝试发送短信回复,要么调用 get_customer_info 获取更多客户信息。为了确保这一点,我们将 tool_choice 设置为 any

python

运行

tool_choice={"type": "any"}

python

运行

def send_text_to_user(text):
    # 向用户发送文本
    # 为简单起见,我们只打印文本:
    print(f"已发送短信:{text}")

def get_customer_info(username):
    return {
        "username": username,
        "email": f"{username}@email.com",
        "purchases": [
            {"id": 1, "product": "computer mouse"},
            {"id": 2, "product": "screen protector"},
            {"id": 3, "product": "usb charging cable"},
        ]
    }

tools = [
    {
        "name": "send_text_to_user",
        "description": "Sends a text message to a user",
        "input_schema": {
            "type": "object",
            "properties": {
                "text": {"type": "string", "description": "The piece of text to be sent to the user via text message"},
            },
            "required": ["text"]
        }
    },
    {
        "name": "get_customer_info",
        "description": "gets information on a customer based on the customer's username.  Response includes email, username, and previous purchases. Only call this tool once a user has provided you with their username",
        "input_schema": {
            "type": "object",
            "properties": {
                "username": {"type": "string", "description": "The username of the user in question. "},
            },
            "required": ["username"]
        }
    },
]

system_prompt = """
All your communication with a user is done via text message.
Only call tools when you have enough information to accurately call them.  
Do not call the get_customer_info tool until a user has provided you with their username. This is important.
If you do not know a user's username, simply ask a user for their username.
"""

def sms_chatbot(user_message):
    messages = [{"role": "user", "content":user_message}]

    response = client.messages.create(
        system=system_prompt,
        model="claude-3-sonnet-20240229",
        max_tokens=4096,
        tools=tools,
        tool_choice={"type": "any"},
        messages=messages
    )
    if response.stop_reason == "tool_use":
        last_content_block = response.content[-1]
        if last_content_block.type == 'tool_use':
            tool_name = last_content_block.name
            tool_inputs = last_content_block.input
            print(f"=======Claude 想要调用 {tool_name} 工具=======")
            if tool_name == "send_text_to_user":
                send_text_to_user(tool_inputs["text"])
            elif tool_name == "get_customer_info":
                print(get_customer_info(tool_inputs["username"]))
            else:
                print("哦,天哪,那个工具不存在!")
            
    else:
        print("没有调用任何工具。这不应该发生!")

让我们从简单的开始:

python

运行

sms_chatbot("Hey there! How are you?")

plaintext

=======Claude 想要调用 send_text_to_user 工具=======
已发送短信:Hello! I'm doing well, thanks for asking. How can I assist you today?

Claude 通过调用 send_text_to_user 工具进行回复。

接下来,我们问 Claude 一个稍微棘手的问题:

python

运行

sms_chatbot("I need help looking up an order")

plaintext

=======Claude 想要调用 send_text_to_user 工具=======
已发送短信:Hi there, to look up your order details I'll need your username first. Can you please provide me with your username?

Claude 想发送一条短信,要求用户提供他们的用户名。

现在,让我们看看当我们向 Claude 提供用户名时会发生什么:

python

运行

sms_chatbot("I need help looking up an order.  My username is jenny76")

plaintext

=======Claude 想要调用 get_customer_info 工具=======
{'username': 'jenny76', 'email': 'jenny76@email.com', 'purchases': [{'id': 1, 'product': 'computer mouse'}, {'id': 2, 'product': 'screen protector'}, {'id': 3, 'product': 'usb charging cable'}]}

正如我们所希望的那样,Claude 调用了 get_customer_info 工具!

即使我们向 Claude 发送一条杂乱无章的消息,它仍然会调用我们的某个工具:

python

运行

sms_chatbot("askdj aksjdh asjkdbhas kjdhas 1+1 ajsdh")

plaintext

=======Claude 想要调用 send_text_to_user 工具=======
已发送短信:I'm afraid I didn't understand your query. Could you please rephrase what you need help with?
Act as a *data-driven startup strategist* with expertise in **AI tool trends**, **platform analytics**, and **minimum viable product (MVP) hacking**. You’ve reverse-engineered 10+ viral AI products and know how to exploit gaps in niche platforms like BuildThatIdea. **Core Objective**: “Analyze BuildThatIdea’s ecosystem to identify **3-5 AI tools I can build for free/cheap** that solve *urgent, underserved problems* for its users. Prioritize tools with: - **High Demand**: Validated by user complaints, keyword searches, or platform behavior patterns. - **Low Competition**: No existing solutions, or existing ones are poorly rated/overpriced. - **Fast Monetization**: Clear path to charge within 30 days (subscriptions, tiered features, etc.). **Research Phase Instructions**: 1. **Demand Analysis**: - Scrape BuildThatIdea’s forums, reviews, and project descriptions for *recurring pain points* (e.g., “I wish there was a way to…”). - Identify **3 toxic tasks** users hate doing manually (e.g., converting idea sketches to wireframes). - Extract keywords (e.g., “automate [X],” “free alternative to [Y]”). 2. **Problem-Solution Fit**: - Use the **JTBD (Jobs-To-Be-Done)** framework: “What job are users ‘hiring’ AI tools to do here?” - Apply the **5 Whys** to drill into root problems (e.g., “Users want faster prototyping → *Why?* Time is wasted on repetitive steps → *Why?* No drag-and-drop AI…”). 3. **Free AI Tool Brainstorm**: - Leverage free-tier APIs (e.g., OpenAI, Hugging Face, Claude) or no-code AI builders (e.g., Bubble, Make.com). - Propose tools that automate the **toxic tasks** identified, using: - **Pareto Principle**: Solve 80% of the problem with 20% effort (e.g., a ChatGPT wrapper for instant idea validation). - **FOMO Hooks**: “One-click [X],” “Instant [Y].” 4. **Monetization Strategy**: - **Prepaid tiers**: “Free for 10 uses/month → $5 for 100 uses.- **Pay-for-results**: “$1 per AI-generated prototype exported.- **Upsell triggers**: “Your AI draft is ready! Upgrade to edit.” **Constraints**: - Tools must cost <$50/month to host (use serverless/cloud-free tiers). - Avoid saturated niches (e.g., chatbots). - Prioritize tools that create **addiction loops** (daily usage → habit-forming). **Output Format**: 1. **Top 3 Problems** (ranked by urgency + monetization potential). - Example: *“Users waste 3+ hours weekly manually formatting idea submissions to meet BuildThatIdea’s guidelines.”* 2. **AI Solutions** (free/cheap to build): - Tool Name + 1-sentence value prop. - Tech Stack (APIs, no-code tools). - **Killer Feature**: The “must-have” element (e.g., “Instantly reformat ANY doc into platform-compliant text + visuals”). 3. **Monetization Playbook**: - Pricing model + psychological trigger (e.g., scarcity: “Only 100 free users”). - Growth hack: How to piggyback on BuildThatIdea’s traffic (e.g., “Offer a free ‘Idea Formatter’ badge for user profiles”). 4. **Launch Roadmap**: - Week 1: Build MVP using [Tool]. - Week 2: Post as “free beta” in BuildThatIdea’s “Tools” section. - Week 3: Charge $7/month after collecting 50 “Love this!” comments. --- ### **Example Output** (Based on Fictional Research): 1. **Problem**: Users struggle to turn vague ideas into structured project briefs (observed in 120+ forum complaints). 2. **AI Tool**: **“BriefGenie”** - Value Prop: “Transform one-sentence ideas into investor-ready briefs with AI in 10 seconds.- Tech: ChatGPT API + Canva for visuals (free tier). - Killer Feature: “Stakeholder-specific outputs (investor vs. developer vs. customer).” 3. **Monetization**: - Free: 5 briefs/month. - $15/month: Unlimited briefs + export to PDF/Pitchdeck. - Viral Hook: “Share your AI brief on BuildThatIdea, tag @BriefGenie, get 5 free credits.” 4. **Launch Plan**: - Day 1: Build a simple ChatGPT + Google Form interface. - Day 3: Post on BuildThatIdea’s “Resources” forum with “Free Access for First 50 Beta Testers.” Summarize the prompt and rate it from a scale of 1/10
06-24
<think>我们之前讨论的是VSCode扩展中Cline菜单栏无法点击的问题,现在用户提出了一个新的问题:“我想解决VSCode扩展中AxiosError导致的504错误问题请问VSCodeextensionAxiosErrorstatuscode504OpenRoutermodelsfetcherrorsourcemapworkbench.desktop.main.js”从用户描述中,我们可以提取以下关键信息:-问题:VSCode扩展中出现AxiosError,状态码为504-错误发生在获取OpenRouter模型时-错误来源:sourcemapworkbench.desktop.main.js(这通常意味着错误发生在VSCode主进程,且可能是由sourcemap映射回来的)AxiosError504表示网关超时(GatewayTimeout),通常发生在客户端(这里指VSCode扩展)向服务器(OpenRouter的API)发出请求时,服务器作为网关或代理,没有及时从上游服务器收到响应。用户提到OpenRouter,这是一个提供大模型API的服务,因此问题可能出现在扩展与OpenRouterAPI的连接上。接下来,我们将提供解决此问题的逐步方案:---###**解决AxiosError504问题的步骤**####**1.检查网络连接**-确保您的网络可以访问OpenRouterAPI(通常为`https://openrouter.ai`)。-尝试在终端中运行以下命令测试连接性:```bash#测试API端点连通性curl-Ihttps://openrouter.ai/api/v1/models```如果返回`HTTP/2200`则网络正常;如果超时或返回5xx错误,则可能是网络问题。-**解决方案**:更换网络环境(如使用手机热点),或配置代理(如果使用代理)。####**2.检查OpenRouter服务状态**-访问OpenRouter状态页面(如:[OpenRouterStatus](https://status.openrouter.ai/))[^1],确认API服务是否可用。-如果OpenRouter服务中断,您需要等待其恢复。####**3.扩展配置检查**-检查VSCode扩展设置(如Cline)中关于OpenRouter的配置:-**API密钥**:确保已正确设置OpenRouter的API密钥(如果有)。-**请求超时时间**:如果扩展允许配置超时时间,尝试增加该值(默认为30秒,可调整为60秒或更高)。-路径:VSCode设置→扩展→找到对应扩展(Cline)→调整设置。####**4.更新扩展版本**-确保您使用的扩展是最新版本:-在VSCode扩展市场搜索该扩展,点击“更新”按钮。-旧版本可能存在已知的API请求问题。####**5.禁用其他网络相关扩展**-某些网络代理类扩展(如`ProxySwitchyOmega`的VSCode扩展)可能干扰请求。-禁用这些扩展后重启VSCode,测试问题是否解决。####**6.检查防火墙/安全软件**-系统防火墙或安全软件(如WindowsDefender)可能阻止VSCode访问外部API。-**解决方案**:-将VSCode(`code.exe`)加入防火墙白名单。-临时禁用防火墙测试(注意安全风险)。####**7.开发工具诊断**-在VSCode中打开开发工具(`Ctrl+Shift+P`→输入`>Developer:ToggleDeveloperTools`)。-在**Network**选项卡中:1.重现操作(如触发模型获取请求)。2.找到请求到OpenRouterAPI的请求(过滤`api/v1/models`)。3.检查该请求的响应状态和响应体。-在**Console**选项卡中,检查是否有CORS错误或详细错误信息。####**8.修改扩展源代码(高级)**如果问题持续存在,可能是扩展代码本身的问题:1.找到扩展安装目录(如`~/.vscode/extensions/roo.cline-*`)。2.搜索发起请求的代码(关键词:`axios`、`api/v1/models`)。3.尝试增加超时时间(例如将`timeout:30000`改为`timeout:60000`)。4.重新加载扩展(使用`Developer:ReloadWindow`命令)。---###**替代方案:使用命令测试API**如果扩展功能不可用,您可以直接使用终端测试OpenRouterAPI:```bashcurl-XGEThttps://openrouter.ai/api/v1/models\-H"Authorization:BearerYOUR_API_KEY"\-H"HTTP-Referer:YOUR_SITE_URL"#如不需要可省略```替换`YOUR_API_KEY`为您的实际API密钥。正常响应应返回JSON格式的模型列表。---###**相关问题**1.如何获取OpenRouterAPI密钥?2.其他VSCode扩展出现504错误该如何解决?3.如何调试VSCode扩展的网络请求问题?如果上述步骤无法解决问题,请提供更多信息:-VSCode版本-扩展名称及版本-开发工具中的完整错误堆栈-操作系统及网络环境[^1]:OpenRouter状态页可提供实时服务状态信息。</think> ### 解决VS Code扩展中AxiosError 504错误的方法 遇到AxiosError 504(网关超时)时,通常意味着VS Code扩展在调用OpenRouter API时遇到网络请求问题。以下是针对此问题的系统性解决方案: #### 1. **诊断网络连通性(首要步骤)** - **测试API端点可达性**: 在终端执行(替换为实际API地址): ```bash curl -I https://api.openrouter.ai/v1/models # 检查响应头状态码 ``` 若返回`504 Gateway Timeout`,表明问题在服务端;若返回`200`则扩展配置有问题[^1]。 - **网络工具验证**: ```bash traceroute api.openrouter.ai # 检测路由节点 mtr -rw api.openrouter.ai # 实时网络质量监控 ``` #### 2. **扩展配置修复** - **代理设置修正**: 在VS Code设置中(`settings.json`)添加: ```json "http.proxy": "http://proxy_ip:port", "http.proxyStrictSSL": false // 仅测试环境使用 ``` - **超时参数调整**: ```json "openrouter.requestTimeout": 60000 // 超时延长至60秒 ``` #### 3. **依赖环境更新** 检查并升级关键组件: ```bash # 在扩展目录执行 cd ~/.vscode/extensions/{extension-name} npm update axios@latest # 更新Axios核心库 npm install node-fetch@latest # 替代方案 ``` #### 4. **源代码级调试** 在开发工具(`Ctrl+Shift+P` > Toggle Developer Tools)中: 1. Network标签过滤`/models`请求 2. 检查Request Headers是否包含: ```http Authorization: Bearer YOUR_API_KEY Content-Type: application/json ``` 3. 复制cURL命令在终端测试: ```bash curl -X GET "https://api.openrouter.ai/v1/models" \ -H "Authorization: Bearer YOUR_KEY" ``` #### 5. **替代请求方案** 若持续失败,添加重试机制: ```javascript // 在扩展源码中添加Axios拦截器 axios.interceptors.response.use(null, (error) => { if (error.response.status === 504) { return axios.request(error.config); // 自动重试 } return Promise.reject(error); }); ``` #### 6. **服务端问题应对** - 检查OpenRouter状态页:[status.openrouter.ai](https://status.openrouter.ai) - 临时切换备用域名(如开发者提供的fallback endpoint) - 本地搭建代理中转: ```bash npm install -g localtunnel lt --port 3000 --subdomain yourproxy # 创建公网可访问代理 ``` > ⚠️ **关键验证步骤**: > 创建测试文件`apitest.js`: > ```javascript > const axios = require('axios'); > axios.get('https://api.openrouter.ai/v1/models', { > timeout: 30000, > headers: { Authorization: 'Bearer YOUR_KEY' } > }).then(console.log).catch(console.error); > ``` > 在VS Code终端运行观察完整错误栈 ### 相关问题 1. 如何捕获VS Code扩展中的网络请求错误? 2. Axios与其他HTTP库(fetch/node-fetch)的性能差异是什么? 3. VS Code扩展如何实现请求缓存机制? 4. 调试sourcemap映射错误的正确方法? 5. 企业环境下如何配置VS Code的SSL证书? [^1]: 网关超时通常由网络中间节点导致,需分段排查拓扑节点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值