Talim

Harnessni test qilish

Turn, sessiya va plaginlarni deterministik test qilish: replay, snapshot va eval skriptlari.

9 daqiqa o‘qishO'rta → Ilg'orArxitektura: Cordis va tizim11 / 17
Harness test sikli

Harnessni «qo’lda bosib ko’rish» bilan tekshirib bo’lmaydi. Bitta turn ichida model chaqiruvi, tool bajarilishi, ruxsat tekshiruvi va sessiya yozuvi bir-biriga ulanadi — qo’lda takrorlash sekin, noaniq va qimmat. Cordis’da imtiyozli yadro yo’qligi (harness-cordis’da ko’rganimizdek) test uchun ustunlik beradi: har bir qobiliyat ctx orqali ro’yxatdan o’tadi, demak har birini alohida almashtirish va deterministik qayta o’ynash mumkin.

Deterministik test — tasodifiylik va tashqi dunyoni qulflab, bir xil kirishga bir xil chiqish olish. Shundagina replay, snapshot va eval ishonchli bo’ladi.

1. Nima uchun test qiyin

Agent testi oddiy funksiya testidan farq qiladi — yon effektlar (side-effect) ko’p, vaqtga bog’liq va model javobi tabiatan no-deterministik.

Muammo Yechim
Yon effektlar — fayl yozish, tarmoq, tool chaqiruvi Mock provider va in-memory sandbox, effektlarni array’ga yig’ish
Async va tartib — turn ichida bir nechta step, event zanjiri createTestTurn bilan turn’ni izolyatsiyada ishga tushirish, event tartibini tekshirish
Tasodifiylik — model javobi, Math.random(), vaqt Seeded RNG, soat (clock) mock’i, LLM javobini fixture’dan berish

Asosiy g’oya: test hech qachon haqiqiy modelga chiqmasligi kerak. Model o’rniga yozib olingan javob, fayl tizimi o’rniga xotiradagi nusxa, vaqt o’rniga belgilangan soat ishlatiladi.

2. Turn testi — effektlarni yig’ish

Turn testi eng kichik ishonchli birlik. Kirish — foydalanuvchi xabari, chiqish — to’plangan effektlar. harness-turn darsidagi 16 ta event aynan shu effektlar orqali tekshiriladi.

import { createTestTurn, mockProvider } from './test-utils'

test('read_changelog tool turn ichida chaqiriladi', async () => {
  const effects: string[] = []
  const turn = createTestTurn({
    provider: mockProvider({ reply: 'changelog o\'qildi' }),
    plugins: [changelogPlugin],
    onEffect: (e) => effects.push(e.type),
  })

  await turn.run('changelog 2.5 ni ko\'rsat')

  expect(effects).toEqual(['turn/start', 'tool/call', 'tool/result', 'turn/end'])
  expect(turn.session.events).toContainEqual(
    expect.objectContaining({ type: 'tool/result', name: 'read_changelog' })
  )
})

Bu yerda effects — turn davomida Cordis orqali o’tgan barcha event nomlari. Mock provider haqiqiy LLM’ni almashtiradi, onEffect esa nima bo’lganini kuzatishga imkon beradi. Test tez, arzon va har safar bir xil natija beradi.

Muhim

Testda haqiqiy LLM chaqirmang — mock ishlating. Haqiqiy model chaqiruvi sekin, qimmat va no-deterministik: bir xil test ikki marta har xil o'tishi mumkin. Mock javobni fixture faylda saqlang va faqat eval bosqichida cheklangan, nazoratli haqiqiy chaqiruvga ruxsat bering.

3. Sessiya replay va snapshot

harness-sessiya darsida ko’rgan append-only jurnal replay uchun ideal. Bir marta yozilgan sessiyani qayta o’ynab, yangi kod eski xatti-harakatni buzmaganini tekshirish mumkin. Snapshot test — kutilgan sessiya JSON’ini saqlab, keyingi ishga tushirishdagi farqni diff sifatida ko’rsatish.

from harness.test import replay_session

events = replay_session("fixtures/session-2026-08-23.jsonl", plugins=[my_plugin])
snapshot = [e.to_json() for e in events if e.durable]

assert snapshot == load_snapshot("snapshots/session-2026-08-23.json")
# Idempotent tekshiruvi — ikkinchi replay bir xil natija berishi kerak
assert replay_session("fixtures/session-2026-08-23.jsonl", plugins=[my_plugin]) == events

Ikkinchi assert idempotent’likni tekshiradi: plagin bir xil jurnalni ikki marta o’ynaganda bir xil effekt berishi kerak, qo’shimcha yozuv yoki yo’qolgan event bo’lmasligi kerak. Snapshot diff’i esa aynan qaysi event o’zgarganini ko’rsatadi — yangi tool qo’shildi mi, tartib buzildi mi.

4. Eval — har plagin uchun minimal mezon

Eval — turn va snapshot testlaridan keyingi qadam: plagin kutilgan vazifani bajaryaptimi, xatoda o’zini qanday tutadi. Har bir plagin uchun kamida ikkita test yozish amaliy qoida.

Amaliy maslahat

Har plagin uchun minimal 2 test: happy — to'g'ri kirishda kutilgan natija va effektlar, error — noto'g'ri kirish, ruxsat rad etilishi yoki bekor qilish (cancellation) da xato to'g'ri belgilangan va sessiyaga yozilgan. Shundan keyin qo'shimcha holatlar qo'shing.

Eval skriptini oddiy tuting: kirish fixture’larini papkada saqlang, kutilgan natijani JSON’da yozing, farqni diff bilan hisobot qiling. Murakkab framework shart emas — deterministik replay va snapshotning o’zi ko’p xatoni ushlaydi.

Xulosa

Harnessni qo’lda tekshirish o’rniga deterministik test qurish kerak — Cordis’da har bir qism almashtirilishi mumkinligi buni oson qiladi. Yon effektlarni mock’lang, vaqt va tasodifiylikni qulflang, turn testida effektlar ro’yxatini tekshiring. Sessiya jurnalini replay qilib snapshot bilan solishtiring, idempotent’likni tasdiqlang. Va har bir plagin uchun kamida happy + error ikkita test yozing — haqiqiy LLM’ni testda chaqirmasdan. Keyingi modulda bu amaliyotni nazariya bilan bog’laymiz.

Bu dars foydali bo‘ldimi?

Keyingi darsMuammo: dinamik kompozitsiya →