Lompat ke konten
dokumentasi.id
Commit e4397d1
v1
Star2,4 rb

2.10

Skills Agen dan Pengujian

Skill Deep Eye adalah berkas Markdown biasa di .agents/skills/. Berkas itu tidak dimuat sebagai isi prompt, melainkan hanya didaftarkan sebagai path absolut agar agen memuatnya on-demand lewat read_file saat topiknya relevan. Loader-nya ada di proxy/system.py, dan paket proxy/__init__.py mengekspor find_skill, get_available_skills_block, get_system_prompt, list_skill_index, list_skill_paths, read_skill, serta skills_dir sebagai permukaan publiknya. .agents/skills/README.md:1-3 proxy/init.py:1-20

Jalur discovery dan pemuatan on-demand

proxy/system.py menghitung _REPO_ROOT dari lokasi berkasnya, lalu menetapkan _AGENTS_SKILLS ke <repo>/.agents/skills dan _LEGACY_PROXY_SKILLS ke proxy/skills. Keduanya dipakai oleh _skill_roots(), yang memasukkan direktori legacy hanya bila direktori itu benar-benar ada dan bukan path yang sama dengan .agents/skills. proxy/system.py:12-14 proxy/system.py:33-42

skills_dir() mengembalikan .agents/skills bila direktori itu ada, dan jatuh ke direktori legacy bila tidak. list_skill_paths() menelusuri rglob("*.md") pada setiap root, menyaring berkas non-file, membuang duplikat lewat resolve() di set seen, lalu mengurutkan hasilnya secara case-insensitive berdasarkan as_posix().lower(). proxy/system.py:27-30 proxy/system.py:45-57

list_skill_index() memetakan setiap path menjadi string relatif terhadap skills_dir(). Bila relative_to gagal, ia mencoba relatif terhadap _REPO_ROOT, dan bila masih gagal memakai path absolut. _load_local_skills() merakit daftar itu menjadi teks berisi instruksi read_file dengan path absolut, dengan fallback - (no skills found under .agents/skills/) ketika tidak ada skill. get_available_skills_block() membungkusnya dalam tag <available_skills>, dan get_system_prompt() menggabungkan _METHODOLOGY dengan blok tersebut plus extra opsional. proxy/system.py:60-96

Sisi pembacaan memakai dua fungsi. find_skill() menormalkan substring pencarian dengan lower() dan penggantian \\ menjadi /, lalu mengembalikan path pertama yang cocok pada path relatif atau stem berkas; read_skill() memanggilnya dan mengembalikan isi berkas dengan encoding="utf-8", atau None bila tidak ditemukan. proxy/system.py:99-114

graph TD
  A["proxy.system.get_system_prompt"] --> B["_skill_roots"]
  B --> C["_AGENTS_SKILLS .agents/skills"]
  B --> D["_LEGACY_PROXY_SKILLS proxy/skills"]
  C --> E["list_skill_paths rglob *.md"]
  D --> E
  E --> F["list_skill_index relative path"]
  E --> G["_load_local_skills absolute paths"]
  G --> H["get_available_skills_block"]
  H --> A
  A --> I["agent context available_skills"]
  I --> J["read_skill name_substring"]
  J --> K["find_skill path or None"]
  K --> L["read_text utf-8"]
  style C fill:#f59e0b,color:#000
  style D fill:#dc2626,color:#fff
  style E fill:#336791,color:#fff
  style F fill:#8b5cf6,color:#fff
  style G fill:#8b5cf6,color:#fff
  style J fill:#2d7d46,color:#fff
  style L fill:#2d7d46,color:#fff
%% fig: Discovery skill sampai pemuatan on-demand
%% desc: Loader memindai .agents/skills dan direktori legacy, menyuntikkan path absolut ke blok available_skills, lalu agen membaca satu skill lewat find_skill dan read_skill.
Fig. 1: Discovery skill sampai pemuatan on-demandLoader memindai .agents/skills dan direktori legacy, menyuntikkan path absolut ke blok available_skills, lalu agen membaca satu skill lewat find_skill dan read_skill.

Warna pada diagram memisahkan peran: oranye untuk direktori kanonik, merah untuk jalur legacy yang bisa usang, biru untuk pemindaian berkas, ungu untuk data turunan berupa daftar path, dan hijau untuk jalur baca yang berhasil.

Katalog skill yang tersedia

Direktori .agents/skills/ pada commit ini berisi README plus 28 berkas skill Markdown yang tersebar di beberapa kategori. Kategori workflow memakai satu berkas SKILL.md per direktori, sedangkan kategori teknis memakai berkas per topik. .agents/skills/README.md:5-16

KategoriContoh berkasJenis isi
pentest/, bug-bounty/, red-team/, blue-team/, ctf/, security-ops/pentest/SKILL.mdworkflow SKILL.md
vulnerabilities/vulnerabilities/sql_injection.md, vulnerabilities/ssrf.mdplaybook per kelas kerentanan
reconnaissance/reconnaissance/full_recon.mdSOP recon
protocols/protocols/graphql.mdcatatan protokol
payloads/payloads/xss.md, payloads/lfi.mdpaket payload pendek
tools/tools/deep_eye_cli.md, tools/browser_automation.mdDeep Eye CLI dan browser
technologies/, frameworks/technologies/cloud_security.md, frameworks/nextjs.mdcloud dan framework

Aturan penulisan yang dinyatakan README menetapkan tiga hal: hanya target terotorisasi, satu kelas kerentanan per berkas, dan perintah Deep Eye yang eksak. Format berkas mengikuti templat di docs/create_skills_rules.md dengan bagian Trigger, Overview, Detection, Checklist, Payloads, Tools, Exploitation, Bypasses, dan Remediation. .agents/skills/README.md:18-32

docs/SKILLS.md mengulang kontrak yang sama dalam bentuk ringkas dan menunjuk create_skills_rules.md sebagai rujukan format. Berkas itu juga memuat contoh pemakaian loader: list_skill_index() untuk mencetak indeks dan read_skill("sql_injection")[:300] untuk mengambil potongan isi skill. docs/SKILLS.md:1-35

Panduan lengkap di docs/create_skills_rules.md menjelaskan alasan desainnya: memuat semua skill saat startup akan menghabiskan 50.000+ token context window, sehingga pemuatan on-demand membuat agen hanya membayar biaya konteks untuk skill yang benar-benar dipakai. Panduan itu juga menegaskan bahwa proxy/skills/ adalah path legacy dan loader membaca .agents/skills/ lebih dulu. docs/create_skills_rules.md:18-22 docs/create_skills_rules.md:74-76

⚠️ Berkas baru tidak langsung terlihat. Skill dipindai saat startup, jadi berkas yang ditambahkan ke .agents/skills/ baru muncul di <available_skills> setelah Deep Eye dijalankan ulang. docs/create_skills_rules.md:276-283

Verifikasi manual sebuah skill

Panduan menyediakan tiga langkah pemeriksaan. Pertama, cetak list_skill_index() dan potong blok <available_skills> dari get_system_prompt() dengan find('<available_skills>') serta find('</available_skills>'). Kedua, resolusi path lewat find_skill('sql_injection') dan baca isinya lewat read_skill('sql_injection')[:400]. Ketiga, jalankan pytest tests/test_proxy_skills.py -q. docs/create_skills_rules.md:430-464

Kriteria lulus yang dinyatakan panduan: path tercantum di <available_skills> dan read_skill mengembalikan isi. docs/create_skills_rules.md:464

Susunan test pytest di tests/

Suite berada datar di tests/. Setiap berkas melakukan bootstrap sendiri: menghitung REPO_ROOT = Path(__file__).resolve().parent.parent lalu menyisipkannya ke sys.path sebelum mengimpor modul proyek. Perintah yang dianjurkan adalah pip install -r requirements-dev.txt dilanjutkan pytest, atau satu berkas spesifik dengan pytest tests/test_features_1_19.py -v. tests/AGENTS.md:1-22 tests/test_features_1_19.py:1-7

requirements-dev.txt hanya memuat tiga paket: pytest>=7.0.0, pytest-cov>=4.0.0, dan ruff>=0.1.0, sehingga dependensi test terpisah dari dependensi produksi. requirements-dev.txt:1-4

tests/test_features_1_19.py berisi 11 test untuk fitur 1-19. Berkas ini memakai unittest.mock.MagicMock dan mendefinisikan kelas respons palsu kecil (R dengan status_code, headers, text, dan HC dengan get/post) alih-alih melakukan HTTP sungguhan. tests/test_features_1_19.py:1-4

TestTarget yang diimporPerilaku yang diperiksa
test_fingerprint_dedupeutils.finding_fingerprint.fingerprint, dedupe_findingstemuan berbeda severity dengan bukti sama dianggap satu, severity tertinggi menang, kunci fingerprint ditambahkan
test_nl_scope_parseutils.nl_scope.parse_nl_scope, apply_nl_scope_to_configscope bahasa alami memisahkan allowed_hosts, excluded_paths, allowed_ports, path_allow
test_openapi_expandmodules.openapi_ingest.parser.expand_endpointssatu path OpenAPI menghasilkan satu endpoint GET
test_cors_csp_missing_cspmodules.cors_csp.CorsCspTesterheader kosong memicu Missing Content-Security-Policy
test_jwt_alg_none_buildermodules.jwt_deep.tester._make_tokentoken alg: none diawali eyJ dengan dua titik
test_ai_planner_heuristicmodules.ai_planner.AIAttackPlannermode use_ai: False tetap mengurutkan graphql_deep dan jwt_deep lebih dulu
test_supply_chain_missing_srimodules.supply_chain_js.SupplyChainJSTesterscript jQuery tanpa SRI memicu temuan SRI atau Outdated
test_scope_path_allowutils.scope_manager.ScopeManager/api/* lolos, /admin ditolak
test_feature_testers_load_on_scannercore.vulnerability_scanner.VulnerabilityScannercors_csp dan waf_fingerprint terdaftar di _feature_testers
test_jwt_alg_none_builder, test_ai_planner_heuristiclihat baris terkaitlihat berkas rujukan

tests/test_features_1_19.py:10-33 tests/test_features_1_19.py:36-46 tests/test_features_1_19.py:49-69 tests/test_features_1_19.py:72-86 tests/test_features_1_19.py:89-94 tests/test_features_1_19.py:97-106 tests/test_features_1_19.py:109-124 tests/test_features_1_19.py:127-142 tests/test_features_1_19.py:145-165

Enam test terakhir pada tabel di atas dipetakan langsung ke _feature_testers di scanner, yang menghubungkan berkas test ini ke Pemindai Kerentanan dan Katalog Modul. Adapun test_scan_diff.py dan test_export_formats.py yang juga ada di tests/ dibahas di Scan Diff dan Retest dan Pelaporan dan Ekspor.

Test untuk loader skill

tests/test_proxy_skills.py:1-63

Berkas tests/test_proxy_skills.py menguji proxy.system secara langsung dengan enam test. test_skills_dir_is_agents_skills memastikan skills_dir() bernama skills dengan parent .agents dan direktori itu ada. test_list_skill_paths_nonempty menuntut minimal 10 path serta keberadaan vulnerabilities/sql_injection.md dan pentest di indeks. test_available_skills_block_has_absolute_paths memeriksa tag pembuka dan penutup <available_skills>, nama berkas sql_injection.md atau SKILL.md, dan penanda path absolut. test_find_and_read_skill menuntut isi skill memuat SQL Injection dan Trigger condition. test_get_system_prompt memeriksa kata authorized atau Deep Eye serta blok <available_skills>, dan test_workflow_skills_present memastikan enam kategori workflow muncul di indeks. tests/test_proxy_skills.py:9-63

graph LR
  T1["test_skills_dir_is_agents_skills"] --> S["proxy.system.skills_dir"]
  T2["test_list_skill_paths_nonempty"] --> P["list_skill_paths dan list_skill_index"]
  T3["test_available_skills_block_has_absolute_paths"] --> B["get_available_skills_block"]
  T4["test_find_and_read_skill"] --> F["find_skill dan read_skill"]
  T5["test_get_system_prompt"] --> G["get_system_prompt"]
  T6["test_workflow_skills_present"] --> P
  S --> D[".agents/skills sql_injection.md"]
  P --> D
  F --> D
  G --> B
  style D fill:#336791,color:#fff
  style B fill:#8b5cf6,color:#fff
  style G fill:#f59e0b,color:#000
  style F fill:#2d7d46,color:#fff
%% fig: Pemetaan test loader skill ke fungsi proxy.system
%% desc: Setiap test di tests/test_proxy_skills.py mengunci satu fungsi publik loader, dan semuanya bermuara pada berkas Markdown nyata di .agents/skills.
Fig. 2: Pemetaan test loader skill ke fungsi proxy.systemSetiap test di tests/test_proxy_skills.py mengunci satu fungsi publik loader, dan semuanya bermuara pada berkas Markdown nyata di .agents/skills.

Karena test menuntut direktori .agents/skills benar-benar ada dan berisi minimal 10 berkas Markdown, menghapus atau memindahkan direktori itu akan menggagalkan test_skills_dir_is_agents_skills dan test_list_skill_paths_nonempty sekaligus. Jalur legacy proxy/skills tetap dipindai oleh _skill_roots, tetapi tidak diuji secara eksplisit oleh berkas test ini. tests/test_proxy_skills.py:9-26 proxy/system.py:33-42