ไม่ต้อง KYC — ไม่ต้องใช้บัตรประชาชน ไม่ต้องเซลฟี่ ไม่ต้องใช้เอกสาร จ่ายด้วยคริปโต: BTC, USDT, USDC, ETH, SOL, LTC
ภาษา: ไทย
รับ API key

เอกสาร · LangChain · LlamaIndex

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

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

อัปเดตล่าสุด: · 3 นาทีในการอ่าน

คำตอบสั้น

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

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

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

LangChain toolagent จะเรียก search_web เมื่อเห็นว่าตนต้องการเว็บ
LangChain retrieverchain จะดึงเอกสารใหม่สำหรับทุกคำถามโดยไม่ต้องสั่ง
LlamaIndex FunctionToolฟังก์ชัน search_web เดียวกัน สำหรับ agent ของ LlamaIndex
แพ็กเกจlangchain-core หรือ llama-index-core พร้อม requests
KeyLLMWEBSEARCH_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
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
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
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 แสดงตัวอย่าง request

เริ่มต้นที่ US$1.20/1K การค้นหา · ไม่ต้อง KYC

รับ API key