تایید پاسخ و حلقههای اصلاح
توسعه عاملهای هوشمند (Agentic Ai) با Langchain و Langgraph
- Define verification criteria for evidence coverage, citation support, and answer completeness.
- Use a bounded evaluator-generator loop to request targeted repairs.
- Set explicit stopping conditions and failure fallbacks.
چرا پاسخ را بررسی کنیم؟
**هدف:** پاسخ مولد فقط وقتی قابلاعتماد است که هم کامل باشد، هم با شواهد و citation پشتیبانی شود.
- **Builds on ← 4.4: RAG Evaluation Metrics and Test Sets:** معیارها را از سطح مجموعهآزمون به سطح یک پاسخ اجراشده میآوریم.
- **Builds on ← 8.1: Agentic RAG Graph Architecture:** گره تولیدکننده، گره ارزیاب و مسیر repair را در گراف قرار میدهیم.
- **مسئله:** پاسخ ممکن است روان باشد، اما یک ادعا شواهد نداشته باشد یا citation به ادعای دیگری اشاره کند.
- **Where this leads → 9.2: Agent Evaluation and Regression Testing:** همین بررسیهای محلی بعداً روی مجموعهای از سؤالها اجرا میشوند.
```mermaid
flowchart LR
Q["پرسش"] --> R["Retrieval"]
R --> G["تولید پاسخ"]
G --> V["Verification"]
V -->|"معتبر"| A["پاسخ نهایی"]
V -->|"نقص دارد"| P["Repair هدفمند"]
P --> G
V -->|"تلاش تمام شد"| F["Fallback شفاف"]
```
سه معیار قابلاندازهگیری
**پاسخ را به ادعاها بشکنید:**
**ادعاها:** \(C = \{c_1, c_2, \ldots, c_n\}\)
**شواهد:** \(E = \{e_1, e_2, \ldots, e_m\}\)
- **Evidence coverage:** هر ادعای مهم باید دستکم یک شاهد مرتبط داشته باشد.
\[
\operatorname{coverage}(c_i)=
\begin{cases}
1 & \exists e_j:\operatorname{supports}(e_j,c_i)\\
0 & \text{otherwise}
\end{cases}
\]
- **Citation support:** citation باید واقعاً همان ادعا را پشتیبانی کند، نه فقط موضوعی مشابه را.
- **Completeness:** همه بخشهای خواستهشده در پرسش باید پاسخ داده شده باشند.
**مثال کامل:** پاسخ دو ادعا دارد: «زمان اجرا ۲ ثانیه است» و «حالت خطا retry دارد».
1. برای ادعای اول، هیچ شاهد مرتبطی نداریم؛ بنابراین \(coverage(c_1)=0\).
2. برای ادعای دوم، سند \(e_1\) وجود retry را تأیید میکند؛ بنابراین \(coverage(c_2)=1\).
3. پس:
\[
\operatorname{coverage} = \frac{0+1}{2}=\frac{1}{2}
\]
4. اگر پرسش هر دو مورد را خواسته باشد، پاسخ از نظر **Completeness** نیز ناقص است.
```mermaid
flowchart TD
C["ادعا"] --> M{"شاهد مرتبط؟"}
M -->|"بله"| S["Citation پشتیبان"]
M -->|"خیر"| U["ادعای بدون پشتوانه"]
S --> K{"همه بخشهای پرسش؟"}
U --> R["نیازمند repair"]
K -->|"بله"| OK["پاسخ کامل"]
K -->|"خیر"| R
```
Evaluator؛ داور مطلق نیست
**قرارداد خروجی evaluator:**
```python
class Verification:
supported: bool
complete: bool
citations_aligned: bool
missing_claims: list[str]
unsupported_citations: list[str]
repair_request: str
```
- evaluator باید **شاهد و دلیل قابلردیابی** بدهد، نه فقط نمره.
- generator و evaluator ممکن است هر دو اشتباه کنند؛ evaluator «حقیقت مطلق» نیست.
- نتیجه معتبر فقط وقتی صادر شود که:
\[
supported \land complete \land citations\_aligned
\]
**نمونه بررسی:**
- ادعا: «retry سه بار انجام میشود.»
- متن سند: «حداکثر دو retry مجاز است.»
- مقایسه: \(3 \neq 2\)
- نتیجه: `supported = False`
- repair: «عدد retry را به ۲ اصلاح کن و citation همان سند را نگه دار.»
**پیوند با ← 8.1:** خروجی ساختیافته، تصمیمگیری گرههای گراف را قابلمسیریابی میکند.
حلقه repair با سقف تلاش
**قاعده:** repair باید هم هدفمند باشد و هم bounded.
```mermaid
flowchart TD
S["answer + evidence"] --> E["Evaluate"]
E --> D{"قبول؟"}
D -->|"بله"| OUT["Return supported answer"]
D -->|"خیر"| N{"attempt < max_attempts؟"}
N -->|"بله"| T["Targeted repair request"]
T --> G["Generate repaired answer"]
G --> E
N -->|"خیر"| F["Evidence-insufficient fallback"]
```
**شبهکد اجرایی:**
```python
attempt = 0
while attempt < max_attempts:
report = evaluate(answer, evidence, question)
if report.supported and report.complete and report.citations_aligned:
return answer
answer = repair(answer, report.repair_request, evidence)
attempt = attempt + 1
return fallback("evidence_insufficient", report.missing_claims)
```
**ردیابی یک اجرای عددی:** اگر `max_attempts = 2` باشد، حلقه فقط با `attempt = 0` و سپس `attempt = 1` وارد ارزیابی میشود. بعد از repair دوم، مقدار `attempt` به ۲ میرسد و شرط \(2 < 2\) نادرست میشود؛ بنابراین fallback اجرا میشود.
**چرا سقف؟** جلوگیری از هزینه، تأخیر و حلقه بیپایان؛ رضایت کامل evaluator شرط توقف نیست.
نمونه کامل؛ از نقص تا خروجی
**دادهها:** پرسش سه بخش دارد: تعریف، مقدار و محدودیت.
**پاسخ اولیه:** تعریف و مقدار را دارد؛ محدودیت را ندارد. `max_attempts = 2`
**تلاش ۰ — ارزیابی**
\[
\operatorname{coverage}=\frac{2}{3},\qquad \operatorname{complete}=\operatorname{False}
\]
`repair_request = "بخش محدودیت را فقط از سند E2 اضافه کن."`
**تلاش ۱ — repair**
- تعریف ← `E1`
- مقدار ← `E1`
- محدودیت ← `E2`
- citationها به ادعای مربوط متصل شدند.
**تلاش ۱ — ارزیابی دوباره**
\[
\operatorname{coverage}=\frac{3}{3}=1
\]
\[
\operatorname{supported}=\operatorname{True},\quad
\operatorname{complete}=\operatorname{True},\quad
\operatorname{citations\_aligned}=\operatorname{True}
\]
**خروجی:** پاسخ پشتیبانیشده با citation.
**مثال مرزی:** اگر تلاش ۱ هنوز پوشش \(\frac{2}{3}\) داشته باشد، تلاش ۲ انجام میشود. اگر پس از تلاش ۲ نقص باقی بماند، `fallback = "evidence_insufficient"` خواهد بود.
```mermaid
sequenceDiagram
participant G as Generator
participant E as Evaluator
participant S as Evidence
G->>E: پاسخ اولیه
E->>S: تطبیق ادعا و شاهد
S-->>E: گزارش نقص
E-->>G: repair هدفمند
G->>E: پاسخ اصلاحشده
E-->>G: قبول یا fallback
```
قرارداد توقف و fallback امن
**شرایط توقف موفق:**
- همه ادعاهای مهم شاهد دارند: \(\operatorname{coverage}=1\)
- citation هر ادعا با شاهد همان ادعا همراستاست.
- همه بخشهای سؤال پاسخ داده شدهاند.
**شرایط توقف ناموفق:**
- `attempt >= max_attempts`
- یا شواهد کافی برای ادعای مهم وجود ندارد.
**Fallback خوب:**
- **صریح:** «شواهد کافی برای پاسخ قطعی وجود ندارد.»
- **دقیق:** ادعاهای بیپشتوانه را نام میبرد.
- **بدون حدس:** پاسخ ناقص را بهعنوان واقعیت برنمیگرداند.
**مثال نهایی:** اگر دو ادعا داشته باشیم و فقط ادعای اول شاهد داشته باشد، \(\operatorname{coverage}=\frac{1}{2}\) است؛ پس حتی با تمام شدن تلاشها، خروجی باید کمبود ادعای دوم را اعلام کند، نه اینکه مقدار آن را حدس بزند.
**الگوی نهایی در LangGraph:**
```mermaid
flowchart LR
V["Verify state"] -->|"pass"| F["final_answer"]
V -->|"repairable و attempts remain"| R["repair node"]
R --> V
V -->|"not repairable یا limit reached"| U["uncertainty fallback"]
```
- **Where this leads → 9.2:** همین فیلدها به معیارهای regression test تبدیل میشوند.
- **Where this leads → 10.1:** عامل نهایی از routing، citation، verification و bounded repair استفاده میکند.
بازگشت به دوره