چتبات مستندات
پاسخ به پرسشها دربارهٔ مستندات محصول خودتان، با ارجاع به همان صفحه.
پاسخ به پرسشها دربارهٔ مستندات محصول خودتان، با پانویسهایی که به همان صفحه و همان موقعیتی لینک میدهند که پاسخ از آن آمده است.
معماری
ساختارش مثل مرکز راهنماست — یک فضای کاری مشترک، با پراکسی از سرور خودتان — اما بهجای citations از response.parts استفاده میکند، چون پاسخ مستندات با پانویس جملهبهجمله بهتر خوانده میشود تا با فهرستی در انتها.
- هر صفحهٔ مستندات را بهعنوان سندی جدا بارگذاری کنید، با عنوانی که slug آن است.
- از مسیر خودتان بپرسید و شناسهٔ بازدیدکنندهای را که از قبل دارید بفرستید.
- منبع هر part را با کمک عنوان و metadata دوباره به یک نشانی تبدیل کنید.
راهاندازی
slug خودتان را در عنوان سند نگه دارید. تنها فیلدی است که تا داخل ارجاع دوام میآورد، پس همان چیزی است که میگذارد بدون جستوجوی دوم لینک را دوباره بسازید.
کد
به فیلتر توجه کنید: بخشهایی که منبع ندارند متن معمولیاند که مدل برای وصل کردن بخشهای ارجاعدار نوشته، و نباید پانویس شوند.
const BASE = "https://api.daneshyar.info/api/v1";
const KEY = process.env.DANESHYAR_API_KEY;
const WORKSPACE = "8f14e45f-ceea-467a-9f4c-1a2b3c4d5e6f";
/**
* Answer questions about your own docs, and link each source back to the page
* it came from. The trick is keeping your own slug in the resource title, so a
* citation can be turned back into a URL without a second lookup.
*/
export async function answerDocsQuestion({ visitorId, question }) {
const res = await fetch(`${BASE}/workspaces/${WORKSPACE}/chat/`, {
method: "POST",
headers: { "X-API-Key": KEY, "Content-Type": "application/json" },
body: JSON.stringify({
external_user_id: visitorId,
message: question,
}),
});
const { data } = await res.json();
const reply = data.assistant_message;
// response.parts attaches each source to the span it supports — use it when
// you want footnotes rather than a flat list under the answer.
const footnotes = reply.response.parts
.filter((part) => part.source)
.map((part) => ({
text: part.text,
title: part.source.resource_title,
// metadata carries the position: page for a PDF, start_time for audio.
page: part.source.metadata?.page ?? null,
href: `/docs/${slugFromTitle(part.source.resource_title)}`,
}));
return { answer: reply.content, footnotes };
}
function slugFromTitle(title) {
return title.replace(/\.[^.]+$/, "").toLowerCase().replace(/\s+/g, "-");
}نتیجه
خوانندهها پاسخی میگیرند که هر ادعایش لینکی به همان صفحه و موقعیت پشتش دارد — و همین است تفاوت چتباتی که مردم به آن اعتماد میکنند با چتباتی که جای دیگری دوباره بررسیاش میکنند.