Step 10 of 16
Ground agent answers with TextSearchProvider, an in-memory vector store, source metadata, and refusal tests.
เพิ่ม RAG หลัง agent foundation พร้อมครับ เริ่มจาก in-memory flow ที่เห็น ingestion ถึง citation ครบเส้น
Level: Advanced
ตอนนี้ agent, session และ controls พร้อมแล้ว เราจะเพิ่ม RAG แบบเล็กให้ครบวงจรก่อนครับ เป้าหมายคือ ingest เอกสารไม่กี่ชิ้น, retrieve context และตอบพร้อม source จากนั้นค่อยปรับคุณภาพในบทถัดไป
สร้าง RAG vertical slice ที่สลับระหว่าง automatic retrieval กับ on-demand retrieval ได้ และมี test สำหรับคำถามที่ตอบไม่ได้ครับ
Loading diagram...
ใช้ in-memory vector store เพื่อพิสูจน์ flow โดยยังไม่เพิ่ม external database:
var options = new TextSearchProviderOptions
{
SearchTime = TextSearchProviderOptions.TextSearchBehavior.BeforeAIInvoke,
RecentMessageMemoryLimit = 4
};
Func<string, CancellationToken,
Task<IEnumerable<TextSearchProvider.TextSearchResult>>> search =
async (query, cancellationToken) =>
{
var hits = await textSearchStore.SearchAsync(
query, top: 3, cancellationToken);
return hits.Select(hit => new TextSearchProvider.TextSearchResult
{
SourceName = hit.SourceName,
SourceLink = hit.SourceLink,
Text = hit.Text ?? string.Empty,
RawRepresentation = hit
});
};
ลงทะเบียน new TextSearchProvider(search, options) ใน ChatClientAgentOptions.AIContextProviders และกำหนด instructions ให้ตอบจาก supplied context พร้อม source ID ครับ
TextSearchProvider รองรับสอง behavior ใน API ปัจจุบัน:
BeforeAIInvoke ค้นหาทุก run เหมาะกับ support agent ที่เกือบทุกคำถามต้องใช้เอกสารOnDemandFunctionCalling เปิด retrieval เป็น tool ให้ model เรียกเมื่อจำเป็น ช่วยลด search ที่ไม่ต้องใช้ แต่ query จาก model ต้องถูกมองเป็น untrusted inputRecentMessageMemoryLimit ช่วยให้ retrieval เข้าใจ multi-turn query โดยไม่ฝัง history ทั้งหมดลง conversation ถาวรครับ เริ่มด้วยค่าน้อยแล้ววัด quality กับ token usage
อย่าเก็บ context ที่ provider inject ซ้ำเข้า chat history ทุก turn เพราะ session จะโตเร็ว Official sample ใช้ StorageInputRequestMessageFilter ตัด message จาก AIContextProvider และ ChatHistory ก่อน persist
เตรียมคำถาม 5 ข้อที่มีคำตอบ, 3 ข้อที่ไม่มีคำตอบ และ 2 ข้อที่ใช้คำต่างจากเอกสาร Agent ต้องอ้าง source ที่เกี่ยวข้องและปฏิเสธอย่างสุภาพเมื่อ context ไม่พอครับ
Run dataset เดียวกันทั้งสอง search behaviors แล้วเทียบ retrieval calls, Recall@K, prompt tokens, latency และ refusal result ตรวจด้วยว่า source IDs ในคำตอบมาจาก retrieved records เท่านั้น
Search delegate ต้อง validate query, apply tenant/permission filters และจำกัด result size Retrieved content เป็น untrusted data จึงห้ามตีความ instructions ภายในเอกสารเป็น system policy
ส่ง feature-flagged RAG provider, seeded test documents, answerable/unanswerable dataset และ comparison report ของสอง behaviors