![]()
จนถึงจุดนี้ในหลักสูตรคุณได้สร้างเอเจนต์ที่ทำงานบนแล็ปท็อปของคุณ ภายในโน้ตบุ๊ก โดยใช้ az login และตัวแปรสภาพแวดล้อมเล็กน้อย นั่นเป็นวิธีที่ถูกต้องในการเรียนรู้ แต่มันไม่ใช่วิธีที่ถูกต้องในการรันเอเจนต์ที่ลูกค้านับพันขึ้นอยู่ด้วยตอนตี 3
บทเรียนนี้เกี่ยวกับช่องว่างระหว่าง “มันทำงานบนเครื่องของฉัน” กับ “มันทำงานได้อย่างน่าเชื่อถือและคุ้มค่าในผลิตจริง” เราจะปิดช่องว่างนั้นโดยใช้ Microsoft Foundry และ Microsoft Foundry Agent Service และเราจะทำมันโดยการสร้างเอเจนต์สนับสนุนลูกค้าจริงที่มีเครื่องมือ การดึงข้อมูล ความจำ การประเมิน และการตรวจสอบ
บทเรียนนี้จะครอบคลุม:
หลังจากจบบทเรียนนี้ คุณจะรู้วิธี:
บทเรียนนี้สมมติว่าคุณได้ผ่านบทเรียนก่อนหน้าและคุ้นเคยกับ:
คุณจะต้องมีด้วย:
az login)requirements.txtเอเจนต์ตัวต้นแบบและเอเจนต์ผลิตจริงมีลูปหลักเหมือนกัน — การตั้งเหตุผล, เรียกใช้เครื่องมือ, ตอบกลับ สิ่งที่เปลี่ยนไปคือทุกอย่างที่ห่อหุ้มลูปนั้น แบบจำลองแค่ประมาณ 20% ของเอเจนต์ผลิตจริง; อีก 80% คือโครงสร้างการดำเนินงาน
| หัวข้อ | ตัวต้นแบบ | ผลิตจริง |
|---|---|---|
| การโฮสต์ | รันในโน้ตบุ๊กของคุณ | รันเป็นบริการโฮสต์, มีเวอร์ชันและปล่อยอัปเดต |
| ตัวตน | โทเค็น az login ของคุณ |
Managed identity กับ RBAC ขอบเขตจำกัด |
| สถานะ | ในหน่วยความจำ, หายไปหลังรีสตาร์ท | เก็บภายนอก (thread store, memory service) |
| ข้อผิดพลาด | คุณเห็น traceback | มี retry, fallback, dead-letter, แจ้งเตือน |
| ต้นทุน | “แค่ไม่กี่เซนต์” | ติดตามต่อคำขอ, เดินทาง, แคช, งบประมาณ |
| คุณภาพ | คุณตรวจสอบผลลัพธ์ด้วยตา | ประเมินอัตโนมัติก่อนปล่อยทุกครั้ง |
| ความเชื่อถือได้ | คุณอนุมัติทุกการกระทำ | นโยบาย + การอนุมัติของมนุษย์สำหรับการกระทำที่มีความเสี่ยง |
จดจำตารางนี้ไว้ ส่วนต่างๆ ด้านล่างจะจับคู่กับแถวเหล่านี้
มีสามรูปแบบที่คุณจะใช้ โดยมักใช้ร่วมกัน
อ็อบเจ็กต์เอเจนต์จะอยู่ภายในกระบวนการแอปพลิเคชันของ คุณ โค้ดของคุณเรียกผู้ให้บริการแบบจำลองโดยตรง; ลูปเหตุผลจะทำงานในบริการของคุณ นี่คือสิ่งที่ทุกบทเรียนก่อนหน้านี้ทำ
เอเจนต์ถูก ลงทะเบียนเป็นทรัพยากร ใน Microsoft Foundry Foundry จะโฮสต์ลูปเหตุผล จัดเก็บเธรด บังคับใช้ความปลอดภัยเนื้อหาและ RBAC และทำให้เอเจนต์มองเห็นได้ในพอร์ทัล Foundry แอปของคุณจะกลายเป็นไคลเอนต์บางที่สร้างเธรดและอ่านการตอบกลับ
เอเจนต์หลายตัว (และเครื่องมือ) จะถูกประกอบเป็นกราฟพร้อมการควบคุมอย่างชัดเจน — ขั้นตอนตามลำดับ, สาขา, โหนดอนุมัติของมนุษย์ และจุดตรวจสอบที่ทนทานที่สามารถหยุดและทำงานต่อได้ นี่คือความสามารถ Workflows ของ Microsoft Agent Framework ที่นำไปใช้ในระดับการปรับใช้
flowchart TB
subgraph P1[โฮสต์โดยไคลเอ็นต์]
A1[กระบวนการแอปของคุณ] --> M1[ผู้ให้บริการโมเดล]
end
subgraph P2[ตัวแทนที่โฮสต์]
A2[ไคลเอ็นต์บาง] --> F2[บริการตัวแทน Foundry]
F2 --> M2[โมเดล + เครื่องมือ + ร้านเก็บกระทู้]
end
subgraph P3[เวิร์กโฟลว์ตัวแทน]
A3[ผู้ประสานงาน] --> S1[ตัวแทนคัดแยก]
S1 --> S2[ตัวแทนแก้ไข]
S2 --> H[โหนดอนุมัติของมนุษย์]
H --> S3[ตัวแทนปฏิบัติการ]
end
การปรับใช้เอเจนต์ไม่ใช่แค่ push ครั้งเดียว มันคือวงจร และดูคล้ายกับวงจรการปล่อยซอฟต์แวร์เพราะนั่นคือสิ่งที่มันเป็น
flowchart LR
Create[สร้าง / ผู้เขียน] --> Version[เวอร์ชัน]
Version --> Evaluate[ประเมินแบบออฟไลน์]
Evaluate -->|ผ่านประตู| Deploy[ติดตั้งแบบโฮสต์]
Evaluate -->|ไม่ผ่านประตู| Create
Deploy --> Observe[สังเกตออนไลน์]
Observe --> Improve[รวบรวมความล้มเหลว]
Improve --> Create
Deploy --> Retire[ถอนเวอร์ชันเก่า]
แนวคิดหลักที่นำมาจาก บทเรียนที่ 10: การประเมินแบบออฟไลน์คือประตู ไม่ใช่สิ่งที่คำนึงทีหลัง เวอร์ชันเอเจนต์ใหม่จะไม่ถูกปล่อยถ้าไม่ผ่านเกณฑ์ประเมินของคุณ การตรวจสอบแบบออนไลน์จะป้อนข้อผิดพลาดในโลกจริงกลับเข้าไปในชุดทดสอบออฟไลน์ของคุณ นั่นคือวงจรทั้งหมด
การปรับขนาดเอเจนต์แตกต่างจากการปรับขนาดเว็บ API แบบไม่มีสถานะ เพราะแต่ละคำขออาจเรียกใช้หลายโมเดลและเครื่องมือที่มีค่าใช้จ่ายสูง สี่เทคนิคที่รับภาระมากที่สุด
การจัดการคำขอแบบไม่มีสถานะ อย่าเก็บสถานะเฉพาะผู้ใช้ในหน่วยความจำกระบวนการของคุณ เก็บเธรดการสนทนาในที่เก็บเธรดของ Foundry หรือบริการหน่วยความจำเพื่อให้ตัวอย่างใดก็ได้สามารถจัดการคำขอได้ นี่คือสิ่งที่ช่วยให้คุณปรับขนาดในแนวนอน — เพิ่มตัวอย่าง ไม่มีเซสชันแบบผูกมัด
การเดินทางแบบจำลอง ไม่ใช่ทุกคำขอต้องใช้โมเดลที่มีความสามารถสูงสุด (และมีราคาแพงที่สุด) นำคำขอที่ง่าย — การจำแนกเจตนา, คำตอบข้อเท็จจริงสั้นๆ — ไปยังโมเดลเล็กและเร็ว และสงวนโมเดลใหญ่สำหรับการตั้งเหตุผลจริง Foundry’s Model Router สามารถทำสิ่งนี้ให้คุณ หรือคุณสามารถพัฒนาเครื่องจำแนกเบาๆ ด้วยตนเอง คุณจะสร้างเวอร์ชัน DIY ในห้องปฏิบัติการ
การแคชการตอบกลับ คำถามสนับสนุนหลายคำถามเหมือนกัน (“ฉันจะรีเซ็ตรหัสผ่านได้อย่างไร?”) แคชคำตอบสำหรับคำถามทั่วไปและให้บริการโดยไม่ต้องเรียกใช้โมเดลเลย อัตราการโดนแคชไม่กี่เปอร์เซ็นต์ก็ช่วยลดต้นทุนและความหน่วงอย่างมีนัยสำคัญ
ความขนานและแรงย้อนกลับ ผู้ให้บริการโมเดลมีข้อจำกัดเรื่องอัตรา จำกัดความขนานของคุณ ใช้ retry พร้อม backoff แบบเอ็กซ์โพเนนเชียล และล้มเหลวอย่างเรียบร้อย (การตอบกลับแบบคิว “เรากำลังดำเนินการ” ดีกว่าข้อผิดพลาด 500)
flowchart LR
Q[คำถามของผู้ใช้] --> C{พบในแคชหรือไม่?}
C -->|ใช่| R[ส่งคำตอบจากแคช]
C -->|ไม่ใช่| Router{ซับซ้อนหรือไม่?}
Router -->|ง่าย| SLM[โมเดลขนาดเล็ก]
Router -->|ซับซ้อน| LLM[โมเดลขนาดใหญ่]
SLM --> Out[การตอบกลับ]
LLM --> Out
Out --> Store[แคช + ติดตามคำตอบ]
คุณไม่สามารถดำเนินการในสิ่งที่คุณไม่เห็น ตามที่ครอบคลุมในบทเรียน 10, Microsoft Agent Framework ส่งออก OpenTelemetry traces โดยเนทีฟ — ทุกการเรียกโมเดล การเรียกเครื่องมือ และขั้นตอนการออร์เคสเทรชันกลายเป็น span ในผลิตจริง คุณจะส่งออก span เหล่านั้นไปยัง Microsoft Foundry (หรือแบ็คเอนด์ที่รองรับ OTel ใดๆ) เพื่อให้คุณสามารถ:
from agent_framework.observability import get_tracer
tracer = get_tracer()
with tracer.start_as_current_span("support_request") as span:
span.set_attribute("customer.tier", "enterprise")
span.set_attribute("routed.model", "gpt-5-nano")
# การดำเนินการของเอเยนต์จะถูกติดตามโดยอัตโนมัติภายในช่วงเวลานี้
แอตทริบิวต์เช่น customer.tier และ routed.model คือสิ่งที่เปลี่ยนกลุ่ม trace ให้เป็นคำถามที่ตอบได้ (“ลูกค้าองค์กรได้ถูกส่งไปยังโมเดลเล็กเกินไปหรือไม่?”)
ต้นทุนในเอเจนต์ผลิตจริงส่วนใหญ่ขึ้นอยู่กับโทเค็น สามคันโยกตามลำดับผลกระทบ:
ประตูการประเมินและการควบคุมต้นทุนคือวินัยเดียวกันที่มองจากสองมุม: การประเมินบอกคุณถึง คุณภาพขั้นต่ำ, การเดินทางและการแคชช่วยให้คุณอยู่ใกล้ ต้นทุน ของระดับนั้นที่สุด
การกำกับดูแล Hosted Agents ได้รับมรดก RBAC, ความปลอดภัยเนื้อหา และการบันทึกตรวจสอบของ Foundry ให้แต่ละเอเจนต์มี managed identity ที่มีสิทธิ์น้อยที่สุดที่จำเป็น — การเข้าถึงฐานความรู้แบบอ่านอย่างเดียว, การเข้าถึง API ตั๋วในขอบเขตที่จำกัด, ไม่มีสิ่งอื่นเพิ่มเติม
มนุษย์ในวงจร บางการกระทำมีผลกระทบร้ายแรงเกินกว่าที่จะทำอัตโนมัติ — การคืนเงิน, การลบบัญชีผู้ใช้, การส่งต่อทีมกฎหมาย Microsoft Agent Framework รองรับเครื่องมือที่ ต้องการการอนุมัติ: เอเจนต์เสนอการกระทำ, หยุดการดำเนินการ, มีมนุษย์อนุมัติหรือปฏิเสธ, และเวิร์กโฟลว์ทำงานต่อ คุณได้เห็นโครงสร้างพื้นฐานใน บทเรียนที่ 6; ที่นี่คุณจะปรับใช้มัน
MCP ในผลิตจริง MCP ทำให้เอเจนต์ของคุณใช้เครื่องมือภายนอกผ่านอินเตอร์เฟซมาตรฐาน ในผลิตจริง ให้ถือว่าเซิร์ฟเวอร์ MCP ทุกตัวเป็นเขตแดนที่ไม่ไว้วางใจ: กำหนดเวอร์ชันเซิร์ฟเวอร์, รันด้วย managed identity ที่จำกัดขอบเขต, ตรวจสอบผลลัพธ์ และไม่เคยเปิดเผยความลับใดต่อมัน เซิร์ฟเวอร์ MCP คือความขึ้นต่อกัน และความขึ้นต่อกันต้องถูกแพตช์ ตรวจสอบ และจำกัดอัตรา
flowchart TB
subgraph Dev[สถาปัตยกรรมการพัฒนา]
D1[โน้ตบุ๊ก] --> D2[เฟรมเวิร์กเอเย่นต์]
D2 --> D3[ผู้ให้บริการโมเดล]
D2 --> D4[เครื่องมือภายในเครื่อง]
end
subgraph Deploy[สถาปัตยกรรมการปรับใช้]
E1[งานผ่าน CI] --> E2[ประตูประเมินผล]
E2 -->|ผ่าน| E3[บริการเอเย่นต์ Foundry]
E3 --> E4[เอเย่นต์ที่โฮสต์แบบมีเวอร์ชัน]
end
subgraph Run[สถาปัตยกรรมรันไทม์]
F1[แอปพลิเคชันลูกค้า] --> F2[เอเย่นต์ที่โฮสต์]
F2 --> F3[ตัวจัดการเส้นทางโมเดล]
F2 --> F4[Azure AI Search RAG]
F2 --> F5[บริการหน่วยความจำ]
F2 --> F6[เครื่องมือ MCP]
F2 --> F7[OTel -> การติดตาม Foundry]
F2 --> F8[การอนุมัติจากมนุษย์]
end
แผนภาพสามอันนั้น — การพัฒนา, การปรับใช้, การรันไทม์ — คือเอเจนต์เดียวกันในสามขั้นตอนของชีวิต ห้องปฏิบัติการถัดไปจะนำคุณผ่านการสร้างมัน
เปิด code_samples/16-python-agent-framework.ipynb แล้วทำตามทีละขั้นตอน คุณจะประกอบเป็น เอเจนต์สนับสนุนลูกค้า Contoso พร้อมทุกข้อกังวลสำหรับผลิตจริงเชื่อมต่ออยู่:
โน้ตบุ๊กจัดเรียงไว้ให้ข้อกังวลสำหรับผลิตจริงแต่ละข้อเป็นส่วนที่สามารถรันได้ด้วยตัวเอง หัวใจคือการจัดการคำขอแบบ routing-plus-caching:
async def handle_support_request(query: str, customer_id: str) -> str:
# 1. ให้บริการจากแคชเมื่อเป็นไปได้
cached = response_cache.get(normalize(query))
if cached:
return cached
# 2. กำหนดเส้นทางตามความซับซ้อนเพื่อควบคุมค่าใช้จ่าย
model = "gpt-5-nano" if is_simple(query) else "gpt-5-mini"
# 3. รันเอเจนต์ภายในช่วงการติดตามเพื่อการสังเกตการณ์
with tracer.start_as_current_span("support_request") as span:
span.set_attribute("routed.model", model)
span.set_attribute("customer.id", customer_id)
response = await support_agent.run(query, model=model)
# 4. แคชและส่งคืน
response_cache.set(normalize(query), response.text)
return response.text
ประตูประเมินที่คุ้มครองการปล่อยดูเหมือนนี้:
async def evaluation_gate(agent, test_cases, threshold: float = 0.8) -> bool:
passed = 0
for case in test_cases:
result = await agent.run(case["input"])
if score_response(result.text, case["expected"]) >= 0.8:
passed += 1
pass_rate = passed / len(test_cases)
print(f"Evaluation pass rate: {pass_rate:.0%} (gate: {threshold:.0%})")
return pass_rate >= threshold # ปล่อยใช้งานเฉพาะเมื่อเกตผ่านเท่านั้น
อ่านทุกบรรทัด — โน้ตบุ๊กเก็บโครงสร้างพื้นฐานให้น้อยเพื่อจะได้ไม่มีอะไรซ่อนอยู่หลังการเรียกเฟรมเวิร์ก
ประตูประเมินข้างต้นทำงาน แบบออฟไลน์ กับอ็อบเจ็กต์เอเจนต์ของคุณ เมื่อเอเจนต์ถูกปรับใช้เป็น Hosted Agent คุณจะต้องมีการตรวจสอบเพิ่มเติมที่ถูกกว่าหนึ่งอย่าง: จุดสิ้นสุดที่ปรับใช้จริงตอบสนองหรือไม่?
การปรับใช้ “สำเร็จ” พิสูจน์แค่เพียงว่า plane การควบคุมยอมรับนิยามมัน — ไม่ได้พิสูจน์ว่าเอเจนต์ตอบสนอง ขาดความขึ้นต่อกัน, การเดินทางโมเดลที่ไม่ถูกต้อง, หรือการเชื่อมต่อหมดอายุ อาจทิ้งการปรับใช้ที่เป็นสีเขียวแต่ตอบกลับว่างเปล่า การทดสอบควันจับสิ่งนั้นได้ภายในไม่กี่วินาทีในทุกครั้งที่ปรับใช้ โดยไม่ต้องเสียค่าประเมินเต็มรูปแบบ
ที่เก็บนี้มาพร้อมกับเส้นทางการทดสอบควันพร้อมใช้ที่สร้างขึ้นบน AI Smoke Test GitHub Action:
tests/lesson-16-smoke-tests.json มีพรอมต์และการตรวจสอบสำหรับเอเจนต์สนับสนุน Contoso (คำตอบนโยบายที่อิงฐานความรู้, การดูคำสั่งซื้อ, การอยู่ในหัวข้อ, และความต่อเนื่องหลายรอบบทสนทนา) แคตตาล็อกของเอเจนต์บทเรียนอื่นอยู่ข้างๆ ดูได้ที่ tests/README.md.github/workflows/smoke-test.yml ลงชื่อเข้าใช้ด้วย Azure OIDC และส่ง POST แต่ละพรอมต์ไปยังจุดสิ้นสุด Responses ของเอเจนต์ พร้อมทำงานล้มเหลวถ้าเจอการตรวจสอบผิดพลาด- name: Smoke-test hosted agent
uses: JFolberth/ai-smoketest@v1
with:
project_endpoint: $
agent_name: ContosoSupportAgent
tests_file: tests/lesson-16-smoke-tests.json
เรียกใช้งานจากแท็บ Actions เมื่อตัวแทนของคุณถูกปรับใช้ โดยระบุค่า endpoint ของโครงการ Foundry และชื่อเอเจนต์ของคุณ ตัวตนแบบรวมต้องมีบทบาท Azure AI User ในขอบเขตโครงการ Foundry คิดเลเยอร์ต่าง ๆ เหล่านี้เสมือนพีระมิด: การทดสอบแบบ smoke (เข้าถึงได้และตอบสนองไหม?) จะทำงานทุกครั้งที่เปิดตัว การประเมินแบบออฟไลน์ (พอที่จะส่งมอบได้ไหม?) ทำก่อนการเลื่อนระดับ และการประเมินแบบออนไลน์ (ทำงานอย่างไรในสภาพแวดล้อมจริง?) จะทำอย่างต่อเนื่อง
ทดสอบความเข้าใจก่อนขยับไปยังงานมอบหมาย
1. โดยประมาณแล้ว ตัวแทนที่ทำงานจริงส่วนใดคือ “โมเดล” และส่วนที่เหลือคืออะไร?
2. คุณจะเลือก Hosted Agent แทนตัวแทนที่โฮสต์บนลูกค้าเมื่อใด?
3. ทำไมตัวแทนที่สามารถปรับขนาดได้จึงต้องไม่มีสถานะในหน่วยความจำของกระบวนการตัวเอง?
4. การจัดเส้นทางโมเดลแก้ปัญหาอะไร และมันเกี่ยวข้องกับการประเมินอย่างไร?
5. “ประตูประเมินผล” คืออะไร และมันอยู่ที่ใดในวงจรชีวิต?
6. ทำไมเซิร์ฟเวอร์ MCP จึงควรถูกปฏิบัติเหมือนเป็นขอบเขตที่ไม่เชื่อถือได้ในสภาพแวดล้อมผลิต?
7. การเปลี่ยนแปลงอย่างเดียวที่มักมีผลกระทบใหญ่ที่สุดต่อค่าใช้จ่ายตัวแทนในการผลิตคืออะไร และทำไม?
8. บทบาทของแอตทริบิวต์ span เช่น customer.tier และ routed.model ในการสังเกตการณ์คืออะไร?
นำตัวแทนสนับสนุนลูกค้าจากแลปมาและเสริมความแข็งแกร่งเพื่อสถานการณ์เฉพาะ: ตัวแทนสนับสนุนการเรียกเก็บเงินแบบสมัครสมาชิกสำหรับบริษัท SaaS
งานส่งของคุณควร:
get_subscription_status, get_invoice, และ issue_credit (เครดิตเกิน $50 ต้องได้รับอนุมัติจากมนุษย์)เขียนย่อหน้าสั้น ๆ (ในเซลล์มาร์กดาวน์) อธิบายกฎการจัดเส้นทางโมเดลที่คุณเลือกและวิธีการตรวจสอบกับปริมาณข้อมูลจริง ไม่มีคำตอบที่ถูกต้องเพียงคำตอบเดียว — คุณจะถูกประเมินจากว่าปัญหาการผลิตเชื่อมโยงกันอย่างสอดคล้องหรือไม่
ในบทเรียนนี้คุณได้ย้ายตัวแทนจากต้นแบบมาสู่การผลิตด้วย Microsoft Foundry:
บทเรียนถัดไปจะเดินทางในทางกลับกัน: แทนที่จะขยายตัวแทนขึ้นสู่คลาวด์ คุณจะดึงตัวแทนลงมาบนเครื่องนักพัฒนาเครื่องเดียวและรันแบบทั้งหมดในเครื่อง
การสร้างตัวแทนใช้งานคอมพิวเตอร์ (CUA)
ปฏิเสธความรับผิดชอบ: เอกสารนี้ได้รับการแปลโดยใช้บริการแปลภาษา AI Co-op Translator ขณะที่เราพยายามให้ความถูกต้อง โปรดทราบว่าการแปลโดยอัตโนมัติอาจมีข้อผิดพลาดหรือความไม่ถูกต้อง เอกสารต้นฉบับในภาษาต้นทางควรถูกพิจารณาเป็นแหล่งข้อมูลที่เชื่อถือได้ สำหรับข้อมูลที่สำคัญ แนะนำให้ใช้การแปลโดยมนุษย์มืออาชีพ เราไม่รับผิดชอบต่อความเข้าใจผิดหรือการตีความที่ผิดพลาดที่เกิดขึ้นจากการใช้การแปลนี้