31 KiB
Target Architecture — Scalable Tool Discovery (1,200+ Tools)
وضعیت: Target State مشخص است. Phase 0–14 در کد پیاده شدهاند. Indexed Retrieval روی Canary ۵٪ است و Promotion به ۱۰٪ HOLD است تا ترافیک زنده جمع شود. Adaptive K / Hybrid / Progressive خاموشاند.
تاریخ: ۲۱ اوت ۲۰۲۶
Source of Truth کد: hesabixAPI/app/services/ai/
مرتبط: dynamic-tool-discovery.md
LLM فقط حداقل Tool و Schema لازم برای Task جاری را میبیند. مقیاس هدف ۱۲۰۰+ است؛ ۱۸۰ Tool فعلی نقطهٔ شروع مهاجرت است نه سقف طراحی.
1. Current Architecture
وضعیت زنده پس از Phase 0:
- حلقه در
AIService.chat_completion_stream - ثبت Static در
AIFunctionRegistry(Singleton) - فیلتر: Role + Permission + Execution mode + Intent کلیدواژهای
- سقف: ۴۸ (analyzer) / ۱۲۸ (supervised/autonomous)
- Schema کامل زیرمجموعه از
load_tool_schemas؛ ساخت JSON فقط برای نامهای Discovery (نه کل ۱۸۰) - روی سیم: Provider هنوز
toolsرا در هر iteration میگیرد مگر K کوچکتر شود یا cache مخصوص Provider فعال شود - MCP = سرور خروجی (
POST /api/v1/ai/mcp)، نه Discovery داخل Agent - ۱۸۰
AIFunctionواقعی
flowchart TB
User --> API[chat.py]
API --> AIS[AIService]
AIS --> Perm[Tenant + Role + Permission]
Perm --> Sec[side_effect / mutation filter]
Sec --> Intent[Keyword categories + rank cap]
Intent --> LLM[Provider tools JSON]
LLM --> Guard[Write guard]
Guard --> Exec[Registry handler]
پس از Phase 2، Security یک مرز سخت قبل از Ranking است.
پس از Phase 3، همهٔ Consumerهای داخلی از discover_tools() برای انتخاب نام استفاده میکنند؛ Schema هنوز جدا در get_available_functions بارگذاری میشود.
مرتبط: phase-2-security-first-discovery.md · phase-3-unified-discovery-api.md
2. Target Architecture
Discovery داخل Orchestrator انجام میشود (نه وابسته به مدل). LLM فقط Top-K با Schema کامل میبیند؛ در Task مبهم یک meta-tool search_tools برای گسترش کنترلشده دارد.
flowchart TB
User --> Agent
Agent --> Intent[Intent / task analysis]
Intent --> Sec[Tenant → Role → Permission → execution_mode → side_effect policy]
Sec --> Cand[Candidate set — only allowed tools]
Cand --> Disc[Discovery: metadata + keyword + semantic]
Disc --> Rank[Tunable ranker]
Rank --> K[Top-K 5–20]
K --> Schema[Progressive schema load]
Schema --> LLM
LLM -->|tool_call in K| Exec[Execute + guard]
LLM -->|need more| SearchTool[search_tools meta]
SearchTool --> Disc
لایهها از پایین به بالا:
| لایه | مسئولیت | وابسته به LLM؟ |
|---|---|---|
| Tool Manifest + AIFunction | هویت، دامنه، امنیت، alias | خیر |
| Security gate | Tenant / permission / mode | خیر |
| Discovery engine | جستجو روی candidate مجاز | خیر |
| Schema loader | JSON کامل فقط برای K | خیر |
| Provider adapter | تبدیل OpenAI/Anthropic/Local | بله فقط format |
| Agent loop | فراخوانی و نتیجه | بله |
3. Design Principles
- Minimum tool set: پیشفرض ۵–۲۰ Schema؛ افزایش پویا با سقف مطلق (پیشنهاد ۳۲ Schema کامل در یک call).
- Security before search: Tool بدون اجازه هرگز candidate نمیشود.
- Single source of truth: Manifest + فیلدهای
AIFunctionپس از bind. لیستهای Intent/Write/Risk مشتق میشوند. - Provider-agnostic: کاتالوگ و Discovery فرمت مدل نمیدانند.
- Fan-in over explosion: ۱۲۰۰ قابلیت ≠ ۱۲۰۰ function. Entity/report/skill اول.
- Measurable: هر تغییر Discovery با eval طلایی و متریک توکن/latency سنجیده میشود.
- No fashion-driven MCP: MCP برای execution بیرونی میماند تا ارزش Discovery داخلی ثابت شود.
- Incremental migration: رفتار ۱۸۰ Tool تا eval سبز نشکند؛ سقف ۴۸/۱۲۸ تا Phase Discovery عوض نشود.
4. Tool Registry
دو بخش جدا که با bind یکی میشوند:
AIFunction (runtime)
├── identity: name, version, description
├── handler + parameters_schema (schema_version)
├── security: roles, permissions, requires_approval, risk_level,
│ is_readonly, is_agent_internal, always_confirm, side_effect
├── discovery: domains, capability, namespace, aliases, keywords,
│ examples, companion_tools, is_core, intent_write
└── lifecycle: enabled, deprecated, replacement
چرا این فیلدها (و نه بیشتر):
| فیلد | دلیل قابل اندازهگیری |
|---|---|
domains |
فیلتر Intent / metadata بدون regex روی نام |
capability |
آمادهٔ routing دو مرحلهای در ۵k+ بدون تغییر مدل |
namespace |
جلوگیری از تصادم نام در ۱۲۰۰+ |
aliases / keywords / examples |
keyword + later embedding text |
companion_tools |
write بدون حذف lookupهای لازم |
is_core |
سیگنال ranking / tie-break / fallback — نه ظرفیت رزرو Top-K |
intent_write |
کشف نوشتن جدا از requires_approval |
always_confirm / side_effect |
سیاست destructive قبل از LLM |
enabled / deprecated / replacement |
رشد کاتالوگ بدون حذف ناگهانی |
version / schema_version |
مهاجرت Schema بدون rename اجباری |
عمداً در Phase 1 نیست (تا نیاز اندازهگیری شود): embedding vector، tenant_allowlist جدا (همان business_context + permission)، provider compatibility matrix (همه Toolها روی هر سه Provider میروند مگر supports_tools مدل).
Handler در Python میماند. Metadata در ai_tool_manifest.py تا Intent بدون instantiate سرویسها کار کند.
5. Unified Metadata
ai_tool_manifest.TOOL_MANIFEST
│
ai_tool_index.ToolIndex
┌────────┼────────┐
▼ ▼ ▼
Intent Rank Write/Risk
│ │ │
└────────┼────────┘
▼
registry.register → bind_manifest
▼
AIFunction
پس از Phase 1:
_CATEGORY_TOOLS,_WRITE_TOOLS,_CORE_TOOL_NAMES, companions از IndexTOOL_ALIASESاز IndexWRITE_FUNCTIONSوHIGH_RISK_ALWAYS_APPROVEاز Index- Permission map (
ai_permission_map) همچنان نگاشت رشتهٔ permission به UI است — آن نگاشت سیاست محصول است نه هویت Tool؛ هویت Tool همانrequired_permissionsرویAIFunctionاست - l10n (
ai_tool_keys) برچسب UI است نه Discovery؛ همگامسازیاش Phase جدا (اختیاری)
6. Security Filtering
Security is a hard boundary, not a ranking signal.
A tool must be authorized before it can become a discovery candidate.
Discovery reduces context; it must never weaken authorization.
ترتیب اجباری (پس از Phase 2 در کد است):
flowchart LR
All[All enabled tools] --> T[Tenant / business_context]
T --> R[allowed_roles]
R --> P[required_permissions]
P --> E[execution_mode]
E --> S[side_effect + query mutation]
S --> C[Authorized candidate set]
C --> D[Intent / Ranking]
پیادهسازی: ai_tool_security.filter_security_candidates قبل از select_tool_names / select_catalog_tool_names.
- analyzer: فقط
READ_ONLY - supervised/autonomous: write فقط با mutation نوشتن؛ delete/export/execute فقط با mutation صریح
- UNKNOWN → NOT CANDIDATE
- Ranking /
prefer_names/ union مهارت نمیتواند Tool غیرمجاز را برگرداند - Execution Guard (
ai_write_guard) آخرین خط دفاع میماند — Discovery جایگزین آن نیست
جزئیات: phase-2-security-first-discovery.md
7. Capability Architecture
سه مفهوم با شغل جدا (Phase 4):
- Domain: سطل Intent کلیدواژهای موجود (
financial,warehouse,people, …) - Capability: کلید نقطهای جستجوی آینده (
financial.invoice,reports.sales, …) - Namespace: بخش اول capability (
financial,reports) برای ضدتصادم در ۱۲۰۰+
تصمیم: در ۱۲۰۰ Tool، router دو مرحلهای Capability→Tools ارزش پیچیدگی runtime را ندارد. فیلتر domain + hybrid search کافی است. فیلد capability از حالا granular است تا Embedding/Hybrid بدون مهاجرت مدل داده کار کند.
Fan-in موجود بماند:
query_business_data(~۳۰ entity) — یک Schema، permission per entity در handlerget_report(~۳۸ type) — یک Schema، کاتالوگ گزارش جدا
Tool جدا فقط وقتی Schema، permission یا ریسک با sibling فرق دارد (مثلاً delete_invoice ≠ search_invoices).
Generic query خطر دقت و امنیت دارد اگر entity/permission در خود Tool چک نشود. امروز چک میشود؛ این قرارداد حفظ شود.
8. Tool Discovery
موتور جدا از LLM: ai_tool_discovery.discover_tools.
ورودی: permissioned_names + query + mode + limit + channel + history.
خروجی: DiscoveryOffer با ToolCandidate سبک (بدون Schema).
Chat / Subagent / CRM / Ticket / Workflow از طریق get_available_functions به همین API میرسند.
MCP tools/list هنوز کاتالوگ permissionخورده است (قرارداد کلاینت خارجی).
استراتژی فعال: KeywordIntentStrategy. Semantic/Hybrid رزرو شده و فعال نیست.
9. Hybrid Search
ترتیب Target پس از security:
candidate (permissioned)
→ metadata filters (domain, side_effect, enabled)
→ keyword / alias / BM25 روی search_text
→ optional vector روی همان search_text
→ merge + score
→ rerank tunable
→ Top-K
→ schema loader
تا ~۲۰۰۰ Tool، keyword+index حافظه کافی است. Vector وقتی eval نشان دهد paraphrase فارسی fail میشود.
10. Ranking
امتیاز وزنی و قابل تنظیم از config/eval — وزن را حدس نمیزنیم:
score = w1*semantic + w2*keyword + w3*alias + w4*core
+ w5*domain_match + w6*historical (capped)
+ w7*specificity - w8*ambiguity
وزنها در فایل eval کالیبره میشوند. History فقط به عنوان boost ضعیف با سقف و با decay؛ هرگز Tool بدون permission را بالا نمیآورد.
11. Progressive Disclosure
سه سطح vis-à-vis LLM:
- Always: core (~۱۲) + در صورت نیاز
search_tools(schema کوچک) - Task K: ۵–۲۰ Schema کامل
- On demand: نتیجه
search_tools→ round بعد حداکثر چند Schema اضافه با سقف مطلق
مدل نام خارج از offer را اجرا نمیکند (fail-closed).
12. Schema Loading
Schema کامل فقط برای offer فعلی. منبع: AIFunction.parameters_schema از طریق load_tool_schemas().
Discovery (ToolCandidate) JSON Schema ندارد.
هدف iteration 2+: اگر hash مجموعه Tool عوض نشده، از نظر معماری همان offer است. محدودیت: بسیاری از Providerها tools را در هر call میخواهند. استراتژی:
- داخلی:
ToolSchemaCachekeyed by(name, schema_version)؛ از ساخت مجدد JSON پرهیز - session:
ToolContextStateفقط schemaهای جدید را میسازد - Anthropic: cache_control روی بلوک پایدار (system)؛ tools جدا است
- OpenAI رسمی:
prompt_cache_keyبرای prefix؛ tools ممکن است cache نشود - Local/vLLM: فرض resend هر call؛ بهینهسازی = کوچک کردن K نه حذف فیلد API
پس «نفرستادن Schema» فقط جایی تضمین میشود که API Provider اجازه دهد. کاهش K اثر قطعی دارد.
Schema cache is not an authorization cache. مجوز هر round جداگانه اعمال میشود.
جزئیات: phase-7-progressive-schema-loading.md
13. Caching
| کش | محتوا | محدوده |
|---|---|---|
| Manifest/Index | Metadata | فرایند، تا deploy |
| Schema JSON per name | تعریف | فرایند |
| Tool-set hash | offer | session |
| Read-only results | خروجی handler | امروز in-process TTL ۶۰s؛ بعداً Redis چند-worker |
| Prompt cache Provider | system prefix | طبق ai_prompt_cache.py |
کش Schema سراسری است؛ فیلتر permission همیشه per-request.
14. Provider Abstraction
کاتالوگ داخلی خنثی است. AIProviderBase همان adapter است:
- OpenAI / Local:
tools: [{type:function, function:{name,description,parameters}}] - Anthropic:
_openai_tools_to_anthropic
Discovery به این لایه وصل نمیشود. مدل بدون supports_tools اصلاً offer نمیگیرد (رفتار فعلی).
15. MCP Strategy
| نقش | تصمیم |
|---|---|
| Tool Execution برای کلاینت خارجی | بله — همین امروز |
| Tool Discovery برای Agent داخلی | خیر در Target نزدیک |
| tools/list بدون سقف | باید بعداً همان discover_tools را صدا بزند |
دلیل: Auth، tenant، execution_mode و eval داخلی از قبل در Hesabix است. MCP Discovery یعنی وابستگی پروتکل و کلاینت. وقتی کاتالوگ چند مستأجر/افزونه خارجی شد، MCP بهعنوان منبع Tool شخص ثالث بررسی میشود نه جایگزین Index داخلی.
16. Database Strategy
| مقیاس metadata | ذخیره |
|---|---|
| ۱۸۰–۱٬۲۰۰ | Manifest در کد + RAM index (الان) |
| ~۱۰٬۰۰۰ | همان + اختیاری جدول PG برای embedding Tool |
| ~۱۰۰٬۰۰۰ | PostgreSQL + pgvector (همان الگوی ai_knowledge_chunks) |
Redis برای جستجو لازم نیست؛ برای result cache چند-worker بله.
در این مرحله migration نیست. Vector DB جدا تا وقتی pgvector در production ناکافی ثابت شود توصیه نمیشود.
17. Evaluation
گسترش tests/test_ai_tool_intent_gold.py + موارد منفی destructive:
برای هر کیس: query، expected tools، forbidden tools، K، tokens تخمینی، latency discovery.
هدف محصولی: Discovery accuracy قابل گزارش (مثلاً ≥۹۵٪ recall روی طلایی واقعی ۱۸۰ نام، صفر نشت delete_* روی گزارشخوانی).
18. Observability
رویداد tool_discovery (بدون مبلغ/نام مشتری):
tenant_id, user_id, mode, candidate_count, selected[], scores[], search_ms, schema_tokens, iteration, hash
اجرا جدا: موفقیت/خطای handler با کد خطا، نه payload مالی.
19. Failure Handling
| حالت | رفتار |
|---|---|
| صفر candidate پس از permission | پاسخ: دسترسی/حالت اجرا؛ Tool جعلی نباشد |
| صفر پس از search | یک بار گسترش domain؛ سپس clarification |
| Tool اشتباه / نتیجه خالی | ضدloop موجود (AGENT_MAX_IDENTICAL_TOOL_*) |
| نام خارج از offer | unknown_tool_result |
| search_tools بینتیجه | توقف گسترش؛ سؤال روشنسازی |
Fallback عمومی به «همهٔ financial» فقط با سقف خیلی کوچک و بدون write/delete.
20. Scalability
| N metadata | Bottleneck |
|---|---|
| ۱۸۰ | LLM و تکرار Schema، نه search |
| ۱٬۲۰۰ | همان + Intent شلوغ اگر K کم نشود |
| ۵٬۰۰۰ | نیاز به hybrid + search_tools |
| ۱۰٬۰۰۰ | index RAM هنوز کوچک؛ schema load باید lazy باشد |
| ۱۰۰٬۰۰۰ | pgvector + capability pre-filter؛ LLM همچنان Top-K |
Bottleneck هزینه همیشه LLM است اگر K کنترل شود.
21. Migration Strategy
- Phase 1: Manifest = SSOT (انجامشده در همین کار)
- رفتار ۴۸/۱۲۸ تا eval Phase Discovery عوض نشود
- Dual-read حذف شد؛ لیستهای کهنه نباید برگردند
- Tool جدید = Manifest entry اجباری + register (تست پوشش نامها)
- هرگز REST را 1:1 به Function تبدیل نکنید
22. Phase Breakdown
| Phase | هدف | خروجی | وابسته |
|---|---|---|---|
| 0 | تحلیل | dynamic-tool-discovery.md |
— |
| 1 | Unified metadata / SSOT | Manifest + Index + bind | 0 |
| 2 | Security-first discovery | filter_security_candidates قبل از rank؛ UNKNOWN fail-closed |
1 |
| 3 | Discovery engine | discover_tools() واحد؛ هنوز همان K≈۴۸ برای سازگاری |
1–2 |
| 4 | Tight Top-K + progressive | analyzer ۵–۲۰؛ search_tools |
3 |
| 5 | Hybrid / embedding | روی embedder دانشنامه یا PG | 4 + eval |
| 6 | Ranking tunable + history cap | وزن از eval | 5 |
| 7 | Schema/tool-set cache + بودجه tools | hash session؛ تخمین توکن tools | 4 |
| 8 | Eval + observability | طلایی ۱۸۰ واقعی + متریک | 3+ |
| 9 | MCP list از discover_tools | سقف MCP | 3 |
| 10 | Fan-in رشد دامنه / skills | پوشش ۱۲۰۰ قابلیت بدون ۱۲۰۰ function | محصول |
| 11 | Redis result cache / worker | مقیاس کاربر | 7 |
| 12 | Production hardening | cap مطلق، feature flag، rollback | همه |
Phase 0–10 در کد هستند. Ranking اصلاح شد (Recall@15 = 97.5٪). Schema Loading از Discovery جدا است. Adaptive K و Hybrid و Progressive و Indexed Candidate Retrieval بهصورت flag خاموشاند. سقف production هنوز ۴۸/۱۲۸ است. Canary Adaptive K آماده و HOLD است. Inverted index مشتق برای Candidate Retrieval ساخته شد ولی مسیر آنلاین همان Ranker کامل است.
اصول Phase 6:
- Core is a ranking signal, not a reserved capacity.
- Every authorized candidate must compete on relevance before Top-K truncation.
- Do not introduce semantic retrieval to compensate for a deterministic ranking bug.
search_tools: گزینهٔ انتخابشده
| گزینه | Token | Latency | Accuracy | وابستگی مدل | پیچیدگی | Debug | امنیت | مقیاس |
|---|---|---|---|---|---|---|---|---|
| A Orchestrator only | بهترین | بهترین | خوب با rank | کم | متوسط | بالا | بالا | تا ~۲k |
| B فقط Tool LLM | بد در دور اول | +۱ نوبت | وابسته به مدل | زیاد | کم ظاهری | ضعیف | خطرناک اگر قبل از permission | ضعیف |
| C Hybrid (انتخاب) | خوب | یک نوبت اضافه فقط در miss | بالا | کم | متوسط | بالا | permission قبل از search_tools | ۱۲۰۰–۱۰k |
Orchestrator همیشه K میدهد. search_tools Schema کوچک دارد و فقط روی candidate مجاز جستجو میکند.
23. Risks
- Tight K → از دست رفتن Tool دمبلند (جبران: search_tools + eval)
- وزن ranking حدسی (ممنوع تا eval)
- Provider که tools را هر بار میخواهد (کاهش K نه حذف فیلد)
- انفجار ۱۲۰۰ Function جدا (خلاف fan-in)
- History bias (سقف boost)
24. Open Questions
- مدل/gateway واقعی production و اثر cache روی
tools - فعال بودن pgvector در production
- آیا صوت/تلگرام همان
get_available_functionsرا صدا میزنند - سقف مطلق Schema در یک call (پیشنهاد ۳۲ — نیاز به تأیید محصول)
Phase 1 — آنچه در کد فرود آمده
ai_tool_spec.py— انواع، domain، capability، side_effectai_tool_manifest.py— یک رکورد per Toolai_tool_index.py— ایندکس مشتق +bind_manifestAIFunctionفیلدهای Discovery/امنیت- Intent / aliases / WRITE_FUNCTIONS / HIGH_RISK از Index
رفتار سقف ۴۸/۱۲۸ عمداً عوض نشده است.
Phase 2 — آنچه در کد فرود آمده
ai_tool_security.py— mutation کوئری، کلاس امنیت Tool،filter_security_candidatesget_available_functionsفیلتر امنیت را قبل از Ranking اعمال میکند- Intent/catalog فقط روی مجموعهٔ مجاز rank میکنند
filter_function_definitionsfail-closed است- Execution Guard و MCP
tools/callدستنخوردهاند
جزئیات: phase-2-security-first-discovery.md
Phase 3 — آنچه در کد فرود آمده
ai_tool_discovery.py—discover_tools,DiscoveryOffer,KeywordIntentStrategy- Chat / Subagent از همین API استفاده میکنند؛ Schema جدا بارگذاری میشود
- سقف پیشفرض ۴۸/۱۲۸ حفظ شد؛
DISCOVERY_HARD_MAX=256 - MCP
tools/listعمداً dynamize نشد - Vector / hybrid / progressive schema پیاده نشد
جزئیات: phase-3-unified-discovery-api.md
Phase 4 — آنچه در کد فرود آمده
- Permission خالی دیگر fail-open نیست؛ سیاست صریح (
handler/self_scoped/agent_internal/user_context) یاrequired_permissionsواقعی upsert_memory_entryبهعنوان WRITE طبقهبندی شد- Capability نقطهای (
reports.sales,financial.invoice, …) +search_text - Quality score فقط برای audit؛ Ranking عوض نشد
جزئیات: phase-4-permission-metadata-hardening.md
Phase 4 improves the quality and trustworthiness of the catalog; it does not improve retrieval yet.
Phase 5 — آنچه در کد فرود آمده
- Gold ۴۷۳ query + Recall/MRR/Precision/NDCG روی
discover_tools(بدون LLM) - K sweep نشان داد Tight Top-K در Keyword/Intent فعلی امن نیست
- سقف production همان ۴۸/۱۲۸ ماند
DiscoveryOfferفیلد confidence دارد؛ کاندیداها score-desc مرتب میشوند
جزئیات: phase-5-tight-topk-evaluation.md
Phase 6 — آنچه در کد فرود آمده
rank_and_cap: score همهٔ authorized candidates، سپس Top-K. Core/prefer دیگر ظرفیت رزرو نمیکنندis_coreفقط tie-break است؛fallback_namesجدا از ranked results و بدون Schema کامل- No-match احتیاطی: empty offer فقط وقتی
top_score<=0و query دامنهٔ ابزار نیست (FN empty روی Gold = ۰) - Alias/example فقط برای missهای Gold؛ کاتالوگ ۱۸۰ تایی ماند
- سقف production همان ۴۸/۱۲۸؛
Recall@15 = 97.52٪روی Gold v1
جزئیات: phase-6-ranking-correction.md
Phase 7 — آنچه در کد فرود آمده
load_tool_schemasجدا ازdiscover_tools؛ToolCandidateبدون JSON SchemaToolSchemaCache+ versioning (declared.hash)؛ cache ≠ authorizationToolContextStateدر Chat و Subagent؛ CRM / Ticket / Workflow از همان loader- Progressive loading opt-in (
PROGRESSIVE_SCHEMA_LOADING=False)؛ production K همان ۴۸/۱۲۸ - Eval: Progressive K=15 حدود ۵۴٪ توکن schema کمتر از Current K=48 اگر مجموعهٔ کوچکتر روی سیم برود
- MCP
tools/listعوض نشد
جزئیات: phase-7-progressive-schema-loading.md
Phase 8 — آنچه در کد فرود آمده
DiscoveryConfidence+AdaptiveKPolicy(برنده eval: tight، Avg K=۱۰.۱۹، Recall=۹۶.۶۱٪) — flag خاموش- Hybrid اختیاری روی ranker واژهای؛ n-gram metadata؛ وزن lexical_dominant بهترین Hybrid است ولی از Keyword بهتر نیست
- Semantic فقط روی authorized؛ cache/fingerprint ≠ authorization
ProviderContextPolicy+ fingerprint؛ Anthropic last-tool cache hint؛ Local = resend- Rediscovery حداکثر ۱ بار؛
tool_discovery_misstelemetry - Benchmark مصنوعی تا ۱۰٬۰۰۰ metadata؛ Schema Top-15 ≈۳.۵ms
- Production همچنان Analyzer=۴۸ / Autonomous=۱۲۸
جزئیات: phase-8-adaptive-hybrid-context.md
Phase 9 — Production Canary architecture
هدف: رفتار Adaptive K را روی ترافیک واقعی بسنجید؛ Offline Gold را با Tool Discovery Success زنده اشتباه نگیرید.
Tenant + Role + Permission + mode
↓
Keyword/intent ranker (یکسان برای هر دو بازو؛ Hybrid OFF)
↓
Wide candidates (Analyzer 48 / Autonomous 128)
↓
┌─ control ──────────── effective K = 48/128
hash(biz, user) % 100
└─ experiment ──────── Adaptive tight truncate (≈10/15/20)
↓
load_tool_schemas (Progressive flag جدا و خاموش)
↓
LLM → typed miss / rediscovery≤1 / execution
قواعد:
ADAPTIVE_DISCOVERY_KوADAPTIVE_K_ROLLOUT_PERCENTمستقل ازPROGRESSIVE_SCHEMA_LOADINGهستند.- Assignment با SHA256 پایدار است؛ شناسه در Log نیست.
retrieval_miss/schema_miss/authorization_failure/execution_failureرویدادهای جدا هستند.- Tool مجازِ unoffered = Discovery failure. Tool غیرمجاز هرگز rediscover نمیشود.
- Metric روی سیم:
schema_count+wire_schema_tokens— نه cache hit ارائهدهنده. - Hybrid Canary ندارد. Semantic خطی ۱۰k Production نیست.
- Phase 10: inverted index + vector ANN روی metadata، سپس ranker فعلی، Adaptive K، Progressive Schema.
تصمیم فعلی: HOLD (نمونه زنده < ۵۰۰ در هر بازو).
جزئیات: phase-9-adaptive-k-canary.md
Phase 10 — Scalable candidate index
Tool Registry → Security → Candidate Retrieval (inverted ⊕ optional ANN)
→ Existing Ranker → Adaptive K → Progressive Schema → LLM
- Registry = source of truth. Index = derived posting lists + capability/domain/namespace maps.
INDEXED_CANDIDATE_RETRIEVAL = False— Production هنوز همهٔ Authorized را rank میکند.- Candidate Recall@100 = ۹۸.۸۷٪ (اشباع؛ ۵ miss متادیتا). هدف ۹۹٪+ نرسید → flag خاموش ماند.
- Vector ANN / pgvector برای Tool ساخته نشد. pgvector موجود برای دانشنامه است.
- Neural embedding و Hybrid Production خاموشاند.
- Adaptive K Promoted نشد.
جزئیات: phase-10-scalable-tool-index.md
Phase 11 — Index quality and independent canary
پنج miss متادیتا پوشش داده شد. Candidate Recall@100 = ۱۰۰٪. N بزرگ نشد.
Control: Authorized → Phase 6 Ranker → K=48/128
Experiment: Authorized → Indexed candidates (N=100) → Phase 6 Ranker → K=48/128
INDEXED_CANDIDATE_RETRIEVAL = FalseوINDEXED_CANDIDATE_ROLLOUT_PERCENT = 0.- Assignment با salt جدا (
indexed-retrieval-v1) از Adaptive K. - Fallback خالی → Ranker روی همان Authorized Set؛ هرگز Global Registry.
indexed_retrieval_miss≠retrieval_miss.- Adaptive K HOLD. Hybrid OFF.
جزئیات: phase-11-index-quality-canary.md
Phase 12 — Indexed retrieval production canary
تنها متغیر: Candidate Retrieval (full authorized vs indexed N=100). Ranker / K / Schema / Adaptive / Hybrid ثابت.
INDEXED_CANDIDATE_RETRIEVAL = False
INDEXED_CANDIDATE_ROLLOUT_PERCENT = 5
INDEXED_CANDIDATE_FALLBACK = True
- Assignment: SHA256(
indexed-retrieval-v1+ business_id + user_id). شناسه لاگ نمیشود. - Kill switch بدون دستزدن به Adaptive:
HESABIX_INDEXED_CANDIDATE_KILL=1یاHESABIX_INDEXED_CANDIDATE_RETRIEVAL=0. - Fallback reasons (Phase 13 canonical):
empty/low_candidate_quality/stale_index/index_error/index_inconsistency/unknown. - Live promotion: HOLD تا ۵۰۰ نمونه در هر بازو.
جزئیات: phase-12-indexed-retrieval-canary.md
Phase 13 — Production evidence gate
شواهد Gold و Production جدا میمانند. رویداد indexed_candidate_exposure، شمارندههای بازو، hit/miss/empty/stale، و index_success ≠ task_success. Auto-promotion ممنوع. Kill switch بدون restart. نردبان ۵/۱۰/۲۵/۵۰/۱۰۰ فقط با تصمیم صریح.
این محیط: Live control = 0، Live experiment = 0 → HOLD. Adaptive K / Hybrid / Progressive همچنان OFF.
جزئیات: phase-13-production-evidence-gate.md
Phase 14 — Live canary validation
فقط جمعآوری و ارزیابی شواهد Production. Gold / Control / Experiment جدا. live_control_requests / live_experiment_requests. indexed_retrieval_error و Fallback counters جدا از Miss. Task completion ساختگی نیست. Channel-specific HOLD: HESABIX_INDEXED_CANDIDATE_CHANNEL_HOLD. این محیط همچنان ۰/۰ → HOLD.