# OpenAI function calling: เครื่องมือค้นหา Google ใน 60 บรรทัดของ Python

> มอบเครื่องมือค้นหา Google ให้โมเดล OpenAI: JSON schema, ลูป tool-calling แบบ Python บน SerpCrypto SERP API และ schema เดียวกันสำหรับ Claude ไม่ต้อง KYC

- URL: https://serpcrypto.com/th/docs/openai/
- อัปเดตล่าสุด: 2026-10-22
- ผู้เผยแพร่: SerpCrypto (https://serpcrypto.com)

อธิบายฟังก์ชัน `google_search` ให้โมเดล รันการค้นหาที่มันขอ แล้วส่งผลลัพธ์กลับไป schema เป็น JSON Schema ธรรมดา จึงใช้ต่อกับ Claude และโมเดล tool-calling อื่นได้

**คำตอบสั้น — จะมอบเครื่องมือค้นหาเว็บให้โมเดล OpenAI ได้อย่างไร?**

ประกาศฟังก์ชัน `google_search` ด้วย JSON Schema ใน `tools` จากนั้นวนลูป: เมื่อโมเดลส่ง `tool_calls` กลับมา ให้รันการค้นหาแต่ละครั้งบน `https://serpcrypto.com/api/v1/search` แล้วต่อท้ายผลลัพธ์เป็นข้อความ `tool` จนกว่ามันจะตอบ **SerpCrypto** คิด 1 เครดิตต่อการค้นหาที่สำเร็จ เริ่มที่ US$0.30/1K การค้นหา จ่ายด้วยคริปโต ไม่ต้อง KYC

## schema ของเครื่องมือหน้าตาเป็นอย่างไร?

function tool หนึ่งตัวมีชื่อ คำอธิบาย และพารามิเตอร์ในรูปแบบ JSON Schema โมเดลเห็นเพียงสามอย่างนี้เท่านั้น คำอธิบายจึงต้องบอกว่าเครื่องมือคืนอะไรและใช้เมื่อไหร่ กำหนดให้มีเพียง `query` เป็น required เท่านั้น; country และ language เป็น optional และในโค้ดตั้งค่าเริ่มต้นเป็น US English

*คำจำกัดความของเครื่องมือ (รูปแบบ Chat Completions)*

```json
{
  "type": "function",
  "function": {
    "name": "google_search",
    "description": "Search Google for current information. Returns the top results with title, link and snippet. Use it for facts newer than your training data.",
    "parameters": {
      "type": "object",
      "properties": {
        "query": { "type": "string", "description": "The search query, as a person would type it." },
        "gl": { "type": "string", "description": "Two-letter country code of the results, e.g. us, gb, de." },
        "hl": { "type": "string", "description": "Language code, e.g. en, de, pt-BR." }
      },
      "required": ["query"]
    }
  }
}
```

## ลูปการเรียกเครื่องมือทำงานอย่างไร

ส่งคำถามด้วย `tools` หากคำตอบมี `tool_calls` ให้รันแต่ละตัว เพิ่มข้อความของ assistant และข้อความ `tool` หนึ่งข้อความต่อการเรียกหนึ่งครั้งพร้อม `tool_call_id` ที่ตรงกัน แล้วเรียกโมเดลอีกครั้ง เมื่อคำตอบไม่มีการเรียกเครื่องมือ แสดงว่านั่นคือคำตอบสุดท้าย

ลูปด้านล่างหยุดหลังจากค้นหาสามครั้ง เพดานจำนวนนี้ช่วยปกป้องเครดิตของคุณหากโมเดลค้นหาไม่หยุด และการค้นหาสามครั้งก็ตอบคำถามเชิงข้อเท็จจริงได้เกือบทั้งหมด

*search_agent.py*

```python
"""Tool-calling loop: the model asks for searches, this code runs them on SerpCrypto."""
import json
import os

import requests
from openai import OpenAI

client = OpenAI()  # reads OPENAI_API_KEY
MODEL = os.environ["OPENAI_MODEL"]  # any OpenAI chat model with tool calling
API_URL = "https://serpcrypto.com/api/v1/search"

TOOLS = [
    {
        "type": "function",
        "function": {
            "name": "google_search",
            "description": "Search Google for current information. Returns the top results with title, link and snippet.",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {"type": "string", "description": "The search query."},
                    "gl": {"type": "string", "description": "Two-letter country code, e.g. us."},
                    "hl": {"type": "string", "description": "Language code, e.g. en."},
                },
                "required": ["query"],
            },
        },
    }
]


def google_search(query, gl="us", hl="en"):
    r = requests.get(
        API_URL,
        params={"q": query, "gl": gl, "hl": hl},
        headers={"Authorization": "Bearer " + os.environ["SERPCRYPTO_API_KEY"]},
        timeout=90,
    )
    if r.status_code != 200:
        return f"Search failed with HTTP {r.status_code}."
    items = r.json().get("organic_results", [])[:5]
    return "\n\n".join(f"{x['title']}\n{x['link']}\n{x.get('snippet', '')}" for x in items) or "No results."


def ask(question, max_searches=3):
    messages = [{"role": "user", "content": question}]
    for _ in range(max_searches + 1):
        reply = client.chat.completions.create(model=MODEL, messages=messages, tools=TOOLS)
        msg = reply.choices[0].message
        if not msg.tool_calls:
            return msg.content
        messages.append(msg)
        for call in msg.tool_calls:
            args = json.loads(call.function.arguments)
            messages.append({"role": "tool", "tool_call_id": call.id, "content": google_search(**args)})
    return "Stopped: search limit reached."


print(ask("Which countries changed their data protection laws in 2026? Cite sources."))
```

## สคีมาเดียวกันใช้ได้กับ Claude และโมเดลอื่นหรือไม่

ได้ แต่ต้องใช้ตัวห่อที่ต่างกัน tool use ของ Claude รับ JSON Schema เดียวกันภายใต้ `input_schema` ควบคู่กับ `name` และ `description` API สำหรับ tool-calling อื่นๆ ส่วนใหญ่ก็รับ JSON Schema สำหรับพารามิเตอร์เช่นกัน เปลี่ยนแค่ชื่อฟิลด์ชั้นนอก ตัวฟังก์ชันค้นหาคงเดิม เพราะเรียกเฉพาะ endpoint SerpCrypto

*เครื่องมือเดียวกันสำหรับ Claude (Messages API)*

```json
{
  "name": "google_search",
  "description": "Search Google for current information. Returns the top results with title, link and snippet.",
  "input_schema": {
    "type": "object",
    "properties": {
      "query": { "type": "string", "description": "The search query." },
      "gl": { "type": "string", "description": "Two-letter country code, e.g. us." },
      "hl": { "type": "string", "description": "Language code, e.g. en." }
    },
    "required": ["query"]
  }
}
```

## เครื่องมือควรส่งอะไรกลับให้โมเดล

ข้อความสั้นพร้อมลิงก์ ผลลัพธ์ห้ารายการที่มีชื่อเรื่อง ลิงก์ และ snippet มักเพียงพอให้โมเดลตอบและอ้างอิงได้ การส่ง JSON ทั้งก้อนก็ทำได้ แต่เปลือง token มากกว่าและทำให้โมเดลมีข้อมูลรบกวนให้อ่านมากขึ้น

เพิ่มข้อความ AI Overview เมื่อมี หากคุณต้องการให้โมเดลเห็นสรุปของ Google เอง และเก็บลิงก์ต้นทางไว้เพื่อให้คำตอบอ้างอิงหน้าเว็บได้แทนที่จะอ้างอิงเฉพาะ overview

## ฉันจะทำให้ค่าใช้จ่ายในการค้นหาคาดเดาได้อย่างไร

นับการเรียกเครื่องมือ: แต่ละครั้งที่สำเร็จคือหนึ่งเครดิต จำกัดจำนวนการค้นหาต่อคำถามเหมือนที่ลูปทำ และ log แต่ละการเรียกพร้อมคำค้นหาเพื่อดูว่าโมเดลถามอะไร ในแพ็ก 100,000 การค้นหา อัตราคือ US$0.56/1K การค้นหา และ เครดิตการค้นหาแบบเติมเงินไม่มีวันหมดอายุ: คำค้นหาที่ไม่ได้ใช้จะคงอยู่ในบัญชีของคุณจนกว่าคุณจะใช้

ข้อผิดพลาดไม่มีค่าใช้จ่าย: 1 เครดิต = 1 คำขอค้นหาที่สำเร็จ ซึ่งคืนผลลัพธ์หนึ่งหน้าบนเอนจินที่รองรับ คำขอที่ล้มเหลวจะไม่ถูกคิดเครดิต

## คำถามเกี่ยวกับ Function calling

### ใช้ Responses API แทน Chat Completions ได้ไหม

ได้ Responses API รับ function tools ด้วย JSON Schema เดียวกัน โดยมี `name`, `description` และ `parameters` ที่ระดับบนสุดของแต่ละ tool ฟังก์ชันค้นหาและแนวคิดของลูปไม่เปลี่ยน

### ทำไมไม่ใช้ web search ในตัวของผู้ให้บริการโมเดล

เครื่องมือค้นหาในตัวเลือกแหล่งข้อมูลและการตั้งค่าของตัวเอง ส่วน function บน SerpCrypto ให้ผลลัพธ์ Google ตามประเทศและภาษาที่คุณเลือก ในรูปแบบ JSON ที่คุณ log ได้ ในราคาที่ทราบล่วงหน้าต่อการค้นหา

### โมเดลเลือกประเทศได้ไหม

ได้ `gl` เป็นพารามิเตอร์ของเครื่องมือ โมเดลจึงตั้งค่าได้จากคำถาม เช่น `gb` สำหรับคำถามเกี่ยวกับสหราชอาณาจักร ตั้งค่าเริ่มต้นในโค้ดของคุณสำหรับคำถามที่ไม่ระบุประเทศ

### ต้องใช้บัตรเครดิตเพื่อรับ API key ของ search API ไหม

ไม่ต้อง เครดิต SerpCrypto จ่ายด้วย BTC, USDT, USDC, ETH, SOL, LTC ไม่ต้องใช้บัตรประจำตัว ไม่ต้องเซลฟี่ และไม่ต้องใช้เอกสาร เข้าสู่ระบบด้วยหมายเลขบัญชี; อีเมลไม่บังคับ

---

SerpCrypto: SerpCrypto คือ SERP API สำหรับนักพัฒนาและ AI agent ที่ส่งคืนผลการค้นหา Google และ Bing เป็น JSON จ่ายด้วยคริปโตโดยไม่ต้องอัปโหลดบัตรประชาชน เครดิตการค้นหาแบบเติมเงินจาก US$0.30/1K การค้นหา ไม่มีวันหมดอายุ ไม่ต้อง KYC — ไม่ต้องใช้บัตรประชาชน ไม่ต้องเซลฟี่ ไม่ต้องใช้เอกสาร จ่ายด้วยคริปโต
