← บทความทั้งหมด

API ของ LLM แบบไม่เซ็นเซอร์สำหรับ Red-Teaming และงานวิจัยด้านความปลอดภัย

20 ส.ค. 2026 · 3 นาทีในการอ่าน · red-teaming, security

ถ้าคุณเคยสร้าง harness สำหรับ red-teaming อัตโนมัติ คุณรู้จักโหมดล้มเหลวนี้ดีอยู่แล้ว: โมเดล attacker ของคุณปฏิเสธที่จะสร้างการโจมตี โมเดล judge ของคุณปฏิเสธที่จะอ่านเอาต์พุตที่มันควรจะให้คะแนน และอัตราความสำเร็จของการโจมตี (attack success rate) ของคุณก็ลดลงเงียบ ๆ ไม่มีอะไร error คุณไม่ได้วัดว่าเป้าหมายของคุณปลอดภัยขึ้น — คุณวัดว่าเครื่องมือของคุณระมัดระวังมากขึ้น API ของ LLM แบบไม่เซ็นเซอร์ (uncensored LLM API) มีไว้เพื่อตัดตัวแปรนั้นออกจากการวัด

นี่ไม่ใช่ข้อโต้แย้งว่า guardrail เป็นสิ่งไม่ดี แต่เป็นข้อโต้แย้งว่ามันควรอยู่ตรงไหน guardrail บนผลิตภัณฑ์แชตสำหรับผู้บริโภคกำลังทำหน้าที่ของมัน แต่ guardrail เดียวกันภายในลูปการประเมินคือตัวแปรกวน (confounder) ที่ควบคุมไม่ได้ ซึ่งนั่งขวางอยู่ระหว่างคุณกับตัวเลขที่คุณพยายามคำนวณ

การปฏิเสธคือ false negative และมันดูเหมือนความสำเร็จ

เหตุผลที่เรื่องนี้กัดแรงมากคือการปฏิเสธไม่ใช่ error คุณได้ HTTP 200 คุณได้ finish_reason: "stop" คุณได้ JSON ที่ถูกรูปแบบและ parse ได้สะอาด สตริงข้างในคือ "I can't help with that" (ฉันช่วยเรื่องนี้ไม่ได้) และ pipeline ของคุณเขียนมันลงในคอลัมน์ของ dataset ฟิลด์ label หรือส่วนหนึ่งของรายงาน แล้วเดินหน้าต่อ

พูดให้เป็นรูปธรรม ในสามที่ที่มันเจ็บที่สุด:

โมเดล attacker — ในการค้นหา jailbreak แบบวนซ้ำ — PAIR, TAP, การปรับแต่งสไตล์ GCG หรืออะไรก็ตามที่มี attacker อยู่ในลูป — การปฏิเสธจะตัดจบกิ่งนั้นของการค้นหา attack success rate ที่คุณรายงานจึงกลายเป็นฟังก์ชันของความเต็มใจของ attacker ไม่ใช่ความทนทานของเป้าหมาย สลับ attacker เป็นตัวที่ระมัดระวังน้อยกว่า แล้ว "การปรับปรุง" ที่คุณส่งมอบให้โมเดลเป้าหมายก็ระเหยไป

โมเดล judge และ grader — การให้คะแนนแบบ LLM-as-judge บนเอาต์พุตที่เป็นอันตรายต้องการให้ judge อ่านเอาต์พุตที่เป็นอันตรายนั้นจริง ๆ เมื่อมันปฏิเสธ คุณได้คะแนนที่ parse ไม่ได้ harness ส่วนใหญ่ทิ้งแถวนั้นไป แถวที่ถูกทิ้งไม่ได้หายไปแบบสุ่ม — มันกระจุกอยู่ตรงเอาต์พุตรุนแรงที่คุณจำเป็นต้องให้คะแนนมากที่สุดพอดี ผลรวมของคุณจึงเอียงไปทางปลอดภัย

งานวิเคราะห์ — ถามโมเดลกระแสหลักว่ารูทีนที่ถูก decompile ทำอะไร แล้วมันมักจะปฏิเสธเพราะมี token ที่หน้าตาเหมือนมัลแวร์ ไม่ใช่เพราะคำขอจริงของคุณ งานเป็นเชิงป้องกัน แต่ตัวจำแนกทำงานเพราะคำศัพท์ เรื่องเดียวกันกับการคัดกรอง (triage) ทราฟฟิกของ exploit ในล็อก การติด label คลังอีเมลฟิชชิงเพื่อเทรนตัวตรวจจับ หรือการเขียนรายงานสิ่งที่พบใน CTF

เพราะการปฏิเสธเงียบ ทีมจึงลงเอยด้วยการเขียนตัวตรวจจับการปฏิเสธ — ซึ่งเป็นปัญหาที่ยังไม่มีใครแก้ได้ในตัวมันเอง:

python
REFUSAL_MARKERS = ("i can't", "i cannot", "i'm unable", "i won't", "as an ai")

def looks_like_refusal(text: str) -> bool:
    """Substring heuristic. Good enough to alarm on, not good enough to trust:
    it misses polite deflections that never use the phrase, and it fires on any
    completion that quotes a refusal. Both error directions corrupt a dataset."""
    return any(m in text[:200].lower() for m in REFUSAL_MARKERS)

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

เรียกใช้ API

unbleep พูด schema ของ OpenAI Chat Completions ดังนั้น client อะไรก็ตามที่คุณมีอยู่แล้วใช้ได้ เปลี่ยน base URL เปลี่ยน key เก็บ SDK ไว้

python
import json
import os

from openai import OpenAI

client = OpenAI(
    base_url="https://unbleep.ai/v1",
    api_key=os.environ["UNBLEEP_API_KEY"],
)

TRIAGE = """You are a malware analyst writing notes for a detection engineer.
Given a decompiled routine, describe what it does, the observable artefacts it
would leave on a host, and where a defender could detect it. Reply as JSON with
keys: behaviour, artefacts, detection_surface, confidence."""


def triage(decompiled: str) -> dict:
    """One sample in, one structured verdict out — no refusal branch to handle."""
    resp = client.chat.completions.create(
        model="unbleep",
        messages=[
            {"role": "system", "content": TRIAGE},
            {"role": "user", "content": decompiled},
        ],
        response_format={"type": "json_object"},
        temperature=0.2,
    )
    return json.loads(resp.choices[0].message.content)

แบบเดียวกันผ่าน curl ในที่นี้คือการติด label คลังอีเมลฟิชชิงเพื่อสร้างข้อมูลเทรนสำหรับตัวตรวจจับ:

bash
curl https://unbleep.ai/v1/chat/completions \
  -H "Authorization: Bearer $UNBLEEP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "unbleep",
    "messages": [
      {"role": "system", "content": "Label each email for a phishing detector. Answer with one word: phishing or benign."},
      {"role": "user", "content": "Subject: Payroll update required\n\nYour direct deposit is on hold. Confirm at hxxp://payroll-verify.example.com"}
    ],
    "temperature": 0,
    "max_tokens": 4
  }'

temperature: 0 และ max_tokens ที่ตึงสำคัญกว่าปกติในลูปติด label — คุณต้องการ label ไม่ใช่ย่อหน้าที่อธิบาย label

เลือกระดับ (tier)

สามโมเดล ไม่เซ็นเซอร์ทั้งหมด ต่างกันที่ context และราคา:

unbleep และ unbleep-high เป็นระดับ reasoning: มันคิดก่อนตอบและส่ง trace กลับมาในฟิลด์ reasoning_content ควบคู่กับ content สำหรับโมเดล judge trace นั้นมีประโยชน์จริง — มันบอกคุณว่าทำไมแถวหนึ่งจึงได้คะแนนแบบที่ได้ ซึ่งคือสิ่งที่คุณต้องการเมื่อตรวจสอบกรณีที่ผลไม่ตรงกัน มันถูกคิดเงินเป็น output ด้วย ดังนั้นส่ง "thinking": false ในงานที่ไม่ต้องการมัน unbleep-mini ตอบตรง ๆ และไม่ส่ง trace กลับมา

การกำกับดูแลที่คุณควบคุมเอง

การลบการปฏิเสธออกจากโมเดลไม่ได้แปลว่าลบการกำกับดูแลออกจาก pipeline ของคุณ พารามิเตอร์ policy ที่เลือกใส่ได้จะรันการกำกับดูแลฝั่งเรา แบบต่อ request:

python
resp = client.chat.completions.create(
    model="unbleep",
    messages=[...],
    extra_body={"policy": "research"},  # recorded on the usage row; answers exactly like off
)

off คือ baseline ค่าเริ่มต้นที่ไม่มีการกรอง research ตอบเหมือน off ทุกประการ — ระดับที่ใช้จะถูกบันทึกไว้ในรายการ usage เพื่อให้คุณแยกทราฟฟิกการประเมินออกจากทราฟฟิก baseline ในรายงานของคุณเองได้ มันไม่ได้เพิ่มการคัดกรองใด ๆ strict สแกนข้อความใน message เทียบกับ blocklist ของบริการที่ผู้ดำเนินการของเราดูแล และส่ง 422 กลับมาเมื่อตรงกัน รายการนั้นเหมือนกันสำหรับทุกคนที่เลือกใช้ — ไม่มี blocklist รายบัญชีให้ตั้งค่า — ดังนั้นให้มองมันเป็นด่านสำรอง ไม่ใช่นโยบายเนื้อหาสำหรับโปรดักชันของคุณ

เรื่องหนึ่งที่ต้องเคลียร์ก่อนชี้ pipeline มาที่นี่: เราเก็บสิ่งที่คุณส่งมาและสิ่งที่ส่งกลับไป request body, เนื้อหาของ response และ IP ต้นทางของทุกการเรียกที่เรารับและส่งต่อไปยังโมเดล จะถูกเขียนลงฐานข้อมูลของเราและเก็บไว้ 30 วัน เพื่อการสอบสวนการใช้งานในทางที่ผิด การซัพพอร์ต และข้อพิพาทด้านการเรียกเก็บเงิน body ถูกตัดที่ 64 KB IP ต้นทางอยู่นานกว่า 30 วัน — มันถูกเขียนลงในรายการ usage ที่คิดเงินการเรียกนั้นด้วย และรายการนั้นเป็นบันทึกทางการเงินที่เราเก็บไว้นานกว่า สิ่งเดียวที่ไม่ถูกเก็บคือ request ที่ strict ปฏิเสธก่อนจะไปถึงโมเดล: รายการนั้นจะปรากฏในประวัติ usage ของคุณโดยไม่มีเนื้อหา นอกจากนี้ไม่มีอะไรได้รับการยกเว้น และไม่มีการตั้งค่าเพื่อปิดมัน ถ้าคลังข้อมูลของคุณอ่อนไหวพอที่สำเนา 30 วันนอกขอบเขตระบบของคุณจะเป็นปัญหา — มัลแวร์จริง ข้อมูลลูกค้า งานที่อยู่ภายใต้ NDA — นั่นคือข้อจำกัดจริง และนโยบายความเป็นส่วนตัว คือหน้าที่ต้องอ่านก่อนเริ่ม ไม่ใช่หลังจากนั้น

ข้อผิดพลาดใช้ envelope ของ OpenAI handler เดิมจึงใช้ได้: 401 key ไม่ถูกต้อง, 402 เครดิตหมด, 422 ถูกบล็อกโดย policy, 429 ติด rate limit, 5xx retry ได้ ทุก response มี header x-ratelimit-* งาน batch จึงกำหนดจังหวะตัวเองได้โดยไม่ต้องเดา

สิ่งที่ API ของ LLM แบบไม่เซ็นเซอร์ไม่ได้ให้คุณ

โมเดลที่ไม่เซ็นเซอร์คือเครื่องมือที่คมกว่า ไม่ใช่เครื่องมือที่ผ่อนปรน มันจะตอบคำถามที่โมเดลฐานถูกปรับให้ปฏิเสธ รวมถึงคำถามที่คุณไม่ควรถาม และมันจะตอบด้วยความมั่นใจเท่ากับที่มันใช้กับทุกเรื่อง — ซึ่งหมายความว่าตรงที่โมเดลที่มี guard เคยปฏิเสธเพราะความไม่รู้ ตัวนี้อาจแค่แต่งเรื่องขึ้นมา ให้มีมนุษย์รับผิดชอบสิ่งที่ออกมาเสมอ นโยบายการใช้งานที่ยอมรับได้ ระบุไว้ตรง ๆ ว่า API นี้มีไว้เพื่ออะไร และสิ่งจำนวนไม่กี่อย่างที่ห้ามใช้มันทำโดยเด็ดขาด การได้รับอนุญาตและเจตนาคือเกณฑ์ตัดสิน ไม่ใช่คำศัพท์ การใช้งานอย่างถูกกฎหมายเป็นความรับผิดชอบของคุณ

รับ API key แล้วเลิกวัดความระมัดระวังของเครื่องมือของคุณเสียที