4
Dasar LLM dan Embedding
Halaman ini membahas dua bahan yang dipakai hampir semua contoh lain di repository: memanggil model lewat SDK openai, dan mengubah teks menjadi vektor lewat OpenAIEmbeddings. Tiga berkas menjadi rujukan: 00_start.py untuk embedding paling kecil, 08_openai.py untuk daftar model, dan 17_embeddings.py untuk memeringkat dokumen dengan kemiripan kosinus. Pustaka yang dipasang adalah langchain-openai==1.1.10 dan openai==2.21.0 (requirements.txt:661, requirements.txt:932).
Dari teks ke vektor dengan OpenAIEmbeddings
00_start.py:1-113 adalah contoh terpendek di repository. Berkas itu mengimpor load_dotenv dan OpenAIEmbeddings, memanggil load_dotenv() untuk mengisi environment dari .env — pola yang dibahas di Persiapan Lingkungan dan Konfigurasi API Key — lalu membuat objek embeddings = OpenAIEmbeddings() (00_start.py:4-54). Satu string disimpan di variabel text, dan embeddings.embed_documents([text]) mengubahnya menjadi doc_embeddings yang langsung dicetak (00_start.py:6-75, 00_start.py:116).
graph LR
env["load_dotenv baca .env"] --> emb["OpenAIEmbeddings()"]
emb --> docs["embed_documents"]
text["text: satu string"] --> docs
docs --> vec["doc_embeddings: list vektor"]
vec --> out["print doc_embeddings"]
style env fill:#f59e0b,color:#000
style emb fill:#f59e0b,color:#000
style text fill:#2d7d46,color:#fff
style docs fill:#2d7d46,color:#fff
style vec fill:#8b5cf6,color:#fff
style out fill:#8b5cf6,color:#fff
%% fig: Alur teks menjadi vektor di 00_start.py
%% desc: Kunci dibaca dari .env, objek OpenAIEmbeddings dibuat, lalu satu string diubah menjadi list vektor dan dicetak.Satu detail di berkas ini mudah terlewat: pembacaan kunci manual lewat os.getenv('OPENAI_API_KEY') hanya ada di baris komentar, jadi tidak pernah dijalankan (00_start.py:9-107). Pengisian kunci sepenuhnya bergantung pada load_dotenv().
Dua method pada OpenAIEmbeddings dipakai di repository, dan keduanya berbeda bentuk masukan:
| Method | Masukan | Keluaran |
|---|---|---|
embed_documents | list teks; satu elemen di 00_start.py, sembilan nama dokumen di 17_embeddings.py | satu vektor per elemen masukan |
embed_query | satu string pertanyaan | satu vektor |
Rangkaian pemanggilan keduanya bisa dibandingkan langsung di 00_start.py:1-113 dan 17_embeddings.py:14-278.
Daftar model lewat SDK openai
08_openai.py:1-139 memakai SDK resmi, bukan LangChain. Berkas itu memanggil load_dotenv(), mengimpor OpenAI, membuat client = OpenAI(), lalu meminta client.models.list() untuk mengambil daftar model milik akun. Baris print(models.data[0].id) mencetak satu id, dan print([mod.id for mod in models.data]) mencetak seluruh id lewat list comprehension (08_openai.py:1-139). Tidak ada nama model yang ditulis di kode, jadi isi daftar bergantung pada akun yang dipakai.
Sisa berkas adalah contoh permukaan API lain yang semuanya dikomentari: client.completions.create dengan model "gpt-3.5-turbo-instruct", client.images.generate dengan n=2 dan size="512x512", serta client.audio.transcriptions.create dengan model="whisper-1" yang membaca audio/donda.mp3 (08_openai.py:15-3510). Karena semuanya dikomentari, menjalankan 08_openai.py hanya mencetak daftar model.
Urutan baris membuat load_dotenv() berjalan sebelum client = OpenAI() dibuat (08_openai.py:1-811).
⚠️ Berkas ini tidak memakai
os.getenvsama sekali; tanpa berkas.envyang terbaca,OpenAI()danmodels.list()berjalan tanpa kredensial.
Memeringkat dokumen dengan kemiripan kosinus
17_embeddings.py:11-4112 mengubah satu pertanyaan dan sembilan nama dokumen menjadi vektor, lalu mengurutkan dokumen berdasarkan kemiripan. Query disimpan di input_text, sedangkan input_docs berisi sembilan nama berkas (17_embeddings.py:11-1413). embed_query menghasilkan satu vektor untuk query, dan embed_documents menghasilkan sembilan vektor untuk dokumen (17_embeddings.py:14-278).
| Indeks | Isi input_docs |
|---|---|
| 0 | financial_algoritma |
| 1 | annual_report_algoritma |
| 2 | financial_supertype |
| 3 | agm_supertype |
| 4 | egm_supertype |
| 5 | financial_hypergrowth |
| 6 | annual_report_hypergrowth |
| 7 | agm_sectors |
| 8 | financial_statements_template |
Kesembilan nilai di atas ditulis berurutan di 17_embeddings.py:14-278, dan urutannya penting karena hasil akhir dipetakan balik lewat indeks.
graph LR
q["input_text"] --> eq["embed_query"]
d["input_docs: 9 nama"] --> ed["embed_documents"]
eq --> qv["query: 1 vektor"]
ed --> dv["docs: 9 vektor"]
qv --> cs["cosine_similarity vec1 vec2"]
dv --> cs
cs --> sims["similarities: 9 nilai"]
sims --> am["np.argmax"]
am --> pick["input_docs most_similar_index"]
style q fill:#2d7d46,color:#fff
style d fill:#2d7d46,color:#fff
style eq fill:#f59e0b,color:#000
style ed fill:#f59e0b,color:#000
style qv fill:#8b5cf6,color:#fff
style dv fill:#8b5cf6,color:#fff
style cs fill:#2d7d46,color:#fff
style sims fill:#8b5cf6,color:#fff
style am fill:#2d7d46,color:#fff
style pick fill:#2d7d46,color:#fff
%% fig: Peringkat dokumen dengan kemiripan kosinus
%% desc: Query dan sembilan dokumen di-embed, setiap pasangan dihitung kemiripannya, lalu np.argmax memilih indeks dokumen paling mirip.Fungsi cosine_similarity menghitung np.dot(vec1, vec2) lalu membaginya dengan hasil kali np.linalg.norm(vec1) dan np.linalg.norm(vec2) (17_embeddings.py:29-3514). Setiap dokumen diuji terhadap query yang sama, hasilnya dikumpulkan ke list similarities, dan tiap nilai dicetak bersama indeksnya lewat enumerate (17_embeddings.py:35-3815). Baris terakhir mengambil np.argmax(similarities) dan mencetak input_docs[most_similar_index] (17_embeddings.py:40-4116).
⚠️
input_docsdipakai dua kali secara by index. Urutan list saatembed_documentsharus sama dengan urutan saat dipetakan balik; kalau list diubah di antaranya,input_docs[most_similar_index]menunjuk dokumen yang salah (17_embeddings.py:14-278, 17_embeddings.py:40-4116).
Skrip ini berhenti di pencetakan hasil; vektor tidak disimpan ke mana pun. Penyimpanan dan pencarian vektor dibahas di Vector Store: Chroma Lokal dan Pinecone, sedangkan pemakaian embedding di dalam rantai retrieval ada di Pipeline RAG dengan LangChain.