Jawaban singkat
Bagaimana cara memanggil web search API untuk AI agents dari Node.js?
Gunakan fetch bawaan Node 18+ untuk POST kueri Anda ke https://llmwebsearch.com/api/v1/search dengan key Bearer. LLMWebSearch menjawab dengan hasil berperingkat dan 3 halaman teratas sebagai Markdown, siap diberi nomor dan diteruskan ke model untuk jawaban bersitasi. Satu pencarian memakai 1 kredit, mulai dari US$1,20/1K pencarian per Oktober 2026. Tidak perlu package npm. Tanpa KYC; bayar dengan kripto.
Yang Anda butuhkan
| Node.js | 18 atau lebih baru, untuk fetch bawaan; simpan skrip sebagai .mjs untuk await tingkat atas |
|---|---|
| Paket | Tidak ada |
| Key | LLMWEBSEARCH_API_KEY di environment Anda |
| Untuk loop jawaban | Endpoint chat yang kompatibel dengan OpenAI: LLM_BASE_URL, LLM_API_KEY, LLM_MODEL |
| Penagihan | Satu kredit membayar satu pencarian: hingga 20 hasil berperingkat, dengan halaman dari 3 hasil teratas dibaca dan dikembalikan sebagai Markdown. Membaca 4 hingga 10 halaman menjadi 2 kredit. Panggilan yang berakhir dengan error tidak dikenakan biaya |
Bagaimana cara menulis fungsi pencarian yang dapat digunakan ulang?
Bungkus panggilan sekali dan gunakan ulang di mana saja. Fungsi di bawah mengirim body, melempar error yang mudah dibaca pada setiap kegagalan HTTP, dan mengembalikan JSON yang telah di-parse. Error membawa code milik API itu sendiri, seperti rate_limited atau insufficient_credits, sehingga pemanggil dapat memutuskan apa yang harus dilakukan.
const API = 'https://llmwebsearch.com/api/v1/search';
export async function search(body) {
const res = await fetch(API, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.LLMWEBSEARCH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
const data = await res.json();
if (!res.ok) {
const err = new Error(`${res.status} ${data.error?.code}: ${data.error?.message}`);
err.status = res.status;
throw err;
}
return data;
}
const data = await search({ q: 'how to size a postgres connection pool', read: 3 });
for (const r of data.results) {
console.log(r.position, r.content_status, r.url, r.word_count ?? '');
}
Bagaimana cara menjalankan beberapa pencarian tanpa kena rate limit?
Jalankan lewat pool kecil: sejumlah worker tetap yang masing-masing mengambil kueri berikutnya dari daftar bersama. Empat worker adalah titik awal yang masuk akal. Setiap akun memiliki batas panggilan per menit yang ditampilkan di dashboard; hubungi support dan batas itu bisa dinaikkan.
Pool di bawah ini tidak butuh library. Setiap worker menyimpan hasilnya sendiri, dan pencarian yang gagal dicatat beserta error-nya alih-alih menghentikan proses. Itu penting untuk agen riset, di mana satu sub-pertanyaan yang buruk tidak boleh mengorbankan seluruh tugas.
const API = 'https://llmwebsearch.com/api/v1/search';
const questions = [
'what is connection pooling in postgres',
'recommended pool size per cpu core',
'pgbouncer transaction mode limitations',
'connection pool exhaustion symptoms',
'pool size for serverless functions',
];
async function search(q) {
const res = await fetch(API, {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.LLMWEBSEARCH_API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ q, read: 2, max_chars: 4000 }),
});
const data = await res.json();
if (!res.ok) return { q, error: data.error?.code ?? String(res.status) };
return { q, urls: data.results.filter((r) => r.content_status === 'ok').map((r) => r.url) };
}
async function runPool(items, size, task) {
const out = [];
let next = 0;
const worker = async () => {
while (next < items.length) {
const i = next++;
out[i] = await task(items[i]);
}
};
await Promise.all(Array.from({ length: size }, worker));
return out;
}
for (const row of await runPool(questions, 4, search)) console.log(row);
Bagaimana cara mengubah hasil menjadi jawaban dengan sitasi?
Beri nomor pada sumber, letakkan URL di samping masing-masing, pangkas sesuai anggaran, dan minta model mengutip berdasarkan nomor. API mengembalikan sumber, bukan jawaban tertulis: model Anda sendiri yang membaca halaman, menulis balasan, dan mengutip URL-nya. Skrip di bawah ini berbicara ke endpoint chat/completions apa pun yang kompatibel dengan OpenAI, dipilih lewat tiga environment variable, sehingga berfungsi baik dengan model hosted maupun lokal.
Anggaran sekitar 24.000 karakter, kira-kira 6.000 token, dibagi rata di antara sumber-sumber. Hasil yang halamannya tidak dapat dibaca dikirim sebagai snippet-nya, dengan penanda demikian.
const SEARCH = 'https://llmwebsearch.com/api/v1/search';
const BUDGET = 24000; // characters, about 6,000 tokens
async function sources(question) {
const res = await fetch(SEARCH, {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.LLMWEBSEARCH_API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ q: question, max_results: 5, read: 3 }),
});
const { results } = await res.json();
const share = Math.floor(BUDGET / Math.max(results.length, 1));
return results
.map((r, i) => {
const body = r.content_status === 'ok' ? r.content.slice(0, share) : `(snippet only) ${r.snippet}`;
return `[${i + 1}] ${r.title} - ${r.url}\n${body}`;
})
.join('\n\n');
}
async function answer(question) {
const prompt = 'Answer using only the sources below. Cite them as [1], [2] and so on. '
+ 'Say so if they do not answer the question.\n\n' + (await sources(question)) + '\n\nQuestion: ' + question;
const res = await fetch(`${process.env.LLM_BASE_URL.replace(/\/$/, '')}/chat/completions`, {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.LLM_API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ model: process.env.LLM_MODEL, messages: [{ role: 'user', content: prompt }] }),
});
const data = await res.json();
return data.choices[0].message.content;
}
console.log(await answer('How should I size a Postgres connection pool?'));
Sebaiknya saya pakai GET atau POST dari Node?
POST, dengan body JSON, di kode aplikasi. Array seperti include_domains dan pertanyaan panjang lebih rapi dikirim lewat body daripada query string. GET tersedia untuk uji cepat dan untuk alat yang tidak bisa mengirim body; bangun query string-nya dengan URLSearchParams dan gabungkan daftar dengan koma.
Kedua bentuk berbiaya sama dan mengembalikan JSON yang sama. Referensi pencarian mencantumkan setiap parameter untuk keduanya.
Di mana sebaiknya API key disimpan?
Di environment variable yang dibaca saat runtime, jangan pernah di file sumber. Di server, gunakan secret store platform Anda. Di browser, jangan panggil API sama sekali: API key akan terlihat oleh setiap pengunjung. Panggil backend Anda sendiri, yang kemudian memanggil LLMWebSearch.
Buat satu API key per agen, aplikasi, atau rekan tim dan cabut salah satunya dari dashboard tanpa mengganggu yang lain. Satu API key per layanan membuat riwayat dashboard lebih mudah dibaca, dan API key yang bocor mudah dicabut.
Node.js: pertanyaan umum
Apakah ada paket npm?
Tidak. fetch sudah built-in di Node 18 dan yang lebih baru, dan API-nya adalah JSON biasa lewat HTTPS. Fungsi-fungsi di halaman ini adalah keseluruhan integrasinya.
Apakah berfungsi di Deno, Bun, atau edge runtime?
Kode ini hanya memakai fetch, JSON, dan process.env. Runtime dengan fetch berfungsi setelah mengganti process.env dengan cara mereka sendiri untuk membaca secret.
Bagaimana cara mengulang panggilan yang gagal?
Ulangi hanya 429, 502, dan 504, dengan jeda yang berlipat dua setiap kali. Jangan pernah mengulang 400, 401, atau 402. Halaman error menjelaskan alasannya dan menunjukkan helper.