DEV Community

Cover image for วิธีเพิ่มการเปิดเผย AI ใน API ของคุณ
Thanawat Wongchai
Thanawat Wongchai

Posted on Originally published at apidog.com

วิธีเพิ่มการเปิดเผย AI ใน API ของคุณ

อินเทอร์เฟซแชทของคุณอาจมีป้าย “AI-generated” ใต้ทุกคำตอบอยู่แล้ว แต่เมื่อทีมพันธมิตรเรียกใช้เอนด์พอยต์ /summarize จาก batch job บันทึกผลลงฐานข้อมูล และนำไปแสดงในรายงานลูกค้า ป้ายใน UI จะไม่ถูกส่งต่อไปด้วย การเปิดเผยข้อมูล AI ต้องอยู่ในสัญญา API ไม่ใช่เฉพาะในส่วนหน้า

ลองใช้ Apidog วันนี้

ช่องว่างนี้คือจุดที่การเปิดเผยข้อมูล AI มักล้มเหลว: ทีมออกแบบมันเป็นการตัดสินใจของ UI จึงหยุดอยู่ที่ขอบเขต frontend ผู้บริโภคแบบเครื่องจักรไม่ได้รับข้อมูล ทั้งที่พวกเขาต้องการมากที่สุด เพราะไม่สามารถดูผลลัพธ์แล้วรู้ได้เองว่ามาจากโมเดล

ตั้งแต่วันที่ 2 สิงหาคม 2026 มาตรา 50 ของ EU AI Act ทำให้เรื่องนี้เป็นข้อกำหนดที่จับต้องได้สำหรับหลายทีม ผู้ให้บริการโมเดล เช่น Anthropic อาจทำเครื่องหมายผลลัพธ์ในระดับโมเดล แต่หน้าที่ในการแจ้งผู้คนว่ากำลังโต้ตอบกับ AI อยู่กับผู้ที่นำระบบไปใช้งาน หาก API ของคุณอยู่ระหว่างสองฝ่ายนี้ API ต้องส่งข้อมูลที่ผู้เรียกใช้ใช้เพื่อปฏิบัติตามข้อกำหนดได้

บทความนี้แสดงวิธีใส่การเปิดเผยข้อมูลลงใน API contract: ควรส่งคืนอะไร วางไว้ตรงไหน กำหนดใน OpenAPI อย่างไร และทดสอบอย่างไรให้ไม่หายไปหลัง refactor โดย Apidog สามารถใช้สำหรับออกแบบเอกสารและทดสอบ API ได้ในที่เดียว

สิ่งที่ควรอยู่ในผลตอบกลับ

ข้อมูลเปิดเผยควรตอบคำถามแยกกันอย่างน้อย 3 ข้อ

  1. เนื้อหาถูกสร้างขึ้นหรือไม่
  2. สร้างโดยใครหรือโมเดลใด
  3. เราตรวจสอบแหล่งที่มาแล้วหรือยัง

1. ระบุระดับการสร้างเนื้อหา

เริ่มจาก ai_generated: true ได้ แต่ enum ให้ข้อมูลที่ผู้เรียกใช้ใช้งานต่อได้มากกว่า:

"generation": "synthetic" | "assisted" | "human"
Enter fullscreen mode Exit fullscreen mode

ความแตกต่างสำคัญ:

  • synthetic: โมเดลสร้างเนื้อหาทั้งหมดโดยไม่มีการเขียนโดยมนุษย์
  • assisted: มนุษย์เป็นผู้ร่างเนื้อหา แล้วโมเดลช่วยแก้ไข แปล หรือสรุป
  • human: ไม่มีโมเดลเกี่ยวข้อง

“Claude ปรับปรุงร่างที่มนุษย์เขียน” และ “Claude เขียนทั้งหมด” เป็นกรณีที่ต่างกันจริง รวมถึงมีผลต่อข้อยกเว้นตามมาตรา 50

2. ระบุผู้ให้บริการและโมเดล

ส่งคืนทั้ง vendor และ model ID เพราะผู้เรียกใช้อาจมีนโยบายเฉพาะโมเดล และ fallback model อาจเปลี่ยนสิ่งที่ทำได้กับผลลัพธ์นั้น

3. แยกสถานะแหล่งที่มาออกจากสถานะการสร้าง

ข้อมูลที่คุณสร้างเองกับข้อมูลที่คุณตรวจสอบเป็นคนละเรื่อง:

  • “เราสร้างเนื้อหานี้” คือข้อเท็จจริงที่ระบบของคุณเป็นเจ้าของ
  • “เรายืนยัน C2PA manifest แล้ว” คือผลการตรวจสอบที่ระบบของคุณทำ

ใช้ response shape ที่แยกสองส่วนนี้ชัดเจน:

{
  "id": "sum_4f81a2",
  "content": "The incident affected two regions for 41 minutes...",
  "ai": {
    "generation": "synthetic",
    "vendor": "anthropic",
    "model": "claude-opus-5",
    "human_review": false,
    "generated_at": "2026-08-11T09:14:22Z"
  },
  "provenance": {
    "status": "unchecked",
    "standard": null
  }
}
Enter fullscreen mode Exit fullscreen mode

ให้ความสำคัญกับ 2 ฟิลด์ต่อไปนี้เป็นพิเศษ:

  • human_review: มาตรา 50(4) กำหนดให้เนื้อหา AI ที่เผยแพร่เพื่อแจ้งสาธารณะในเรื่องประโยชน์สาธารณะต้องมีการเปิดเผย เว้นแต่ผ่านการตรวจสอบโดยมนุษย์หรือการควบคุมบรรณาธิการโดยผู้มีความรับผิดชอบ หากระบบบันทึกว่ามนุษย์อนุมัติร่างแล้ว ให้ส่งข้อเท็จจริงนี้กลับไปด้วย
  • provenance.status: อย่าบีบสถานะเป็น boolean เพราะ verified, absent, invalid และ unchecked มีความหมายต่างกัน การที่บริการตรวจสอบล่มไม่ควรมีความหมายเหมือนกับ “ไม่พบหลักฐานแหล่งที่มา”

เฮดเดอร์หรือเนื้อหา?

ใช้ ทั้งสองแบบ แต่ให้ทำหน้าที่ต่างกัน

เนื้อหาคือข้อมูลหลัก

JSON body คือสิ่งที่มักถูกจัดเก็บ บันทึก เล่นซ้ำ และส่งต่อ หากผู้เรียกใช้เก็บเฉพาะ parsed JSON ข้อมูลเปิดเผยต้องอยู่ใน body เสมอ

เฮดเดอร์ช่วยที่ขอบระบบ

เฮดเดอร์มีประโยชน์สำหรับ proxy, gateway และ logging layer ที่ไม่ parse response body รวมถึง response ที่ไม่ใช่ JSON เช่น plain text หรือ binary

HTTP/1.1 200 OK
Content-Type: application/json
X-AI-Generated: synthetic
X-AI-Model: anthropic/claude-opus-5
Enter fullscreen mode Exit fullscreen mode

กฎสำหรับเฮดเดอร์มี 2 ข้อ:

  1. ใช้ให้สม่ำเสมอในทุก endpoint ที่เกี่ยวข้อง เฮดเดอร์ที่มีแค่บาง route แย่กว่าการไม่มีเลย
  2. ระบุให้ชัดว่า body หรือ header คือ source of truth แล้วเขียน test บังคับให้ทั้งคู่ตรงกัน

สำหรับ streaming response ให้ส่งข้อมูลเปิดเผยใน response header หรือ event แรก ผู้เรียกใช้ที่เริ่ม render token แรกไม่ควรต้องรอจน stream จบจึงรู้ว่ากำลังแสดงอะไรอยู่

หากต้องการทบทวนพื้นฐานการออกแบบเฮดเดอร์ ดู HTTP headers คืออะไร

ใส่ไว้ใน OpenAPI spec

ฟิลด์ที่ไม่มีใน OpenAPI definition เป็นเพียงข้อตกลงปฏิบัติ และข้อตกลงแบบนี้มักหายไปเมื่อระบบเปลี่ยน

กำหนด schema ที่ใช้ซ้ำได้สำหรับทุก endpoint ที่อาจคืนผลลัพธ์จากโมเดล:

components:
  schemas:
    AiDisclosure:
      type: object
      required: [generation]
      properties:
        generation:
          type: string
          enum: [synthetic, assisted, human]
          description: >
            synthetic = produced by a model with no human authoring.
            assisted = a human authored the content and a model edited,
            translated, or summarised it.
            human = no model involvement.
        vendor:
          type: string
          example: anthropic
        model:
          type: string
          example: claude-opus-5
        human_review:
          type: boolean
          description: >
            True when a person reviewed the output before it was returned
            and an identifiable party holds editorial responsibility.
        generated_at:
          type: string
          format: date-time
Enter fullscreen mode Exit fullscreen mode

จากนั้นอ้างอิง schema นี้ใน response schema ของทุก endpoint ที่ใช้ AI และทำให้ ai เป็น required property:

type: object
required: [id, content, ai]
properties:
  id:
    type: string
  content:
    type: string
  ai:
    $ref: "#/components/schemas/AiDisclosure"
Enter fullscreen mode Exit fullscreen mode

การทำให้ฟิลด์เป็น required สำคัญมาก เพราะฟิลด์ optional คือฟิลด์ที่ผู้เรียกใช้ต้องเขียน defensive code รองรับ และในทางปฏิบัติหลายทีมจะไม่ทำ

ผลลัพธ์เพิ่มเติมคือ:

  • เอกสาร API ที่ generate จะอธิบายฟิลด์ให้ผู้บริโภคโดยอัตโนมัติ
  • การ validate spec จะตรวจจับวันที่ disclosure field หายไป

ดูเพิ่มเติมที่ วิธีตรวจสอบ OpenAPI specs และ OpenAPI diff เพื่อบล็อกการเปลี่ยนแปลงที่ทำให้ระบบล่มใน CI

เส้นทางที่คนมักลืม

Disclosure field มักหายไปใน flow ที่ไม่ได้ใช้ response serializer หลัก ตรวจสอบอย่างน้อย 4 จุดนี้

1. การตอบกลับที่แคชไว้

หาก cache เก็บ model output ก่อนมีการแนบ disclosure ผู้ใช้จะได้รับผลลัพธ์ที่ไม่มีเครื่องหมายตลอด TTL

แนวทาง: cache complete response หรือ cache ทั้ง model output และ disclosure metadata อย่า cache เฉพาะข้อความจากโมเดลแล้วคาดหวังว่า wrapper จะถูกประกอบกลับอย่างถูกต้องเสมอ

2. การตอบกลับแบบข้อผิดพลาดหรือบางส่วน

Timeout ที่ส่งคืน summary บางส่วนยังคงส่งคืนผลลัพธ์จากโมเดล หาก error envelope คนละ schema กับ success response ให้ใส่ disclosure field ใน error schema ด้วย

3. Batch payload และ webhook

งาน async มักสร้าง payload ด้วยโค้ดคนละชุดและ schema ที่เล็กกว่า นี่คือจุดที่ metadata หายบ่อยที่สุด

4. Fallback route

เมื่อโมเดลหลักล้มเหลวและระบบเปลี่ยนไปใช้ fallback model ค่า model ต้องเปลี่ยนตามไปด้วย อย่าฮาร์ดโค้ดชื่อโมเดลไว้ใน disclosure block

วิธีแก้ปัญหาสำหรับทุกกรณีเหมือนกัน: แนบ disclosure ณ จุดที่ model output เข้าสู่ response object ไม่ใช่เฉพาะตอน serialize normal route

ทดสอบให้เหมือนเป็นหลักประกัน

Disclosure field คือคำสัญญากับผู้เรียกใช้ คำสัญญาที่ไม่ผ่านการทดสอบเป็นเพียงเอกสารประกอบ

เริ่มจาก assertion 5 ข้อต่อไปนี้

1. ทุก AI route ต้องมี disclosure field

const body = pm.response.json();

pm.test("response carries AI disclosure", function () {
  pm.expect(body).to.have.property("ai");
  pm.expect(body.ai.generation).to.be.oneOf([
    "synthetic",
    "assisted",
    "human"
  ]);
});
Enter fullscreen mode Exit fullscreen mode

2. เฮดเดอร์ต้องตรงกับ body

pm.test("header and body agree", function () {
  pm.expect(pm.response.headers.get("X-AI-Generated"))
    .to.eql(body.ai.generation);
});
Enter fullscreen mode Exit fullscreen mode

3. โมเดลที่รายงานต้องตรงกับโมเดลที่เรียกใช้จริง

การทดสอบนี้ช่วยตรวจจับ fallback model ที่เกิดขึ้นแบบเงียบ ๆ การมีหรือไม่มีลายน้ำต้นทางของผลลัพธ์อาจขึ้นอยู่กับ model ID ดังนั้นการระบุโมเดลจึงเป็นรายละเอียดด้าน compliance ไม่ใช่แค่รายละเอียดด้านประสิทธิภาพ

ดูบริบทเพิ่มเติมใน การทำลายน้ำ API ของ Claude

4. Cached route ยังต้องเปิดเผยข้อมูล

เรียก endpoint เดิม 2 ครั้ง แล้วตรวจสอบว่าการตอบกลับครั้งที่ 2 ซึ่งมาจาก cache มี disclosure เหมือนครั้งแรก

5. Error route ยังต้องเปิดเผยข้อมูล

บังคับ timeout หรือ downstream failure แล้วตรวจสอบว่า error envelope ยังคงมีฟิลด์ ai หรือ disclosure ที่เทียบเท่า

รวม assertion เหล่านี้เป็น test scenario ตรวจ schema กับ OpenAPI definition แล้วรันใน CI ด้วย apidog-cli:

apidog run --access-token "$APIDOG_ACCESS_TOKEN" \
  -t "$DISCLOSURE_SCENARIO_ID" \
  -e "$APIDOG_ENV_ID" \
  -r cli,html
Enter fullscreen mode Exit fullscreen mode

เมื่อ assertion ล้มเหลว คำสั่งจะคืน non-zero exit code ดังนั้น PR ที่ทำให้ disclosure field หายไปจะทำให้ build ล้มเหลวก่อน deploy

ดูตัวอย่าง pipeline ที่ การทำให้การทดสอบ API เป็นไปโดยอัตโนมัติใน GitHub Actions และแนวทางทั่วไปใน การยืนยัน API

ดาวน์โหลด Apidog เพื่อสร้าง scenario สำหรับ endpoint ของคุณ

จัดทำเอกสารในที่ที่ผู้เรียกใช้มองหา

ผู้บริโภคมี 2 กลุ่ม จึงควรมีเอกสาร 2 ที่

ใน API reference

Schema description ควรอธิบายความหมายในบริบทผลิตภัณฑ์ของคุณโดยตรง โดยเฉพาะ assisted ผู้เรียกใช้จะอ่านคำอธิบายนี้เพื่อตัดสินใจว่าต้องติดป้ายหรือดำเนินการทางกฎหมายอย่างไร

ในหน้านโยบายสั้น ๆ

สร้าง policy page ที่ระบุว่า:

  • endpoint ใดอาจส่งคืนผลลัพธ์จากโมเดล
  • ใช้โมเดลใดบ้าง
  • มี human review หรือไม่ และหมายถึงอะไร
  • อะไรคือสิ่งที่ระบบรับประกัน และอะไรไม่รับประกัน

เชื่อมโยงหน้านี้จาก API reference และจัดเวอร์ชันเช่นเดียวกับ API

ระบุข้อจำกัดอย่างชัดเจนด้วย ตัวอย่างเช่น หากคุณส่งผ่านผลลัพธ์ของ Claude ข้อความอาจมีลายน้ำฝังอยู่ แต่คุณไม่สามารถตรวจสอบเองได้ และ Anthropic ยังไม่ได้เปิดเผยวิธีตรวจจับ การระบุข้อจำกัดตรง ๆ ดีกว่าสื่อเป็นนัยว่าระบบตรวจสอบสิ่งที่ตรวจสอบไม่ได้

อ่านรายละเอียดได้ที่ วิธีตรวจจับลายน้ำของ Claude

เอกสารแบบ interactive มีประโยชน์เป็นพิเศษ เพราะผู้เรียกใช้สามารถเห็น disclosure field ใน live response แทนการอ่านเพียงตาราง schema ดูวิธีตั้งค่าได้ที่ การโฮสต์เอกสาร API แบบโต้ตอบพร้อมคอนโซลทดลองใช้

คำถามที่พบบ่อย

เฮดเดอร์ X-AI-Generated เป็นมาตรฐานหรือไม่?

ไม่ใช่ ปัจจุบันไม่มีเฮดเดอร์มาตรฐานที่ได้รับการรับรองสำหรับ AI disclosure เลือกชื่อ จัดทำเอกสาร ใช้อย่างสม่ำเสมอ และถือว่าเป็นส่วนหนึ่งของ API contract

การเปิดเผยข้อมูลควรอยู่ในเฮดเดอร์หรือ body?

ทั้งคู่ Body คือสิ่งที่ถูกจัดเก็บและส่งต่อ ส่วน header มีประโยชน์สำหรับ proxy, gateway, log และ response ที่ไม่ใช่ JSON ระบุให้ชัดว่าอันใดเป็น source of truth หากข้อมูลไม่ตรงกัน

จำเป็นต้องทำตามกฎหมายหรือไม่?

ขึ้นอยู่กับบทบาทและเนื้อหาของคุณ ภาระตามมาตรา 50 ใช้กับผู้ให้บริการและผู้ใช้งานต่างกัน ขณะที่มาตรา 50(4) ครอบคลุม deepfake และข้อความเพื่อประโยชน์สาธารณะ พร้อมข้อยกเว้นสำหรับการควบคุมบรรณาธิการโดยมนุษย์

อ่านรายละเอียดใน มาตรา 50 ของ EU AI Act สำหรับนักพัฒนา API การตัดสินใจทางกฎหมายเป็นหน้าที่ของที่ปรึกษากฎหมาย ส่วนการออกแบบระบบเป็นหน้าที่ของทีมคุณ

ผู้ให้บริการทำลายน้ำผลลัพธ์อยู่แล้ว แค่นั้นไม่พอหรือ?

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

แล้ว streaming response ล่ะ?

ส่ง disclosure ใน response header หรือ event แรก อย่ารอให้ stream จบ เพราะผู้เรียกใช้เริ่มแสดงผลทันทีที่ token มาถึง

จัดการเนื้อหาที่มนุษย์แก้ไขหลังสร้างอย่างไร?

ใช้ assisted และ human_review มาตรา 50(4) มีข้อยกเว้นสำหรับเนื้อหาที่ผ่านการตรวจสอบโดยมนุษย์พร้อมความรับผิดชอบด้านบรรณาธิการ ดังนั้นการบันทึก metadata ให้ถูกต้องมีค่ามากกว่า boolean เพียงตัวเดียว

ต้อง version ฟิลด์นี้หรือไม่?

ต้อง เพราะมันเป็นส่วนหนึ่งของ response schema การเพิ่ม enum value เป็นการเปลี่ยนแปลงที่ผู้เรียกใช้ควรทราบ ใช้ OpenAPI diff ใน CI เพื่อตรวจจับการเปลี่ยนแปลงเหล่านี้

ข้อคิดที่สำคัญ

AI disclosure ล้มเหลวเมื่อเป็นเพียง UI feature และทำงานได้เมื่อเป็น API contract

ทำตาม checklist นี้:

  • เพิ่ม disclosure field แบบ required ใน response body
  • สะท้อนข้อมูลเดียวกันใน header
  • กำหนด schema ครั้งเดียวใน OpenAPI
  • ทดสอบ success, cache, partial error, batch, webhook และ fallback route
  • ตรวจ schema และ spec diff ใน CI
  • เขียนเอกสารให้ผู้เรียกใช้เข้าใจความหมายและข้อจำกัดของข้อมูล

งานนี้อาจใช้เวลาเพียงช่วงบ่าย แต่เปลี่ยนคำกล่าวอ้างเรื่อง AI transparency ให้เป็นข้อมูลที่ผู้เรียกใช้สร้างระบบต่อได้ และเป็นสัญญาที่ test suite ของคุณบังคับใช้ได้

Top comments (0)