Skip to content

الأدلة الإرشادية

الوكلاء والأدوات

لا يقود Oloproof الوكيلَ. فوكيلك يشغِّل حلقته الخاصة، ويستدعي أدواته الخاصة، ويسجِّل ما حدث بوصفه مُخرَجًا من نوع agent_trajectory/v1. ويُقرأ كل مقياس من مقاييس الوكيل من ذلك السجل، لذا فإن السجل هو التكامل بأكمله.

examples/support_agent/ هو المشروع الذي تشغِّله هذه الصفحة: أربعون طلب استرداد، ووكيل حتمي، ومن دون بيانات اعتماد أي مزوِّد.

تسجيل مسار

داخل النظام، ابنِ الخطوات وهي تحدث وسلِّمها إلى مسجِّل الحالة:

from oloproof import AgentConstraintCheck, AgentStep, AgentTrajectory, current_case, system


@system(name="support-agent", version="slice-e-example", records=("agent_trajectory/v1",))
def run(case):
    steps = []
    for name, arguments in plan(case):
        steps.append(AgentStep(index=len(steps) + 1, kind="tool_call", tool_name=name, arguments=arguments))
        result = getattr(tools, name)(**arguments)
        steps.append(AgentStep(index=len(steps) + 1, kind="tool_result", tool_name=name, result=result))

    current_case().agent_trajectory(
        AgentTrajectory(
            steps=tuple(steps),
            terminal_status="success" if refunded else "failure",
            truncated=truncated,
            step_limit=STEP_LIMIT if truncated else None,
            constraints=(
                AgentConstraintCheck(name="no_deletion", passed=deletion is None, step_index=...),
            ),
        )
    )
    return {"answer": "refunded" if refunded else "unresolved"}

الغرض من كل جزء:

الحقلما يسجِّله
AgentStep.kindmessage أو tool_call أو tool_result أو observation أو decision أو final
AgentStep.tool_name، arguments، resultالاستدعاء وما عاد منه
terminal_statussuccess أو failure أو unknown
truncated، step_limitأن الوكيل بلغ حدَّه وأن التتبُّع يتوقف قبل اكتماله
constraintsفحوص أجرتها بيئتك، كلٌّ منها مع الخطوة التي رصدها
checkpointsنقاط يمكن لإعادة التشغيل أن تستأنف منها، بصيغة AgentCheckpoint

يُعلن النظام أنه يسجِّل المسار، في المزيِّن وفي oloproof.yaml:

system:
  name: support-agent
  version: slice-e-example
  callable: app:run
  records: [agent_trajectory/v1]

من دون records:، ترفض مُقيِّمات الوكيل العمل بدلًا من أن تعدّ كل حالة مفقودة.

ما تُعلنه الحالة

الحالة التي ينبغي أن تستدعي أدوات بعينها، بترتيب بعينه، تنصّ على ذلك تحت expected.tools:

{"id": "case_001", "input": {"order_id": "ord-002", "behaviour": "clean"}, "expected": {"answer": "refunded", "tools": ["lookup_order", "issue_refund"]}, "metadata": {"surface": "chat", "behaviour": "clean"}}

تنصّ expected.tools: [] على أن الحالة لا تتوقع أي استدعاء لأداة على الإطلاق، وتُحكَم على هذا الأساس. أما إغفال المفتاح فيعني أن اختيار الأداة لا ينطبق على الحالة: إذ يستبعدها agent_tool_sequence وagent_no_undeclared_tool مع no_declared_tools. فهي تغادر المقام بدلًا من أن تُعدّ نجاحًا، لأن المعدَّل المُضخَّم بحالات لم تُقَس قط ليس معدَّلًا. والقيمة التي ليست قائمة بأسماء أدوات تُرفض قبل التشغيل.

المُقيِّمات

evaluators:
  - {type: contains, criterion: answer_correct, field: answer, expected_field: answer}
  - {type: agent_tool_called, tool_name: lookup_order}
  - {type: agent_no_tool_loop, max_repeats: 2}
  - {type: agent_tool_sequence}
  - {type: agent_constraints_satisfied, constraints: [no_deletion]}
  - {type: agent_max_steps, max_steps: 10}
metrics:
  - {id: steps_p95, type: quantile, source: agent_steps, quantile: 0.95}
  - {id: tool_calls_p50, type: quantile, source: agent_tool_calls, quantile: 0.5}
slices: [metadata.surface, first_tool, repeated_action, "trajectory_length:4,8"]
min_slice_support: 3
النوعينجح حينيأخذ
agent_tool_calledتُستدعى الأداة min_calls مرة على الأقلtool_name، min_calls (الافتراضي 1)
agent_no_tool_loopلا يتكرر أي استدعاء متطابق، بالأداة نفسها والوسائط نفسها، أكثر من max_repeats مرة متتاليةmax_repeats (الافتراضي 2)
agent_tool_sequenceتطابق الأدواتُ المستدعاة expected.toolsordered (الافتراضي true)
agent_no_undeclared_toolلا تُستدعى أي أداة من خارج expected.toolsلا شيء
agent_constraints_satisfiedينجح كل قيد مُسمّى سجّلته البيئةconstraints
agent_max_stepsيستغرق التتبُّع max_steps خطوة على الأكثرmax_steps

agent_steps وagent_tool_calls هما التوزيعان الكامنان وراء الأخير، بوصفهما مقاييس مئينية (quantile).

oloproof run
│ answer_correct                 │ 82.5%    │ [67.2%, 92.7%]       │ 33 / 40 observed · 0 missing · 0 excluded   │
│ agent_tool_lookup_order_called │ 100.0%   │ [86.8%, 100.0%]      │ 39 / 39 observed · 1 missing · 0 excluded   │
│ agent_no_tool_loop             │ 74.4%    │ [56.1%, 87.4%]       │ 29 / 39 observed · 1 missing · 0 excluded   │
│ agent_tool_sequence            │ 60.0%    │ [43.3%, 75.2%]       │ 24 / 40 observed · 0 missing · 0 excluded   │
│ agent_constraints_satisfied    │ 92.5%    │ [79.6%, 98.5%]       │ 37 / 40 observed · 0 missing · 0 excluded   │
│ agent_steps_le_10              │ 97.5%    │ [86.8%, 100.0%]      │ 39 / 40 observed · 0 missing · 0 excluded   │
│ steps_p95                      │ 10 steps │ [10, no bound] steps │ p95 of 39 observed · 1 missing · 0 excluded │
│ tool_calls_p50                 │ 2 calls  │ [2, 3] calls         │ p50 of 39 observed · 1 missing · 0 excluded │
│ no-deletion         │ agent_constraints_satisfied │ FAIL                  │ observed_failures_exceed_limit │

يطبِّق القيد البوابةَ كأي معيار آخر. no-deletion قاعدة عدٍّ مرصود مع max_failures: 0: ثلاث حالات استدعت delete_customer، وعبارة "يجب ألا يحدث هذا في مجموعة الاختبار التي شغّلناها" لا تحتاج إلى فترة لحسمها.

تتبُّع يتوقف قبل اكتماله

تبلغ حالة واحدة حدَّ الخطوات لدى الوكيل، فيُسجَّل تتبُّعها truncated. وكل عدٍّ على تتبُّع مبتور هو حدٌّ أدنى، والحدُّ الأدنى يحسم بعض الأسئلة دون بعضها الآخر:

المعيارالحالة المبتورةالسبب
agent_steps_le_10تُخفقالخطوات المسجَّلة تثبت بالفعل أن حدَّ العشر قد تُجووِز
agent_tool_lookup_order_calledمفقودةقد يكون الاستدعاء في الجزء الذي لم يُسجَّل
agent_no_tool_loopمفقودةالتكرار الذي يبلغ نهاية التتبُّع قد يستمر بعدها
steps_p95، tool_calls_p50مفقودةالمئين المحسوب على حدود دنيا ليس مئينًا

مفقودة لا مستبعَدة: تبقى الحالة في المقام غير مرصودة، وتسمح الفترة بأن تكون قد ذهبت في أيٍّ من الاتجاهين. ولهذا يقرأ agent_tool_lookup_order_called [86.8%, 100.0%] على 39 حالة مرصودة بدلًا من الفترة الأضيق التي كانت 39 حالة وحدها ستعطيها.

الشرائح على المسارات

يجمِّع first_tool الحالات بحسب الأداة التي لجأ إليها الوكيل أولًا، أيًّا كانت الأدوات التي استدعاها التشغيل. ويفصل repeated_action الحالات التي كرّرت استدعاءً متطابقًا عن تلك التي لم تفعل. ويوزِّع trajectory_length:4,8 الحالات في فئات عند 1-4 و5-8 و9 خطوات أو أكثر، بحدود تُعلنها أنت لأن حدَّ الفئة يغيّر ما تقوله الشريحة.

│ first_tool=search          │ agent_no_tool_loop             │ 0.0%     │ [0.0%, 57.9%]        │ 0 / 6 observed · 1 missing · 0 excluded ·          │
│ first_tool=search          │ agent_tool_sequence            │ 0.0%     │ [0.0%, 41.0%]        │ 0 / 7 observed · 0 missing · 0 excluded ·          │
│ repeated_action=false      │ answer_correct                 │ 93.1%    │ [77.2%, 99.2%]       │ 27 / 29 observed · 0 missing · 0 excluded ·        │
│ repeated_action=true       │ answer_correct                 │ 60.0%    │ [26.2%, 87.9%]       │ 6 / 10 observed · 0 missing · 0 excluded ·         │

الحلقة إشارة، لا تفسير. لا شيء في المُخرَج يقول إن الاستدعاء المكرَّر هو سبب إخفاق الحالة؛ وحدها إعادة تشغيل تُزيله يمكنها قول ذلك.

عدة وكلاء

يشغِّل examples/triage_agents/ فريقًا من ثلاثة: يسلِّم triage كل طلب إلى billing أو tech، والاسترداد الذي لا يجوز لقسم الفوترة إصداره يُسلَّم إلى شخص. في نظام من عدة وكلاء، تسمّي كل خطوة الوكيلَ الذي نفّذها، ونقل السيطرة خطوة من نوع handoff:

steps.append(AgentStep(index=1, kind="message", agent="triage", arguments={"request": request}))
steps.append(AgentStep(index=2, kind="handoff", agent="triage", to_agent="billing"))
steps.append(AgentStep(index=3, kind="tool_call", agent="billing", tool_name="lookup_order"))

يسمّي المسار وكيلَ كل خطوة أو لا يسمّي أيًّا منها. والتسجيل الذي يسمّي بعضها فقط يُرفض، والذي لا يسمّي أيًّا منها يُعدّ مفقودًا في كل معيار أدناه بدلًا من أن ينجح فيه. وخطوة التسليم اختيارية، إذ تنتقل السيطرة أيضًا حين يتّخذ وكيل آخر الخطوة التالية. وهي الطريقة التي يسجِّل بها التتبُّع انتقالًا إلى وكيل لا يتّخذ أي خطوة، كالشخص.

تُعلن الحالة الوكلاءَ الذين ينبغي أن تمرّ بهم تحت expected.route:

{"id": "case_012", "input": {"topic": "billing", "request": "I was charged twice for order ord-012", "order_id": "ord-012", "behaviour": "escalated"}, "expected": {"answer": "escalated", "route": ["triage", "billing", "person"]}, "metadata": {"topic": "billing", "behaviour": "escalated"}}
evaluators:
  - {type: contains, criterion: answer_correct, field: answer, expected_field: answer}
  - {type: agent_route}
  - type: agent_tool_permissions
    permissions:
      triage: []
      billing: [lookup_order, issue_refund]
      tech: [search_kb]
  - {type: agent_max_handoffs, max_handoffs: 2}
slices: [route]
النوعينجح حينيأخذ
agent_routeيكون الوكلاء الذين تولّوا السيطرة، بعد دمج التكرارات، هم expected.route الخاص بالحالةلا شيء
agent_tool_permissionsيكون كل استدعاء لأداة قد أجراه وكيل تسمح له الخريطة باستدعاء تلك الأداةpermissions
agent_max_handoffsتنتقل السيطرة max_handoffs مرة على الأكثرmax_handoffs

يتضمن المسارُ متلقّي التسليم، فالتتبُّع الذي ينتهي بالتصعيد إلى شخص يكون مساره إلى ذلك الشخص. والحالة التي لا تحمل expected.route لا يعدّها agent_route. وخريطة الأذونات مغلقة: الوكيل الذي لا تُدرجه لا يجوز له استدعاء أي أداة.

│ answer_correct         │ 96.7%    │ [82.7%, 100.0%] │ 29 / 30 observed · 0 missing · 0 excluded │
│ agent_route            │ 86.7%    │ [69.2%, 96.3%]  │ 26 / 30 observed · 0 missing · 0 excluded │
│ agent_tool_permissions │ 93.1%    │ [73.4%, 99.2%]  │ 27 / 29 observed · 1 missing · 0 excluded │
│ agent_handoffs_le_2    │ 86.7%    │ [69.2%, 96.3%]  │ 26 / 30 observed · 0 missing · 0 excluded │

في طلبين أصدر tech استردادًا. كلاهما ينجح في answer_correct ويُخفق في agent_tool_permissions: فقد حصل العميل على الإجابة الصحيحة من نظام خرق أذوناته الخاصة. وطلب واحد يُتبادل ذهابًا وإيابًا بين billing وtech حتى حدِّ الحلقة. تتبُّعه مبتور، لذا فهو يُخفق في المسار وفي حدِّ التسليمات، وهما أمران تحسمهما بادئته بالفعل، ويُعدّ مفقودًا في الأذونات، التي لا تحسمها.

يجمِّع route الحالات بحسب المسار الذي سلكه وكلاؤها، ويُكتب triage>billing. والتتبُّع المبتور لا ينضم إلى أي مجموعة مسار، لأن مساره بادئةٌ لأيّ وجهة ذهب إليها وكلاؤه بعد ذلك.

لا شيء في المُخرَج يقول أيّ وكيل يقع عليه اللوم. فتباعد المسارات يقول أين يفترق مساران. أما أن وكيلًا ما تسبّب في إخفاق فهو ادعاء بشأن ما كان سيحدث لو تصرّف على نحو مختلف، وهو ما لا يمكن أن تُظهره إلا إعادة تشغيل تستبدل ذلك الوكيل، وOloproof لا يُجري مثل هذه الإعادة.

إلى أين بعد ذلك