Meniru Panggilan LLM dalam Pengujian
unittest.mock, fixture pytest, serta merekam dan memutar ulang respons LLM.
Meniru Panggilan LLM dalam Pengujian adalah pelajaran AI Agents gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar AI Agents, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus AI Agents mencakup 4 pelajaran total.
Apa Itu Pembuatan Tiruan?
Pembuatan tiruan menggantikan fungsi atau objek nyata dengan versi palsu yang mengembalikan respons terkontrol. Dalam pengujian agen, kita membuat tiruan untuk panggilan API LLM agar pengujian berjalan seketika, tidak memerlukan biaya, dan menghasilkan hasil yang dapat diprediksi.
Modul Python unittest.mock adalah alat standar untuk keperluan ini.
Dasar-dasar unittest.mock.patch()
unittest.mock.patch(target) menggantikan objek bernama untuk sementara selama pengujian berlangsung. target adalah string bertitik yang menunjuk ke objek sebagaimana objek tersebut diimpor dalam modul yang sedang diuji.
from unittest.mock import patch, MagicMock
# The function under test calls openai.chat.completions.create
# We patch it so no real API call is made
def ask_llm(question: str) -> str:
import openai
client = openai.OpenAI(api_key='test')
resp = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': question}]
)
return resp.choices[0].message.content
with patch('openai.OpenAI') as mock_client_class:
mock_instance = MagicMock()
mock_client_class.return_value = mock_instance
mock_instance.chat.completions.create.return_value = MagicMock(
choices=[MagicMock(message=MagicMock(content='Paris'))]
)
result = ask_llm('Capital of France?')
print(result) # 'Paris' — no API call madeMenggunakan patch sebagai Dekorator dalam pytest
Saat digunakan sebagai dekorator dengan pytest, @patch() menyisipkan tiruan sebagai parameter fungsi. Tiruan tersebut otomatis dihapus setelah pengujian selesai.
from unittest.mock import patch, MagicMock
import pytest
# Assume agent.py contains: import openai; client = openai.OpenAI(...)
@patch('agent.openai.OpenAI')
def test_agent_calls_llm(mock_openai_class):
# Set up the mock chain
mock_client = MagicMock()
mock_openai_class.return_value = mock_client
mock_client.chat.completions.create.return_value = MagicMock(
choices=[MagicMock(message=MagicMock(content='Paris is the capital of France.'))]
)
from agent import ask_llm
result = ask_llm('What is the capital of France?')
assert 'Paris' in result
mock_client.chat.completions.create.assert_called_once()Membangun Respons Tiruan yang Dapat Digunakan Kembali
Membangun objek respons tiruan secara manual membutuhkan banyak kode. Buat fungsi pembantu untuk membangun objek tiruan dengan struktur yang benar dan sesuai dengan bentuk respons SDK OpenAI.
from unittest.mock import MagicMock
def make_mock_response(content: str, tool_calls: list = None) -> MagicMock:
message = MagicMock()
message.content = content
message.tool_calls = tool_calls or []
choice = MagicMock()
choice.message = message
choice.finish_reason = 'stop' if not tool_calls else 'tool_calls'
response = MagicMock()
response.choices = [choice]
response.usage = MagicMock(total_tokens=42)
return response
# Usage in tests:
# mock_create.return_value = make_mock_response('Hello!')
# mock_create.return_value = make_mock_response('', tool_calls=[...])
# --- demo ---
response = make_mock_response('The weather in Paris is 18C and sunny.')
print('content:', response.choices[0].message.content)
print('finish_reason:', response.choices[0].finish_reason)
print('total_tokens:', response.usage.total_tokens)
Membuat Tiruan untuk Panggilan Alat dalam Respons
Saat menguji logika pemanggilan alat milik agen, respons tiruan harus menyertakan bidang tool_calls dengan struktur yang benar agar kode penguraian agen dapat memprosesnya dengan tepat.
import json
from unittest.mock import MagicMock
def make_tool_call_response(tool_name: str, arguments: dict) -> MagicMock:
tool_call = MagicMock()
tool_call.id = 'call_abc123'
tool_call.type = 'function'
tool_call.function = MagicMock()
tool_call.function.name = tool_name
tool_call.function.arguments = json.dumps(arguments)
message = MagicMock()
message.content = None
message.tool_calls = [tool_call]
response = MagicMock()
response.choices = [MagicMock(message=message, finish_reason='tool_calls')]
return response
# mock.return_value = make_tool_call_response('search_web', {'query': 'Python tutorials'})
# --- demo ---
response = make_tool_call_response('search_web', {'query': 'Python tutorials'})
call = response.choices[0].message.tool_calls[0]
print('tool name:', call.function.name)
print('tool arguments:', call.function.arguments)
print('finish_reason:', response.choices[0].finish_reason)
Fixture pytest untuk Pembuatan Tiruan
Fixture pytest memungkinkan Anda mendefinisikan kode penyiapan yang dapat digunakan kembali. Buat fixture yang menerapkan patch pada klien LLM dan menyediakannya untuk setiap pengujian yang memintanya — tidak perlu mengulang kode.
import pytest
from unittest.mock import patch, MagicMock
@pytest.fixture
def mock_openai(make_mock_response):
with patch('myagent.client.chat.completions.create') as mock_create:
mock_create.return_value = MagicMock(
choices=[MagicMock(message=MagicMock(
content='Default mocked response',
tool_calls=[]
))]
)
yield mock_create
# Now any test can use it:
def test_agent_responds(mock_openai):
from myagent import agent
result = agent.run('Hello')
assert result is not None
mock_openai.assert_called_once()Fixture mocker dari pytest-mock
pytest-mock menyediakan fixture mocker yang menyederhanakan penerapan patch. Fixture ini otomatis membersihkan tiruan dan menyediakan sintaks yang lebih rapi daripada unittest.mock.patch mentah.
# pip install pytest-mock
# In your test file:
def test_agent_with_mocker(mocker):
mock_create = mocker.patch('myagent.client.chat.completions.create')
mock_create.return_value = mocker.MagicMock(
choices=[mocker.MagicMock(message=mocker.MagicMock(
content='Mocked answer',
tool_calls=[]
))]
)
from myagent import agent
result = agent.run('What is 2+2?')
assert 'answer' in result.lower() or '4' in result
mock_create.assert_called_once()
# No cleanup needed — mocker handles itMerekam dan Memutar Ulang dengan vcr.py
vcrpy merekam interaksi HTTP nyata ke dalam berkas 'kaset' pada proses pertama, lalu memutarnya ulang pada proses-proses berikutnya. Cara ini ideal untuk menguji kode yang menggunakan API HTTP mentah, bukan SDK.
# pip install vcrpy
import vcr
import httpx
@vcr.use_cassette('fixtures/cassettes/openai_chat.yaml')
def test_with_recorded_response():
# First run: makes a real HTTP call and records it
# Subsequent runs: uses the recorded cassette (no network, no cost)
response = httpx.post(
'https://api.openai.com/v1/chat/completions',
json={'model': 'gpt-4o-mini', 'messages': [{'role': 'user', 'content': 'Hello'}]},
headers={'Authorization': 'Bearer YOUR_KEY'}
)
data = response.json()
assert data['choices'][0]['message']['content'] is not NoneMemastikan Tiruan Dipanggil dengan Benar
Setelah pengujian selesai, pastikan tiruan dipanggil dengan argumen yang tepat. Hal ini dapat menemukan kesalahan ketika agen mengirim model yang salah, parameter yang hilang, atau pesan yang keliru.
from unittest.mock import patch, MagicMock, call
@patch('myagent.client.chat.completions.create')
def test_agent_sends_correct_model(mock_create):
mock_create.return_value = MagicMock(
choices=[MagicMock(message=MagicMock(content='ok', tool_calls=[]))]
)
from myagent import agent
agent.run('Hello')
# Verify the mock was called with correct arguments
mock_create.assert_called_once()
call_kwargs = mock_create.call_args.kwargs
assert call_kwargs['model'] == 'gpt-4o-mini'
assert len(call_kwargs['messages']) >= 1
assert call_kwargs['messages'][0]['role'] == 'system'Mensimulasikan Kesalahan API dalam Pengujian
Uji cara agen Anda menangani kegagalan LLM dengan mengonfigurasi tiruan agar memunculkan pengecualian. Dengan demikian, Anda dapat memverifikasi penanganan kesalahan dan logika percobaan ulang tanpa menyebabkan kegagalan API yang nyata.
from unittest.mock import patch
import openai
@patch('myagent.client.chat.completions.create')
def test_agent_handles_rate_limit(mock_create):
# Simulate a rate limit error
mock_create.side_effect = openai.RateLimitError(
message='Rate limit exceeded',
response=None,
body=None
)
from myagent import agent
result = agent.run('Hello')
# Agent should handle this gracefully
assert result['error'] == 'rate_limit'
# or
assert result['retry_after'] is not NoneMengatur Fixture Tiruan dalam conftest.py
Tempatkan fixture bersama di conftest.py pada akar direktori pengujian Anda. pytest otomatis menemukan berkas ini dan menyediakan fixture untuk semua berkas pengujian tanpa perlu mengimpornya.
# tests/conftest.py
import pytest
from unittest.mock import patch, MagicMock
@pytest.fixture(autouse=False)
def mock_llm():
with patch('myagent.client.chat.completions.create') as mock_create:
mock_create.return_value = MagicMock(
choices=[MagicMock(message=MagicMock(
content='Test response',
tool_calls=[]
))]
)
yield mock_create
@pytest.fixture
def mock_search_tool():
with patch('myagent.tools.search_web') as mock_search:
mock_search.return_value = [{'title': 'Test', 'url': 'https://example.com'}]
yield mock_searchUji Pemahaman: Pembuatan Tiruan untuk Panggilan LLM
Uji pemahaman Anda tentang teknik pembuatan tiruan untuk pengujian agen.
Ringkasan: Pembuatan Tiruan untuk Panggilan LLM dalam Pengujian
Sekarang Anda memiliki alat untuk menulis pengujian unit agen yang cepat dan andal:
- Gunakan
unittest.mock.patch()untuk mengganti klien LLM dengan tiruan - Bangun pembantu respons tiruan yang dapat digunakan kembali dan sesuai dengan struktur respons SDK
- Buat tiruan untuk panggilan alat dengan bidang
tool_callsyang terstruktur dengan benar - Gunakan fixture pytest dan
conftest.pyuntuk berbagi tiruan di antara pengujian - Gunakan
pytest-mockuntuk sintaks yang lebih rapi - Gunakan
vcrpyuntuk merekam dan memutar ulang interaksi HTTP nyata
Tiruan adalah dasar dari rangkaian pengujian agen yang cepat dan mudah dipelihara.
Belajar AI Agents dengan tutor AI — gratis
Tulis dan jalankan kode asli di browser kamu, dapatkan bantuan instan dari tutor AI 24/7, dan lanjutkan di mana kamu tinggalkan di web atau aplikasi.
- Kursus
- 60
- Pelajaran
- 239
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Meniru Panggilan LLM dalam Pengujian” gratis?
Ya — teks lengkap “Meniru Panggilan LLM dalam Pengujian” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus AI Agents, upgrade ke CoddyKit PRO. Kursus AI Agents mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Meniru Panggilan LLM dalam Pengujian”?
unittest.mock, fixture pytest, serta merekam dan memutar ulang respons LLM. Kamu berlatih AI Agents dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai AI Agents?
Tidak diperlukan pengalaman sebelumnya. AI Agents di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.
Berapa lama pelajaran “Meniru Panggilan LLM dalam Pengujian” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran AI Agents ini?
Ya. Setiap pelajaran AI Agents menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Mengapa Pengujian Agen Berbeda
- Meniru Panggilan LLM dalam Pengujian
- Pengujian Agen Berbasis Assertion
- Pengujian Integrasi untuk Pipeline Agen