การดำเนินผลิตภัณฑ์แชทบอทผู้ใหญ่อย่างรับผิดชอบ: รายการตรวจสอบสำหรับผู้สร้าง
แชทบอทผู้ใหญ่เป็นผลิตภัณฑ์จริง และผลิตภัณฑ์จริงมีความรับผิดชอบ API มอบโมเดลที่ไม่ปฏิเสธเนื้อหาผู้ใหญ่ที่ถูกต้องตามกฎหมาย ซึ่งหมายความว่าแอปของคุณไม่ใช่โมเดล คือจุดที่มีการตรวจสอบอายุ กฎบ้าน การรายงาน และการควบคุมการละเมิด รายการตรวจสอบนี้จะอธิบายแต่ละชั้นพร้อมโค้ดที่ใช้งานได้ เพื่อให้คุณเปิดตัวได้อย่างมั่นใจ
อัปเดต
ประเด็นสำคัญ
- แพลตฟอร์มมีสำหรับผู้ใหญ่เท่านั้น; ตรวจสอบอายุที่ประตูของคุณและเก็บการตรวจสอบไว้ที่เซิร์ฟเวอร์
- เขียนนโยบายเนื้อหาของคุณเองและเส้นทางรายงาน เพราะความเปิดกว้างของโมเดลไม่ได้แทนที่กฎของคุณ
- เนื้อหาทางเพศที่เกี่ยวข้องกับผู้เยาว์จะถูกบล็อกด้วย 403 เสมอ; ออกแบบ UX ที่ชัดเจนและสงบสำหรับเรื่องนี้
- จำกัดการใช้งานต่อผู้ใช้และเก็บคีย์ API บนเซิร์ฟเวอร์ของคุณ; คีย์หนึ่งถูกใช้ร่วมกันสำหรับการใช้งานทั้งหมดของคุณ
ใครรับผิดชอบอะไร
คิดเกี่ยวกับสแต็กเป็นสองชั้น API จัดหาเนื้อหาผู้ใหญ่ กฎหมาย นิยาย และหัวข้อที่ถกเถียงได้โดยไม่ปฏิเสธ สำหรับผู้ใช้อายุ 18 ปีขึ้นไป ทุกอย่างรอบโมเดล บุคคลที่เข้าถึงได้ กฎที่พวกเขาตกลง และสิ่งที่เกิดขึ้นเมื่อมีข้อผิดพลาด เป็นของคุณ การแยกนี้ทำให้เป็นอิสระ แต่เฉพาะเมื่อคุณรับผิดชอบส่วนของคุณอย่างจริงจัง
นี่คือตารางความรับผิดชอบสั้นๆ ที่ควรวางไว้บนผนัง
| ข้อกังวล | แพลตฟอร์ม | แอปของคุณ |
|---|---|---|
| เนื้อหาทางเพศที่เกี่ยวข้องกับเด็ก | บล็อกเสมอ (403) | อธิบาย จบฉาก ป้องกันการใช้ช่องโหว่ |
| อายุของผู้ใช้ของคุณ | ผู้ใหญ่เท่านั้นตามข้อกำหนด | กำหนดอายุและตรวจสอบที่ทางเข้าของคุณ |
| กฎระเบียบภายในที่เกินกว่ากฎหมาย | ไม่ได้ใช้ | เขียน เผยแพร่ และบังคับใช้ |
| การละเมิดต่อผู้ใช้ | 300 คำขอต่อนาทีต่อคีย์ | ขีดจำกัดต่อผู้ใช้และรายวัน |
| คีย์ลับ | ออกให้ | เก็บไว้ที่เซิร์ฟเวอร์ของคุณ |
นี่คือคำแนะนำด้านวิศวกรรม ไม่ใช่คำแนะนำทางกฎหมาย; กฎแตกต่างกันไปตามสถานที่ ดังนั้นตรวจสอบข้อกำหนดในพื้นที่ที่ผู้ใช้ของคุณอาศัยอยู่
การจำกัดอายุที่จำกัดจริงๆ
แบนเนอร์ที่มีปุ่ม "ฉันอายุ 18 ปี" เป็นขั้นต่ำ และผู้เยาว์ที่มุ่งมั่นสามารถคลิกได้ มันยังสำคัญ เพราะบันทึกคำกล่าวที่ยืนยันและทำให้นโยบายของคุณตรงไปตรงมา คีย์คือจุดที่คุณบังคับใช้ หากการตรวจสอบเพียงซ่อนแชทในเบราว์เซอร์ ทุกคนสามารถเรียกใช้ endpoint ของคุณโดยตรงได้ ทำให้เซิร์ฟเวอร์ปฏิเสธที่จะพูดจนกว่าจะมีเครื่องหมายที่ลงนามแล้ว
import crypto from "node:crypto";
// Minimal 18+ gate: the user must confirm before the chat routes work.
// Replace the confirmation with a real verification step when your market requires it.
const SECRET = process.env.GATE_SECRET; // random string kept on the server
function sign(value) {
return crypto.createHmac("sha256", SECRET).update(value).digest("hex");
}
export function issueAdultCookie(res, userId) {
const stamp = String(Date.now());
const payload = `${userId}.${stamp}`;
res.cookie("adult_ok", `${payload}.${sign(payload)}`, {
httpOnly: true, sameSite: "strict", secure: true, maxAge: 30 * 24 * 3600 * 1000,
});
}
export function requireAdult(req, res, next) {
const raw = req.cookies?.adult_ok || "";
const [userId, stamp, sig] = raw.split(".");
if (!sig || sign(`${userId}.${stamp}`) !== sig) {
return res.status(403).json({ state: "age_required" });
}
req.userId = userId;
next();
}เชื่อมต่อ requireAdult หน้าเส้นทางแชททุกเส้นทาง เพิ่มการยืนยันที่เข้มงวดขึ้นเมื่อตลาดหรือระดับความเสี่ยงของคุณกำหนด เช่น การตรวจสอบอายุโดยบุคคลที่สาม และเก็บเครื่องหมายให้สั้นพอที่คุณจะส่งพรอมต์ใหม่ได้ อย่ากำหนดเป้าหมายนักเรียนหรือโรงเรียนในการตลาดของคุณ และวางประตูก่อนแสดงเนื้อหาผู้ใหญ่ใดๆ รวมถึงตัวอย่างและตัวอย่างการสนทนา
การเขียนนโยบายเนื้อหาของคุณเอง
โมเดลไม่ปฏิเสธเนื้อหาผู้ใหญ่ที่ถูกต้องตามกฎหมาย ดังนั้นคุณจึงตัดสินใจว่าผลิตภัณฑ์ของคุณอนุญาตอะไร นโยบายหนึ่งหน้าก็เพียงพอแล้ว ครอบคลุมเนื้อหาที่อนุญาต สิ่งที่ห้ามในชุมชนของคุณแม้ว่าจะถูกต้องตามกฎหมาย (เช่น การกลั่นแกล้งบุคคลจริงหรือการเปิดเผยข้อมูลส่วนตัว) วิธีการที่ผู้ใช้สามารถรายงานปัญหา และมาตรการที่คุณดำเนินการ: คำเตือน การระงับชั่วคราว การแบน
- เผยแพร่ เมื่อผู้ใช้สมัครสมาชิก เป็นภาษาที่เข้าใจง่าย
- คัดลอกในพรอมต์ระบบของคุณ บรรทัดเช่น "ตัวละครทั้งหมดเป็นผู้ใหญ่; จบฉากใดๆ ที่กลายเป็นไม่ยินยอมหรือเกี่ยวข้องกับบุคคลจริงที่มีชื่อ" ทำให้บอทสอดคล้องกับกฎของคุณ
- ทำให้การบังคับใช้เป็นเรื่องน่าเบื่อ ตัดสินเกณฑ์ล่วงหน้าเพื่อให้ผู้ตรวจสอบไม่ตัดสินใจเอง
- ทบทวนนโยบาย ทุกไตรมาสเมื่อผลิตภัณฑ์ของคุณพัฒนา
เส้นทางรายงานที่ผู้ใช้สามารถค้นหาได้
ให้การรายงานข้อความแต่ละรายการด้วยปุ่มควบคุมเล็กๆ และทำให้มันทำงานได้โดยไม่ต้องเข้าสู่ระบบ เมื่อมีคนรายงานคำตอบ ให้บันทึกสิ่งขั้นต่ำที่คุณต้องการเพื่อดำเนินการ: รหัสผู้ใช้ รหัสข้อความ เหตุผลสั้นๆ และเวลา จัดเส้นทางไปยังคิวที่ผู้ตรวจสอบของคุณเฝ้าดู
app.post("/api/report", requireAdult, express.json(), (req, res) => {
const { messageId, reason } = req.body;
// Store only what you need to act on: who, which message, why, when.
queueForModerator({ userId: req.userId, messageId, reason: String(reason).slice(0, 500), at: Date.now() });
res.json({ ok: true });
});รักษาคำสัญญาของคุณให้แคบ บอกผู้ใช้ให้ชัดเจนว่าการรายงานจะกระตุ้นอะไร และเก็บเฉพาะสิ่งที่นโยบายของคุณและกฎที่เกี่ยวข้องต้องการ ทบทวนว่าคุณเก็บรายงานนานแค่ไหน และลบตามกำหนดเวลา ยอมรับรายงานแต่ละรายการแก่บุคคลที่ยื่นมัน แม้ด้วยข้อความขอบคุณหนึ่งบรรทัด เพราะผู้ใช้จะหยุดรายงานเมื่อดูเหมือนว่าไม่มีอะไรเกิดขึ้น ติดตามว่าผู้ตรวจสอบของคุณปิดรายการได้เร็วเพียงใด และกำหนดเป้าหมายที่คุณสามารถทำได้จริง
การออกแบบสำหรับการบล็อกผู้เยาว์ 403
เนื้อหาทางเพศที่เกี่ยวข้องกับเด็กถูกบล็อกเสมอ ทั้งในนิยายและบทบาทสมมติ และ API ตอบกลับด้วย 403 และโค้ด content_blocked อย่าลองใหม่และอย่าพยายามเขียนใหม่แทนผู้ใช้ แทนที่จะจัดการเป็นช่วงเวลาผลิตภัณฑ์ที่ต้องมีการออกแบบที่ชัดเจน
- แปลที่เซิร์ฟเวอร์ เป็นสถานะที่ UI ของคุณรู้จัก เพื่อให้ข้อความต้นทางดิบไม่ปรากฏบนหน้าจอ
- บอกสิ่งที่เกิดขึ้น ด้วยประโยคสงบหนึ่งประโยคและระบุกฎ
- จบหรือรีเซ็ตฉาก การเสนอ "ดำเนินการต่อ" ขัดแย้งกับจุดประสงค์
- บันทึกเหตุการณ์ ด้วยรหัสผู้ใช้เพื่อให้การพยายามซ้ำสามารถกระตุ้นการบังคับใช้ของคุณเองได้
- อย่าคาดเดาเจตนา การบล็อกบางรายการมาจากถ้อยคำที่คลุมเครือ; ข้อความที่เป็นกลางใช้ได้กับทั้งสองกรณี
// server: translate upstream outcomes into states your UI understands
if (upstream.status === 403) {
return res.status(403).json({
state: "content_blocked",
message: "That request breaks our rules, so we can't continue this scene.",
});
}
if (upstream.status === 402) return res.status(503).json({ state: "paused" });
if (upstream.status === 503) return res.status(503).json({ state: "busy" });// browser: show a calm, specific message for each state
const MESSAGES = {
content_blocked: "This scene can't continue. Sexual content involving minors is never allowed. Start a new chat any time.",
age_required: "Please confirm you are 18 or older to use the chat.",
slow_down: "You're sending messages quickly. Give it a few seconds.",
daily_limit: "You've reached today's message allowance. Come back tomorrow.",
paused: "Chat is briefly unavailable. We're on it.",
busy: "The service is busy. Try again in a moment.",
};
async function send(messages) {
const res = await fetch("/api/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ messages }),
});
if (!res.ok) {
const info = await res.json().catch(() => ({}));
showBanner(MESSAGES[info.state] || "Something went wrong.");
if (info.state === "content_blocked") endCurrentScene();
return null;
}
return res;
}
การควบคุมการละเมิดและอัตราต่อผู้ใช้
คีย์ API เดียวของคุณอนุญาตให้ทำ 300 คำขอต่อนาที โดยรวม แบ่งปันโดยผู้ใช้ทั้งหมด บัญชีสคริปต์หนึ่งอาจทำให้ผู้ใช้คนอื่นหมดสิทธิ์ ดังนั้นบังคับใช้ขีดจำกัดการใช้งานที่เป็นธรรมเอง ต่ำกว่าเพดานนั้นมาก ตัวอย่างจำกัดผู้ใช้แต่ละรายที่ 12 ข้อความต่อนาทีและให้งบประมาณโทเคนรายวันวัดจากตัวเลข usage ในส่วนสตรีมสุดท้าย
const WINDOW_MS = 60_000;
const PER_USER_PER_MIN = 12; // your product rule, far below the key's 300
const DAILY_TOKEN_BUDGET = 60_000; // per user, tracked from the usage chunk
const hits = new Map(); // userId -> array of timestamps
const spent = new Map(); // userId -> tokens used today
export function userLimit(req, res, next) {
const now = Date.now();
const recent = (hits.get(req.userId) || []).filter((t) => now - t < WINDOW_MS);
if (recent.length >= PER_USER_PER_MIN) {
return res.status(429).json({ state: "slow_down" });
}
if ((spent.get(req.userId) || 0) >= DAILY_TOKEN_BUDGET) {
return res.status(429).json({ state: "daily_limit" });
}
recent.push(now);
hits.set(req.userId, recent);
next();
}
export function recordUsage(userId, totalTokens) {
spent.set(userId, (spent.get(userId) || 0) + totalTokens);
}สำหรับการผลิต เก็บตัวนับในที่เก็บที่แชร์แทนหน่วยความจำกระบวนการเพื่อให้ขีดจำกัดอยู่รอดเมื่อเริ่มใหม่และทำงานข้ามเซิร์ฟเวอร์หลายเครื่อง เพิ่ม max_tokens ที่สมเหตุสมผลในทุกคำขอเพื่อจำกัดกรณีเลวร้ายที่สุด และเฝ้าระวัง 402 บนยอดเงินของคุณ การทดลองใช้ฟรี $0.50 เป็นเวลา 7 วันเป็นวิธีที่ดีในการทดสอบการควบคุมเหล่านี้ก่อนปริมาณการใช้งานจริงจะมาถึง
เก็บคีย์ไว้บนเซิร์ฟเวอร์
อย่าส่งคีย์ในแพ็กเกจหน้าเว็บ แอปมือถือ หรือที่เก็บสาธารณะ เก็บเป็นตัวแปรสภาพแวดล้อมหรือในตัวจัดการความลับ โหลดเฉพาะในแบ็กเอนด์ของคุณและยกเว้นจากบันทึกและรายงานข้อผิดพลาด หากคุณสงสัยว่ามีการเปิดเผย ให้สร้างคีย์ใหม่จากบัญชีของคุณ; คีย์เก่าจะหยุดทำงานทันที ดังนั้นให้พร้อมสำหรับการปรับใช้ คู่มือเว็บแชท แสดงรูปแบบตั้งแต่ต้นจนจบ และเอกสาร ระบุรหัสข้อผิดพลาดที่ wrapper ของคุณควรแมป
รายการตรวจสอบก่อนเปิดใช้งาน
ตรวจสอบรายการนี้ในวันก่อนที่คุณจะเปิดให้บริการ แต่ละรายการใช้เวลาเพียงไม่กี่นาทีและป้องกันปัญหาประเภทหนึ่งที่แก้ไขยากหลังจากผู้ใช้เข้ามาแล้ว
- พยายามทำลายประตู เรียกเส้นทางแชทของคุณด้วย curl โดยไม่มีคุกกี้ มันต้องตอบกลับ 403 ด้วย
age_requiredไม่ใช่การตอบกลับของโมเดล - กระตุ้นทุกสถานะ จำลองแหล่งที่มาให้ส่ง 402, 403, 429 และ 503 ตามลำดับ และยืนยันว่าแต่ละรายการแสดงแบนเนอร์ที่ถูกต้องและไม่เปิดเผยข้อความข้อผิดพลาดดิบ
- อ่านนโยบายของคุณดังๆ หากผู้ตรวจสอบไม่สามารถตัดสินคดีจากมันได้ในหนึ่งนาที ให้ปรับข้อความให้กระชับขึ้น
- ทดสอบปุ่มรายงาน จากหน้าจอโทรศัพท์ การควบคุมที่เข้าถึงยากไม่นับเป็นช่องทางรายงาน
- ค้นหาที่เก็บข้อมูลของคุณสำหรับคีย์ ดูในโฟลเดอร์หน้าเว็บ ผลการสร้าง การกำหนดค่าตัวอย่างและประวัติการคอมมิต สร้างคีย์ใหม่หากคุณพบบทใดที่สาธารณะ
- ตั้งค่าการแจ้งเตือน แจ้งเตือนคุณเมื่อเกิด 402 เมื่อมีบล็อก 403 จากผู้ใช้รายเดียวและเมื่อมีการเพิ่มขึ้นของการใช้งานโทเคนรายวัน
- เตรียมสวิตช์หยุดชั่วคราว แฟล็กเดียวที่ปิดแชทอย่างสุภาพมีค่ามากในช่วงเหตุการณ์
ความปลอดภัยไม่เคยเสร็จสิ้น และรายการก็เช่นกัน; เพิ่มรายการทุกครั้งที่มีเหตุการณ์สอนสิ่งใหม่ให้คุณ และแชร์กับทุกคนที่เข้าร่วมทีมของคุณในภายหลัง ทบทวนรายการเมื่อเพิ่มฟีเจอร์เช่น การอัปโหลดรูปภาพใน UI ของคุณ ห้องกลุ่มหรือการแบ่งปันตัวละครสาธารณะ เพราะแต่ละอย่างเปิดเส้นทางใหม่สำหรับการใช้งานผิดวัตถุประสงค์ สำหรับความช่วยเหลือในการกำหนดตัวละครเอง อ่าน คู่มือการออกแบบบุคลิก และเก็บพื้นฐานของการเชื่อมต่อของคุณใน เอกสาร ให้พร้อมใช้งานเมื่อทีมของคุณเติบโต
ถาม-ตอบ
กล่องกาเครื่องหมายเพียงพอสำหรับการยืนยันอายุหรือไม่?
เป็นข้อกำหนดขั้นต่ำและบันทึกข้อเท็จจริง แต่สามารถข้ามได้ง่าย บังคับใช้บนเซิร์ฟเวอร์และเพิ่มการยืนยันที่เข้มงวดขึ้นเมื่อความเสี่ยงหรือกฎท้องถิ่นกำหนด
แอปของฉันควรทำอย่างไรเมื่อได้รับสถานะ 403 content_blocked?
อย่าลองใหม่ แปลงเป็นข้อความในแอปที่สงบ จบหรือรีเซ็ตฉากและบันทึกเหตุการณ์สำหรับการบังคับใช้ของคุณเอง
ฉันอนุญาตให้ผู้ใช้แบ่งปันความจุของคีย์ API ของฉันได้อย่างยุติธรรมหรือไม่?
ใช่ โดยเพิ่มขีดจำกัดอัตราและขีดจำกัดโทเคนรายวันบนเซิร์ฟเวอร์ของคุณ คีย์เองมีขีดจำกัดรวม 300 คำขอต่อนาที
โมเดลบังคับใช้กฎระเบียบภายในของฉันหรือไม่?
ไม่ มันไม่ปฏิเสธเนื้อหาผู้ใหญ่ที่ถูกต้องตามกฎหมาย ดังนั้นนโยบาย ระบบพรอมต์ และขั้นตอนการตรวจสอบของคุณต้องทำหน้าที่นี้
คีย์ของคุณอยู่ห่างแค่แบบฟอร์มเดียว
สร้างบัญชี คัดลอกคีย์ เปลี่ยน base URL นั่นคือการตั้งค่าทั้งหมด