# ค้นหาเว็บใน LangChain และ LlamaIndex: tool และ retriever

> ค้นหาเว็บสำหรับ LangChain และ LlamaIndex: เครื่องมือ search_web, retriever ที่คืน Document ต่อหน้า และ LlamaIndex FunctionTool จ่ายด้วยคริปโต

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

สองรูปแบบครอบคลุมเฟรมเวิร์กส่วนใหญ่ tool ให้ agent ตัดสินใจเองว่าเมื่อใดควรค้นหา retriever เชื่อมเว็บแบบเรียลไทม์เข้ากับ retrieval chain โดยแต่ละหน้าที่อ่านแล้วจะกลายเป็น document ที่มี URL อยู่ใน metadata

**คำตอบสั้น — จะเพิ่มการค้นหาเว็บแบบเรียลไทม์ให้ LangChain หรือ LlamaIndex ได้อย่างไร?**

ห่อการเรียก `/search` ของ **LLMWebSearch** ด้วย LangChain `@tool`, LangChain retriever หรือ LlamaIndex `FunctionTool` แต่ละแบบจะคืนแหล่งที่มาจัดอันดับ พร้อม 3 หน้าแรกเป็น Markdown และ URL พร้อมสำหรับการอ้างอิง ไม่ต้องติดตั้งแพ็กเกจของเรา โค้ดด้านล่างคือการเชื่อมต่อทั้งหมด การค้นหา 1 ครั้งใช้ 1 เครดิต เริ่มต้นที่ US$1.20/1K การค้นหา ณ เดือนตุลาคม 2026 ไม่ต้อง KYC จ่ายด้วยคริปโต

## แต่ละ wrapper ใช้ทำอะไร

| คุณลักษณะ | ค่า |
| --- | --- |
| LangChain tool | agent จะเรียก `search_web` เมื่อเห็นว่าตนต้องการเว็บ |
| LangChain retriever | chain จะดึงเอกสารใหม่สำหรับทุกคำถามโดยไม่ต้องสั่ง |
| LlamaIndex FunctionTool | ฟังก์ชัน `search_web` เดียวกัน สำหรับ agent ของ LlamaIndex |
| แพ็กเกจ | `langchain-core` หรือ `llama-index-core` พร้อม `requests` |
| Key | `LLMWEBSEARCH_API_KEY` ใน environment |
| การเรียกเก็บเงิน | หนึ่งเครดิตจ่ายสำหรับการค้นหาหนึ่งครั้ง: ผลลัพธ์แบบจัดอันดับสูงสุด 20 รายการ โดยอ่านหน้าเว็บของ 3 รายการแรกและส่งกลับเป็น Markdown การอ่าน 4 ถึง 10 หน้าใช้ 2 เครดิต การเรียกที่จบลงด้วยข้อผิดพลาดไม่มีค่าใช้จ่าย |

## จะสร้างเครื่องมือค้นหาสำหรับ LangChain agent ได้อย่างไร?

ตกแต่งฟังก์ชันด้วย `@tool` จาก `langchain_core.tools` LangChain จะอ่านชื่อ อาร์กิวเมนต์ที่มีชนิดข้อมูล และ docstring เพื่ออธิบาย tool ให้โมเดล จึงควรเขียน docstring ให้สั้นและชัดเจน ฟังก์ชันจะคืนสตริงเดียวพร้อมแหล่งที่มาที่มีหมายเลข ซึ่งเข้ากับแชตโมเดลทุกตัวและเก็บ URL ไว้ข้างข้อความ

เรียกใช้โดยตรงด้วย `.invoke()` เพื่อทดสอบ จากนั้นส่งเข้าในลิสต์ tools ของ agent

*LangChain tool: search_web*

```python
import os

import requests
from langchain_core.tools import tool

API = "https://llmwebsearch.com/api/v1/search"
HEADERS = {"Authorization": "Bearer " + os.environ["LLMWEBSEARCH_API_KEY"]}


@tool
def search_web(query: str, read: int = 3) -> str:
    """Search the live web. Returns numbered sources with URLs; the first `read` include page text."""
    body = {"q": query, "max_results": 5, "read": max(0, min(read, 10)), "max_chars": 5000}
    resp = requests.post(API, headers=HEADERS, json=body, timeout=60)
    resp.raise_for_status()
    parts = []
    for i, r in enumerate(resp.json()["results"], start=1):
        text = r["content"] if r["content_status"] == "ok" else "(snippet only) " + r["snippet"]
        parts.append(f"[{i}] {r['title']} - {r['url']}\n{text}")
    return "\n\n".join(parts)


print(search_web.invoke({"query": "postgres connection pool size"})[:500])

```

## จะใช้เว็บแบบเรียลไทม์เป็น retriever ได้อย่างไร?

สร้าง subclass ของ `BaseRetriever` และคืน `Document` หนึ่งรายการต่อหน้าที่อ่าน ข้อความของหน้าจะอยู่ใน `page_content` ส่วน URL, title, rank และวันที่อยู่ใน `metadata` ซึ่ง chain ที่อ้างอิงแหล่งที่มาจะค้นหาข้อมูลเหล่านี้ ผลลัพธ์ที่ไม่มีเนื้อหาจะถูกข้าม เพราะ retriever ควรส่งข้อความที่โมเดลนำไปอ้างอิงได้

retriever ทำงานทุกคำถาม เหมาะกับ chain ตอบคำถามเกี่ยวกับหัวข้อปัจจุบัน แต่สิ้นเปลืองในแชตที่ส่วนใหญ่ไม่ต้องค้นหา ในกรณีนั้นให้ใช้ tool

*LangChain retriever: LLMWebSearchRetriever*

```python
import os
from typing import List

import requests
from langchain_core.callbacks import CallbackManagerForRetrieverRun
from langchain_core.documents import Document
from langchain_core.retrievers import BaseRetriever


class LLMWebSearchRetriever(BaseRetriever):
    """Live web search results as Documents, one per page that was read."""

    max_results: int = 5
    read: int = 3
    max_chars: int = 6000

    def _get_relevant_documents(self, query: str, *, run_manager: CallbackManagerForRetrieverRun) -> List[Document]:
        resp = requests.post(
            "https://llmwebsearch.com/api/v1/search",
            headers={"Authorization": "Bearer " + os.environ["LLMWEBSEARCH_API_KEY"]},
            json={"q": query, "max_results": self.max_results, "read": self.read, "max_chars": self.max_chars},
            timeout=60,
        )
        resp.raise_for_status()
        docs = []
        for r in resp.json()["results"]:
            if r["content_status"] != "ok":
                continue
            meta = {"source": r["url"], "title": r["title"], "position": r["position"], "published_at": r.get("published_at")}
            docs.append(Document(page_content=r["content"], metadata=meta))
        return docs


retriever = LLMWebSearchRetriever(read=3)
for doc in retriever.invoke("pgbouncer transaction mode limitations"):
    print(doc.metadata["position"], doc.metadata["source"], len(doc.page_content))

```

## จะให้การค้นหาเดียวกันกับ agent ของ LlamaIndex ได้อย่างไร?

เขียนฟังก์ชันธรรมดาแล้วห่อด้วย `FunctionTool.from_defaults` จาก `llama_index.core.tools` LlamaIndex จะสร้างชื่อและคำอธิบายของ tool จากชื่อฟังก์ชัน signature และ docstring การเรียก tool จะคืน `ToolOutput` ที่มี `content` เป็นข้อความที่ agent จะอ่าน

ฟังก์ชันนี้เหมือนกับของ LangChain ทีมที่ใช้ทั้งสองเฟรมเวิร์กจึงแชร์ฟังก์ชันนี้ได้

*LlamaIndex: FunctionTool*

```python
import os

import requests
from llama_index.core.tools import FunctionTool


def search_web(query: str, read: int = 3) -> str:
    """Search the live web and return numbered sources; the first `read` include their page text."""
    resp = requests.post(
        "https://llmwebsearch.com/api/v1/search",
        headers={"Authorization": "Bearer " + os.environ["LLMWEBSEARCH_API_KEY"]},
        json={"q": query, "max_results": 5, "read": max(0, min(read, 10)), "max_chars": 5000},
        timeout=60,
    )
    resp.raise_for_status()
    parts = []
    for i, r in enumerate(resp.json()["results"], start=1):
        text = r["content"] if r["content_status"] == "ok" else "(snippet only) " + r["snippet"]
        parts.append(f"[{i}] {r['title']} - {r['url']}\n{text}")
    return "\n\n".join(parts)


search_tool = FunctionTool.from_defaults(fn=search_web)
print(search_tool.metadata.name)
print(search_tool.call(query="postgres connection pool size").content[:300])

```

## ฉันจะควบคุม context window ได้อย่างไร?

ตั้งค่า `max_chars` ตอนเรียก API แทนที่จะมาตัดทีหลัง: ข้อมูลที่ส่งไปน้อยกว่า และ framework จะไม่ถือเวอร์ชันยาวไว้เลย 5,000 ตัวอักษรต่อหน้าและ 3 หน้า คิดเป็นประมาณ 4,000 tokens ซึ่งสบายสำหรับโมเดลส่วนใหญ่

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

## ฉันเก็บสิ่งที่ retriever ส่งคืนไว้ใน vector database ได้ไหม?

ได้ เท่าที่เราเกี่ยวข้องนะ เราไม่ฝึกโมเดลใดๆ ด้วยคำค้นหาของคุณหรือข้อมูลที่ API ส่งกลับ และเราไม่เพิ่มกฎของเราเองต่อต้านการจัดเก็บผลลัพธ์; สิทธิ์ของเว็บไซต์ที่คุณอ่านหน้ายังคงมีผล เก็บ URL และ `published_at` ไว้กับทุก chunk เพื่อให้ agent อ้างอิงหน้าเว็บได้ และคุณลบ chunk ที่เก่าเกินไปได้

ทีมส่วนใหญ่แคชผลการค้นหาเว็บของคำถามที่ถามบ่อยไว้หนึ่งวันหรือหนึ่งสัปดาห์ ช่วยลดการค้นหาซ้ำ และทุกการค้นหาที่เลี่ยงได้คือเครดิตที่ประหยัด

## LangChain และ LlamaIndex: คำถามที่พบบ่อย

### มีแพ็กเกจ langchain-llmwebsearch ไหม?

ไม่มี เราไม่ได้เผยแพร่แพ็กเกจใดๆ โค้ดในหน้านี้สั้นพอที่จะเป็นของคุณเอง: คัดลอกไป เปลี่ยนค่า default และเก็บไว้ใน repository ของคุณ

### ฉันทำให้ tool เป็น async ได้ไหม?

ได้ แทนที่ `requests` ด้วย `httpx.AsyncClient` และนิยามฟังก์ชันด้วย `async def` decorator `@tool` ของ LangChain ใช้กับฟังก์ชัน async ได้โดยตรง ส่วนใน LlamaIndex ให้ส่งเวอร์ชัน async ไปยัง `FunctionTool.from_defaults` เป็น `async_fn`

### ฉันจะอ่านหน้าเว็บที่ agent เจอมาจากที่อื่นได้อย่างไร?

เพิ่ม tool ที่สองที่ส่ง URL ไปยัง `https://llmwebsearch.com/api/v1/extract` การอ่านหน้าเว็บที่คุณมี URL อยู่แล้วใช้ 1 เครดิตต่อกลุ่ม 3 หน้าที่เริ่มอ่านและส่งกลับพร้อมเนื้อหา สูงสุด 20 URL ต่อการเรียก; URL ที่ถูกปฏิเสธหรือล้มเหลวไม่ถูกนับ [เอกสารอ้างอิง extract](https://llmwebsearch.com/th/docs/extract/) แสดงตัวอย่าง request

---

LLMWebSearch: LLMWebSearch คือ web search API สำหรับ AI agents ที่คืนผลการค้นหาที่จัดอันดับแล้วพร้อมเนื้อหาของหน้าอันดับต้นๆ ในรูปแบบ Markdown จ่ายด้วยคริปโตโดยไม่ต้องอัปโหลดเอกสารยืนยันตัวตน เครดิตแบบเติมล่วงหน้าตั้งแต่ US$1.20/1K การค้นหา ไม่มีวันหมดอายุ ไม่ต้อง KYC — ไม่ต้องใช้บัตรประชาชน ไม่ต้องเซลฟี่ ไม่ต้องใช้เอกสาร จ่ายด้วยคริปโต
