ในบทความนี้
In this post
ตอนที่ 10 จากสิบตอน: ตรึง model, SDK, questions, policy และข้อมูล เตรียม shadow mode กับ rollback และเก็บการเรียก live เป็นตัวเลือกที่ยังไม่ยืนยัน
ฉบับร่างสำหรับตรวจในเครื่อง • โค้ดเริ่มต้นใช้ offline fixtures เท่านั้น ตัวเลขเป็นสถานการณ์สมมติ ไม่ใช่ผลวัด Jev จริง และยังไม่มีการพิสูจน์ว่าระบบเร็วขึ้นหรือประหยัดลง
เป้าหมายและสิ่งที่ต้องพร้อม
แนะนำให้เริ่มจาก companion repo และคู่มือ README บน GitHub ด้านล่าง ส่วน ZIP ของเว็บไซต์เป็นสำเนาออฟไลน์อีกทางหนึ่ง คำสั่ง Node ใช้เหมือนกันเมื่อรันจากรากโครงการ GitHub repository · README / Quickstart
ใช้โครงการ Support Ticket Decision Lab เดิมตลอดสิบตอน เตรียม Node 22.18 ขึ้นไป terminal และโฟลเดอร์ที่เขียนไฟล์ได้ รันคำสั่งจากราก repo ai-core-jev-tutorial หรือจากไดเรกทอรี ai-core-jev-lab หากใช้ ZIP ของเว็บไซต์ ไม่ต้อง npm install สำหรับออฟไลน์ เผื่อเวลาลงมือและทดลองเปลี่ยนโค้ดประมาณ 20–40 นาที โดยเวลาที่แสดงบนหัวบทความเป็นเวลาอ่านเนื้อหา ไม่รวมเวลาลองทำ
ดาวน์โหลดโครงการพร้อมโค้ดและ tests (ZIP) · อ่านคู่มือโครงการ
ตอนนี้เน้นไฟล์ src/providers.mjs และใช้ผลจาก fixture เพื่อทดสอบการประกอบระบบเท่านั้น ยังไม่ได้ติดตั้ง SDK หรือใช้ key ในการจัดทำบทเรียน เส้นทาง live ที่แยกไว้ในตอนท้ายยังไม่ได้ทดสอบผ่าน API จริง
ทำความเข้าใจขอบเขตนี้
release มีมากกว่าชื่อโมเดล ต้องตรึง runtime, SDK, คำถาม นิยามป้าย policy ชุดข้อมูล และโค้ดอนุมัติกับ effect ไปด้วยกัน แล็บนี้บันทึกรุ่นโมเดลและ SDK แบบระบุเต็ม แต่ตั้งใจไม่ติดตั้ง dependency หรือให้ lockfile ของ dependency ทางอ้อม ก่อนรันจริงให้สร้างและตรวจ lockfile ในสภาพแวดล้อมของคุณ แล้วบันทึกรุ่นที่ใช้จริง
shadow mode คือสังเกต candidate โดยไม่ให้เส้นทางทำผลภายนอก การสาธิต live ที่เลือกได้จะเรียก Jev ด้วย ticket สมมติหนึ่งรายการ ตรวจ response แล้วคืนข้อเสนอหรือผล review เท่านั้น มันไม่เรียก generative fallback จริง ไม่รันประเมินเสียเงินแบบเป็นชุด ไม่ส่งข้อมูลลูกค้า และไม่ทำงาน support ขอบเขตจำกัดนี้เป็นความตั้งใจ
ผู้เขียนยังไม่ได้รันเส้นทาง live การตรวจเอกสารไม่ใช่การตรวจผ่านเครือข่ายจริง เราไม่ได้สมมติว่าทุกบัญชีเข้าถึงได้ และการมี API key ไม่ใช่หลักฐานว่า use case ได้รับอนุมัติ เก็บ credentials ฝั่ง server ไม่ใส่ใน HTML ภาพหน้าจอ commit หรือไฟล์ตัวอย่างที่แจก และตรวจรุ่นโมเดลกับราคาทางการใหม่ก่อนเลือกเรียกแบบมีค่าใช้จ่าย
ลงมือทีละเจ็ดขั้น
ขั้นที่ 1
เปิด config/release.json แล้วเทียบรุ่นทุกค่ากับโค้ด ตรวจว่ารุ่น policy ตรงกับ policy.json และ model ID ตรงกับ live client manifest ที่คัดมาแต่ข้อมูลเก่าแย่กว่าการไม่มี เพราะทำให้เชื่อว่าทำซ้ำได้ทั้งที่ไม่ตรง
ขั้นที่ 2
รันชุดทดสอบออฟไลน์ทั้งหมดกับ doctor จากไฟล์ที่แตกใหม่ โค้ดสมบูรณ์ต้องทำงานได้โดยไม่ติดตั้ง SDK ไม่ใช้ API key และไม่พึ่งเครือข่าย ให้รักษาด่านนี้เป็นข้อแรกของ release แม้เพิ่ม paid provider ภายหลัง งาน integration ใหม่ไม่ควรทำให้เส้นทางเรียนเริ่มต้นเสีย
ขั้นที่ 3
บันทึกรายงาน validation, test และ attack โดยคงป้ายหลักฐานไว้ เก็บ policy ที่ตรึงคู่กับผล อย่านำตัวเลข fixture สมมติไปใส่คำอ้างประสิทธิภาพผลิตภัณฑ์ release record ที่ดีแยกให้เห็นว่าอะไรได้รันจริงกับอะไรเพียงระบุแผนไว้
ขั้นที่ 4
อ่านคำแนะนำติดตั้งที่เป็นตัวเลือกโดยไม่รันรวมกับคอร์สออฟไลน์ หากเลือกทดสอบ live ด้วยบัญชีของคุณเอง ให้ติดตั้ง SDK รุ่นที่ตรึงฝั่ง server ตรวจ lockfile และส่ง key ผ่าน environment ของ shell ห้ามวาง key ลงในหน้าบทเรียนหรือ JavaScript ที่ทำงานในเบราว์เซอร์
ขั้นที่ 5
เรียก live เพียงหนึ่ง ticket อย่างชัดแจ้งหลังตรวจต้นทุนและขอบเขตข้อมูล คำสั่งแยกไว้ด้านล่างและยังไม่ได้รันสำหรับฉบับนี้ หากไม่มี key ไม่มี SDK หรือเรียกล้ม ต้องไม่เกิด action ตรวจรุ่นโมเดลที่ตอบกลับและเก็บ trace ที่ลบข้อมูลลับแล้วไว้ตรวจ
ขั้นที่ 6
วางการทดลอง shadow จริงก่อนให้สิทธิ์ ใช้ input ที่ได้รับอนุญาตและเป็นตัวแทน baseline ที่ตรึง และด่านคุณภาพ/coverage ที่เท่ากัน บันทึก latency end-to-end จริงและหลักฐานต้นทุนครบ รวมความไม่แน่ใจเรื่อง retry ภายในกับผลลัพธ์ของคน อย่าเลื่อนจาก shadow เพียงเพราะ endpoint คืน typed JSON ได้
ขั้นที่ 7
เตรียม rollback กับเงื่อนไขหยุด ระบุว่าใครปิด candidate ได้ artifact รุ่นใดใช้คืน baseline และการเพิ่มของข้อผิดพลาด การมองข้ามคำขอใช้คน หรือต้นทุนที่ไม่ทราบแบบใดจะหยุดทดลอง อำนาจควรเพิ่มเมื่อหลักฐานรองรับการเปลี่ยนขอบเขตที่ตรวจแล้วเท่านั้น
ไฟล์และคำสั่งที่ใช้
โค้ดประกอบบน GitHub: ai-core-jev-tutorial · README. ใช้ repo เป็นทางหลักในการทำแบบฝึก ไฟล์ต่อไปนี้ตรึงกับรุ่นที่ทดสอบแล้ว src/providers.mjs · config/release.json · test/report.test.mjs
เปิดไฟล์นี้เทียบกับ source ใน ZIP ก่อนแก้ ข้อความต่อไปนี้คือโค้ดที่ใช้ในโครงการจริง ไม่ใช่ pseudocode ผลโมเดลเป็น input ให้โค้ดตรวจและวางเส้นทางต่อ ไม่ใช่สิทธิ์ให้ข้ามด่านอนุมัติ
import {readFile} from 'node:fs/promises';
import {performance} from 'node:perf_hooks';
import {requestShape,ROUTES,ROUTE_QUESTION,HUMAN_QUESTION} from './questions.mjs';
import {tokenUsage} from './contracts.mjs';
export async function fixtureProviders() {
const fixtures=JSON.parse(await readFile(new URL('../data/predictions.mock.json',import.meta.url),'utf8'));
async function call(kind,ticket) {
const f=fixtures[ticket.id]?.[kind];if(!f)throw new Error('fixture not found');
return {value:structuredClone(f.value),attempt:{provider:kind,mode:'MOCK / FICTIONAL SCENARIO',usage:f.usage,scenarioLatencyMs:f.scenarioLatencyMs,wallMs:null,httpAttempts:1,costComplete:true}};
}
return {jev:t=>call('jev',t),baseline:t=>call('baseline',t)};
}
export async function liveJev(ticket,{live=false}={}) {
if(!live)throw new Error('Live API requires explicit --live');
if(!process.env.TYPESAFE_API_KEY)throw new Error('TYPESAFE_API_KEY is not set');
// Offline mode never resolves the SDK or reads a secret.
const {choice,noul,TypeSafeClient}=await import('@typesafe-ai/sdk');
const client=new TypeSafeClient({defaultModel:'jev-1.13.0'});
const started=performance.now();
const value=await client.systemOne({state:requestShape(ticket).state,questions:{route:choice(ROUTE_QUESTION,{...ROUTES}),wantsHuman:noul(HUMAN_QUESTION)}});
return {value,attempt:{provider:'jev',mode:'LIVE / NOT VERIFIED BY THE AUTHOR',usage:tokenUsage(value),wallMs:performance.now()-started,scenarioLatencyMs:null,httpAttempts:null,costComplete:false}};
// SDK retries may occur internally. No outer retry loop is added. Final
// response usage alone cannot establish the total bill across failed attempts.
}
คำสั่งออฟไลน์ต่อไปนี้รันได้โดยไม่ใช้ SDK หรือ API key:
node src/cli.mjs doctor
node --test --test-reporter=spec
node src/cli.mjs evaluate --split validation --save
node src/cli.mjs evaluate --split test --save
node src/cli.mjs evaluate --split attack --saveตัวเลือก live เท่านั้น: มีค่า API ตามบัญชีของผู้อ่าน คำสั่งนี้ยังไม่ได้รันหรือยืนยันสดสำหรับฉบับร่าง ห้ามนำ key ไปใส่หน้าเว็บไซต์
npm install --ignore-scripts @typesafe-ai/[email protected]
# Set TYPESAFE_API_KEY privately in your server-side shell first.
node src/cli.mjs demo --ticket T-001 --live
ตรวจผลที่ควรได้
คำสั่งออฟไลน์ทุกข้อควรผ่านได้โดยไม่มี node_modules คำสั่ง live ด้านล่างเป็นตัวเลือกตามเอกสารที่ยังไม่ได้ทดสอบ ไม่อยู่ใน acceptance suite ที่ไม่เสียค่า API และแม้สังเกต shadow สำเร็จก็ยังไม่ได้อนุญาตการกระทำกับ help desk ภายนอก
ตรวจชื่อ test และเส้นทางปฏิเสธด้วย อย่าดูเพียง exit code หรือ label สุดท้าย ข้อมูลที่ไม่ทราบต้องยังระบุว่าไม่ทราบ และรายงานทุกชิ้นต้องแยกผลจำลองออกจากข้อมูลที่วัดจริง
แก้ปัญหาเมื่อผลไม่ตรง
ถ้า alias ย้ายรุ่น ให้ใช้โมเดลที่ตรึงต่อจนกว่าจะประเมินใหม่ ถ้าบิล live ไม่มี usage ของ attempts ที่ล้ม ให้ระบุต้นทุนรวมว่ายังไม่ทราบ ไม่อนุมานเป็นศูนย์ ถ้าหยุด rollout ไม่ได้โดยไม่ถามโมเดล candidate ต้องทำปุ่มหยุดที่แอปเป็นเจ้าของก่อนขยายการทดลอง
หากเปิดบทเรียนผ่าน Python http.server ให้ใช้ลิงก์ .html ที่ท้ายตอนเมื่อจำเป็น ลิงก์ chip แบบไม่มีนามสกุลในแถบซีรีส์อาศัยการ resolve ของ GitHub Pages และเป็นข้อจำกัด preview ที่มีอยู่เดิม ไม่ใช่ปัญหาในโค้ด Node
เปลี่ยนหนึ่งอย่างแล้วทดสอบ
ร่าง go/no-go record ที่มีรุ่น release ชัด เงื่อนไขคุณภาพ ความครบของต้นทุน ผู้รับผิดชอบ rollback และข้อค้าง ข้อสรุปที่ถูกอาจเป็นให้คง shadow ต่อ อย่าอนุญาต action ภายนอกเพียงเพื่อให้ตอนจบดูเหมือน deploy สำเร็จ
ทำการแก้ไขในสำเนาทดลอง เก็บไฟล์ต้นฉบับไว้เทียบ แล้วคืนค่าก่อนเริ่มตอนถัดไป หากทดลองกับ provider จริงภายหลัง ให้สร้าง experiment record ใหม่แทนเขียนทับผลเดิม
จุดตรวจถัดไป
ก่อนขยับต่อ ให้บอกได้ว่าไฟล์ใดเป็น contract ไฟล์ใดเป็น policy หลักฐานใดได้จากการรัน และข้อใดยังไม่ได้ทดสอบกับโมเดลจริง การแยกสี่อย่างนี้เป็นงานวิศวกรรมที่สำคัญกว่าการได้เดโมที่ดูไหลลื่น
← ตอนก่อนหน้า · กลับสารบัญซีรีส์
แหล่งอ้างอิงและหลักฐาน
เอกสารและ source ที่ใช้
ตรวจเอกสาร Jev วันที่ 23 ตุลาคม 2026 ข้อเท็จจริง API และราคาอาจเปลี่ยน ให้ตรวจใหม่ก่อนใช้ live ส่วนผลของ fixture เป็นข้อมูลสอนที่ระบุไว้ในโครงการ
สรุปที่นำไปใช้ต่อ
- contract จำกัดโครงสร้าง ส่วน evaluation ตรวจพฤติกรรม
- อ่าน coverage คุณภาพ เวลา และต้นทุนรวมควบคู่กัน
- ข้อเสนอไม่ใช่ผลที่อนุมัติแล้ว และหลักฐาน mock ไม่ใช่หลักฐานโมเดล live
Part 10 of ten: Pin model, SDK, questions, policy and data; prepare shadow mode and rollback while keeping live calls explicitly optional and unverified.
Local review draft • Default code uses offline fixtures. Numbers are fictional scenarios, not measured Jev results. Faster performance and lower cost remain hypotheses.
Outcome and prerequisites
Start with the companion repository and its detailed README. The website ZIP remains an alternative offline snapshot; run the same Node commands from either project root. GitHub repository · README / Quickstart
Use the same Support Ticket Decision Lab throughout the series. Have Node 22.18+, a terminal and a writable directory. Run commands from the cloned ai-core-jev-tutorial root, or the extracted ai-core-jev-lab folder if using the website ZIP. Offline work needs no npm install. Allow roughly 20–40 minutes for experiments; the article reading-time label excludes hands-on work.
Download the complete code and tests (ZIP) · Project README
This chapter focuses on src/providers.mjs. Fixture outputs test the integration mechanics only. The author did not install the SDK or use an API key while preparing the lab. The separately documented live path has not been tested against the API.
How this boundary works
A release is more than a model name. Pin the runtime, SDK, questions, label definitions, policy, dataset and approval/effect code together. The lab records a model and exact SDK version but intentionally does not install dependencies or supply a transitive lockfile. Before a real run, create and review the lockfile in your own environment and record actual versions.
Shadow mode means observing a candidate without giving it an external effect path. The optional live demonstration calls Jev for one synthetic ticket, validates the response and returns a proposal or review result. It does not call a real generative fallback, run bulk paid evaluation, send customer data or execute a support action. That limited scope is deliberate.
The live path has not been executed by the author. Documentation verification is not network verification, account access is not assumed, and an API key is not evidence that a use case is approved. Keep credentials server-side and out of HTML, screenshots, commits and downloaded example files. Recheck official model availability and pricing before opting into a paid request.
Seven practical steps
Step 1 — Open config/release.json and compare every version with the code
Open config/release.json and compare every version with the code. Check that the policy version matches policy.json and the model ID matches the live client. A copied manifest with stale fields is worse than a missing one because it gives false confidence in reproducibility.
Step 2 — Run the full offline suite and doctor from a clean extraction
Run the full offline suite and doctor from a clean extraction. The complete solution must work without an SDK installation, an API key or a network connection. Keep this as the first release gate even if you later add a paid provider: new integration work should not break the learning path.
Step 3 — Save validation, test and attack reports with their evidence labels intact
Save validation, test and attack reports with their evidence labels intact. Store the frozen policy next to the outputs. Do not paste fictional fixture numbers into a product performance claim. A useful release record distinguishes what was executed from what was merely specified.
Step 4 — Review the optional installation instructions without running them as part of the offline course
Review the optional installation instructions without running them as part of the offline course. If you choose live testing on your own account, install the pinned SDK server-side, review its dependency lockfile and provide the key through your shell environment. Never put the key into a tutorial page or browser JavaScript.
Step 5 — Make only an explicit one-ticket live call after reviewing its cost and data scope
Make only an explicit one-ticket live call after reviewing its cost and data scope. The command is shown separately below and was not executed for this draft. A missing key, unavailable SDK or failed call must not create an action. Confirm the returned model and retain a redacted trace for review.
Step 6 — Plan the real shadow experiment before granting authority
Plan the real shadow experiment before granting authority. Use permitted representative inputs, a frozen baseline and identical quality/coverage gates. Record actual end-to-end latency and complete cost evidence, including hidden retry uncertainty and manual outcomes. Do not graduate from shadow merely because the endpoint returns typed JSON.
Step 7 — Prepare rollback and stop conditions
Prepare rollback and stop conditions. Define who can disable the candidate, which release artifact restores the baseline and which increase in errors, human-request misses or unknown costs stops the trial. Authority should grow only after evidence justifies a reviewed change in scope.
Files and commands
Companion code on GitHub: ai-core-jev-tutorial · README. Use the companion repository as the default working copy. These file links pin the tested revision. src/providers.mjs · config/release.json · test/report.test.mjs
Compare this file with the source in the ZIP before editing. The listing is the implementation used by the lab, not pseudocode. Model output is input to validation and routing code; it grants no permission to bypass approval.
import {readFile} from 'node:fs/promises';
import {performance} from 'node:perf_hooks';
import {requestShape,ROUTES,ROUTE_QUESTION,HUMAN_QUESTION} from './questions.mjs';
import {tokenUsage} from './contracts.mjs';
export async function fixtureProviders() {
const fixtures=JSON.parse(await readFile(new URL('../data/predictions.mock.json',import.meta.url),'utf8'));
async function call(kind,ticket) {
const f=fixtures[ticket.id]?.[kind];if(!f)throw new Error('fixture not found');
return {value:structuredClone(f.value),attempt:{provider:kind,mode:'MOCK / FICTIONAL SCENARIO',usage:f.usage,scenarioLatencyMs:f.scenarioLatencyMs,wallMs:null,httpAttempts:1,costComplete:true}};
}
return {jev:t=>call('jev',t),baseline:t=>call('baseline',t)};
}
export async function liveJev(ticket,{live=false}={}) {
if(!live)throw new Error('Live API requires explicit --live');
if(!process.env.TYPESAFE_API_KEY)throw new Error('TYPESAFE_API_KEY is not set');
// Offline mode never resolves the SDK or reads a secret.
const {choice,noul,TypeSafeClient}=await import('@typesafe-ai/sdk');
const client=new TypeSafeClient({defaultModel:'jev-1.13.0'});
const started=performance.now();
const value=await client.systemOne({state:requestShape(ticket).state,questions:{route:choice(ROUTE_QUESTION,{...ROUTES}),wantsHuman:noul(HUMAN_QUESTION)}});
return {value,attempt:{provider:'jev',mode:'LIVE / NOT VERIFIED BY THE AUTHOR',usage:tokenUsage(value),wallMs:performance.now()-started,scenarioLatencyMs:null,httpAttempts:null,costComplete:false}};
// SDK retries may occur internally. No outer retry loop is added. Final
// response usage alone cannot establish the total bill across failed attempts.
}
Run these offline commands without an SDK installation or API key:
node src/cli.mjs doctor
node --test --test-reporter=spec
node src/cli.mjs evaluate --split validation --save
node src/cli.mjs evaluate --split test --save
node src/cli.mjs evaluate --split attack --saveOptional live path only: it can incur API charges on your account. These commands were not run or live-verified for this draft. Never put a key in the website.
npm install --ignore-scripts @typesafe-ai/[email protected]
# Set TYPESAFE_API_KEY privately in your server-side shell first.
node src/cli.mjs demo --ticket T-001 --live
Verify the expected behavior
All offline commands must pass without node_modules. The live command below is a documented, untested option and is not part of the paid-call-free acceptance suite. A successful shadow observation still authorizes no external help-desk action.
Read the named tests and refusal paths, not just the exit code or final label. Unknown values must remain unknown, and every report must distinguish simulation inputs from real measurements.
Troubleshooting
If the model alias moved, keep the pinned model until re-evaluation. If a live bill lacks failed-attempt usage, label total cost unknown rather than extrapolating zero. If a rollout cannot be stopped without asking the candidate model, implement an application-owned stop control before expanding the trial.
When previewing with Python http.server, use the .html continuation links below when needed. Extensionless series chips rely on GitHub Pages resolution; that documented preview limitation is separate from the Node example.
Change one thing, then test
Draft a go/no-go record with the exact release identifiers, quality constraints, cost completeness, rollback owner and unresolved issues. The correct conclusion may be remain in shadow. Do not authorize an external action merely to make the final tutorial look like a deployment success.
Make changes in a disposable copy, retain the reference files for comparison, and restore them before the next chapter. If you later use a real provider, create a new experiment record rather than overwriting the fixture transcript.
Next checkpoint
Before moving on, identify the contract file, the policy file, what was observed in a run, and what remains untested against a real model. Keeping those four things separate matters more than making the demo look effortless.
← Previous chapter · Return to the series index
References and evidence
Documentation and implementation
Jev documentation checked on 23 October 2026. API and pricing details can change; recheck before live use. Fixture results are explicitly authored teaching data in the project.
Key takeaways
- Contracts bound structure; evaluation checks behavior.
- Coverage, quality, latency and total cost must be read together.
- A proposal is not an approved effect; mock evidence is not live model evidence.