Referensi cepat AI engineering. LLM API, prompt engineering, RAG, vector database, embeddings, function calling, fine-tuning, dan AI SDK. Perfect buat developer yang bangun AI app.
Instalasi library utama yang dipake buat AI engineering dengan Python.
Cara install library AI yang paling sering dipake.
# OpenAI Python SDK
pip install openai
# Anthropic SDK (Claude)
pip install anthropic
# LangChain (core + OpenAI integration)
pip install langchain langchain-openai langchain-community
# LlamaIndex
pip install llama-index
# Hugging Face Transformers
pip install transformers torch
# Vector databases
pip install chromadb # Local, embedded
pip install pinecone-client # Pinecone (cloud)
pip install qdrant-client # Qdrant
# Embedding & ML utilities
pip install sentence-transformers scikit-learn numpy pandas
# Fine-tuning
pip install peft trl accelerate bitsandbytes
# Vercel AI SDK (JavaScript/TypeScript)
npm install ai @ai-sdk/openai @ai-sdk/anthropicSimpan API key di environment variable, jangan hardcode di kode.
# .env file
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
HUGGINGFACE_TOKEN=hf_...
PINECONE_API_KEY=...from dotenv import load_dotenv
load_dotenv() # Load dari .env file
import os
api_key = os.getenv("OPENAI_API_KEY")Pola dasar pemanggilan OpenAI API buat chat completion, streaming, dan structured output.
Cara paling dasar panggil LLM lewat OpenAI API.
from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": "Kamu adalah asisten yang membantu."},
{"role": "user", "content": "Apa ibukota Indonesia?"}
],
temperature=0.7,
max_tokens=500
)
print(response.choices[0].message.content)
print(f"Tokens dipake: {response.usage.total_tokens}")Kirim jawaban token per token, biar user nggak nunggu full response selesai.
stream = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Ceritakan tentang sejarah Java"}],
stream=True
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")Paksa model balikin JSON dengan schema yang udah ditentukan.
response = client.chat.completions.create(
model="gpt-4o",
response_format={"type": "json_object"},
messages=[
{"role": "system", "content": "Kembalikan jawaban dalam format JSON."},
{"role": "user", "content": "Buat profil user dengan field: nama, umur, pekerjaan, hobi (array)"}
]
)
import json
data = json.loads(response.choices[0].message.content)
print(data)
# {"nama": "Budi", "umur": 25, "pekerjaan": "Developer", "hobi": ["gaming", "baca"]}Kirim gambar ke model buat dianalisis.
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "user", "content": [
{"type": "text", "text": "Deskripsikan gambar ini"},
{"type": "image_url", "image_url": {"url": "https://contoh.com/foto.jpg"}}
]}
]
)
print(response.choices[0].message.content)Cara pakai Claude API, sebagai alternatif atau pelengkap OpenAI.
import anthropic
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1000,
system="Kamu adalah senior code reviewer yang memberi feedback singkat.",
messages=[
{"role": "user", "content": "Review kode ini: console.log(typeof null)"}
]
)
print(message.content[0].text)Pola prompt yang terbukti efektif untuk berbagai skenario.
Tanya langsung tanpa contoh, cocok buat task simpel.
prompt = "Klasifikasikan sentiment: 'Pelayanan toko ini parah banget'"
# negatifKasih beberapa contoh biar model paham pola yang diinginkan.
messages = [
{"role": "user", "content": """
Klasifikasikan sentiment review berikut:
Review: 'Mantap, kualitas oke banget!' => positif
Review: 'Lama banget pengirimannya' => negatif
Review: 'Sesuai deskripsi, oke lah' => netral
Review: 'Rusak, kecewa berat' =>
"""}
]Minta model berpikir bertahap sebelum kasih jawaban akhir.
system_prompt = """
Sebelum menjawab, pikirkan langkah demi langkah.
1. Identifikasi informasi yang diketahui
2. Identifikasi yang ditanyakan
3. Hitung langkah demi langkah
4. Berikan jawaban akhir dengan format: JAWABAN: [angka]
"""Template system prompt buat berbagai use case.
# Code reviewer
"Kamu adalah senior developer. Review kode dengan fokus pada: bug, performance, readability. Berikan saran dengan contoh kode perbaikan."
# Customer support
"Kamu adalah customer support untuk [produk]. Jawab dengan ramah, singkat, dan akurat. Jika tidak tahu, arahkan ke human agent."
# Data extraction
"Ekstrak informasi dari teks. Kembalikan HANYA dalam format JSON dengan field: nama, tanggal, jumlah, mata_uang. Jangan tambahkan teks lain."
# Tutor
"Kamu adalah tutor programming. Jangan kasih jawaban langsung. Beri petunjuk dan biarkan murid berpikir."Cara mengubah teks jadi representasi vektor untuk semantic search dan RAG.
Buat embedding pakai model OpenAI text-embedding-3-small (1536 dimensi, murah) atau text-embedding-3-large (3072 dimensi, lebih akurat).
from openai import OpenAI
client = OpenAI()
# Single text
response = client.embeddings.create(
model="text-embedding-3-small",
input="Belajar AI engineering untuk developer"
)
vector = response.data[0].embedding
# Batch (lebih efisien)
texts = ["teks pertama", "teks kedua", "teks ketiga"]
response = client.embeddings.create(
model="text-embedding-3-small",
input=texts
)
vectors = [item.embedding for item in response.data]Alternatif gratis tanpa API cost, jalanin lokal.
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('all-MiniLM-L6-v2') # 384 dimensi, cepat
embeddings = model.encode([
"Laptop gaming murah",
"Notebook untuk bermain game",
"Resep nasi goreng spesial"
])
# Cek similarity
from sklearn.metrics.pairwise import cosine_similarity
sim = cosine_similarity([embeddings[0]], [embeddings[1]])
print(f"Similarity: {sim[0][0]:.4f}") # Tinggi, karena maknanya miripHitung kemiripan dua vektor tanpa library tambahan.
import numpy as np
def cosine_sim(a, b):
return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
sim = cosine_sim(vector_a, vector_b)
# Range 0-1 (atau -1 sampai 1). Makin deket ke 1, makin mirip.Langkah-langkah membangun sistem Retrieval-Augmented Generation dari nol.
Cara motong dokumen panjang jadi chunk yang optimal untuk RAG.
from langchain.text_splitter import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # Maksimal karakter per chunk
chunk_overlap=50, # Overlap antar chunk biar konteks nggak putus
separators=["\n\n", "\n", ". ", " ", ""]
)
chunks = splitter.split_text(long_document_text)
print(f"Jumlah chunk: {len(chunks)}")Implementasi RAG lengkap pakai ChromaDB sebagai vector store.
import chromadb
from openai import OpenAI
client = OpenAI()
db = chromadb.PersistentClient(path="./chroma_db")
collection = db.get_or_create_collection("dokumen_saya")
def embed_text(text):
resp = client.embeddings.create(
model="text-embedding-3-small",
input=text
)
return resp.data[0].embedding
# Ingest: simpan dokumen
dokumen = [
{"id": "1", "text": "Produk A memiliki garansi 2 tahun."},
{"id": "2", "text": "Produk B tersedia dalam 5 warna."},
{"id": "3", "text": "Pengembalian barang maksimal 14 hari."}
]
for doc in dokumen:
collection.add(
ids=[doc["id"]],
documents=[doc["text"]],
embeddings=[embed_text(doc["text"])]
)
# Query: cari dan jawab
def ask(question, n_results=3):
# Retrieve
results = collection.query(
query_embeddings=[embed_text(question)],
n_results=n_results
)
context = "\n".join(results['documents'][0])
# Generate
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": f"Jawab berdasarkan konteks. Jika tidak ada info, bilang tidak tahu.\n\nKonteks:\n{context}"},
{"role": "user", "content": question}
]
)
return response.choices[0].message.content
print(ask("Berapa lama garansi Produk A?"))
# "Berdasarkan konteks, Produk A memiliki garansi 2 tahun."Versi yang lebih clean pakai LangChain abstraction.
from langchain_community.document_loaders import TextLoader
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import Chroma
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate
# Load & split
loader = TextLoader("dokumen.txt")
docs = loader.load()
# Embed & store
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma.from_documents(docs, embeddings)
# Buat retriever
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
# RAG chain
llm = ChatOpenAI(model="gpt-4o")
prompt = ChatPromptTemplate.from_messages([
("system", "Jawab berdasarkan konteks:\n{context}"),
("human", "{input}")
])
qa_chain = create_stuff_documents_chain(llm, prompt)
rag_chain = create_retrieval_chain(retriever, qa_chain)
result = rag_chain.invoke({"input": "Apa isi dokumen ini?"})
print(result["answer"])Tabel pemilihan vector database berdasarkan kebutuhan.
+------------+-------------+----------+------------+-----------+
| Database | Type | Language | Best For | Open Src? |
+------------+-------------+----------+------------+-----------+
| Chroma | Embedded | Python | Prototype | Ya |
| Pinecone | Managed SaaS| Any | Production | Tidak |
| Weaviate | Self-host | Go/Python| Hybrid src | Ya |
| Qdrant | Self-host | Rust API | High speed | Ya |
| Milvus | Distributed | Go/C++ | Scale | Ya |
| pgvector | PG Extension| SQL | Sudah pakai| Ya |
| FAISS | Library | Python | In-memory | Ya |
+------------+-------------+----------+------------+-----------+Cara cepat setup Pinecone untuk production.
from pinecone import Pinecone, ServerlessSpec
pc = Pinecone(api_key="your-api-key")
# Buat index
pc.create_index(
name="dokumen",
dimension=1536,
metric="cosine",
spec=ServerlessSpec(cloud="aws", region="us-east-1")
)
index = pc.Index("dokumen")
# Upsert vectors
index.upsert(vectors=[
{"id": "1", "values": [0.1, 0.2, ...], "metadata": {"text": "doc 1"}},
])
# Query
result = index.query(
vector=[0.1, 0.2, ...],
top_k=5,
include_metadata=True
)Kalau kamu udah pakai PostgreSQL, tinggal tambahin extension pgvector. Nggak perlu database baru.
-- Install extension
CREATE EXTENSION vector;
-- Buat table
CREATE TABLE dokumen (
id SERIAL PRIMARY KEY,
content TEXT,
embedding VECTOR(1536)
);
-- Insert
INSERT INTO dokumen (content, embedding)
VALUES ('teks contoh', '[0.1, 0.2, ...]'::vector);
-- Semantic search
SELECT content, embedding <=> '[0.15, 0.25, ...]'::vector AS distance
FROM dokumen
ORDER BY embedding <=> '[0.15, 0.25, ...]'::vector
LIMIT 5;Cara kasih kemampuan ke LLM buat memanggil function eksternal.
Definisikan tool, biar model otomatis panggil saat dibutuhkan.
import json
from openai import OpenAI
client = OpenAI()
# Definisikan tools
tools = [
{
"type": "function",
"function": {
"name": "get_product_info",
"description": "Dapatkan info produk berdasarkan ID",
"parameters": {
"type": "object",
"properties": {
"product_id": {"type": "string", "description": "ID produk, contoh: P001"}
},
"required": ["product_id"]
}
}
},
{
"type": "function",
"function": {
"name": "calculate_discount",
"description": "Hitung harga setelah diskon",
"parameters": {
"type": "object",
"properties": {
"price": {"type": "number"},
"discount_percent": {"type": "number"}
},
"required": ["price", "discount_percent"]
}
}
}
]
# Implementasi function-nya
def get_product_info(product_id):
products = {
"P001": {"name": "Headphone", "price": 500000},
"P002": {"name": "Mouse", "price": 150000}
}
return json.dumps(products.get(product_id, {"error": "Not found"}))
def calculate_discount(price, discount_percent):
final = price - (price * discount_percent / 100)
return json.dumps({"original": price, "final": final})
# Agent loop
def run_agent(user_input):
messages = [{"role": "user", "content": user_input}]
while True:
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=tools
)
msg = response.choices[0].message
messages.append(msg)
if not msg.tool_calls:
return msg.content
for tool_call in msg.tool_calls:
func_name = tool_call.function.name
args = json.loads(tool_call.function.arguments)
# Execute function
if func_name == "get_product_info":
result = get_product_info(**args)
elif func_name == "calculate_discount":
result = calculate_discount(**args)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": result
})
# Test
print(run_agent("Berapa harga Headphone setelah diskon 20%?"))Gunakan model open source secara lokal, tanpa biaya API.
Shortcut buat task ML umum dengan satu baris kode.
from transformers import pipeline
# Sentiment analysis
classifier = pipeline("sentiment-analysis")
classifier("Filmnya bagus banget!")
# [{'label': 'POSITIVE', 'score': 0.999}]
# Text generation
generator = pipeline("text-generation", model="gpt2")
generator("Indonesia adalah negara", max_length=30)
# [{'generated_text': 'Indonesia adalah negara kepulauan terbesar...'}]
# Named Entity Recognition
ner = pipeline("ner")
ner("Joko Widodo adalah presiden Indonesia")
# [{'word': 'Joko Widodo', 'entity': 'PER'}, {'word': 'Indonesia', 'entity': 'LOC'}]
# Translation
translator = pipeline("translation_id_en", model="Helsinki-NLP/opus-mt-id-en")
translator("Selamat pagi, apa kabar?")
# [{'translation_text': 'Good morning, how are you?'}]
# Summarization
summarizer = pipeline("summarization")
summarizer(long_text, max_length=100, min_length=30)
# Image classification
img_clf = pipeline("image-classification")
img_clf("gambar.jpg")Kontrol penuh atas model dan tokenizer.
from transformers import AutoTokenizer, AutoModelForCausalLM
model_name = "meta-llama/Llama-3.2-1B"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)
# Generate text
inputs = tokenizer("Belajar AI itu", return_tensors="pt")
outputs = model.generate(**inputs, max_new_tokens=50)
print(tokenizer.decode(outputs[0]))Untuk developer yang bangun AI app di React atau Next.js.
npm install ai @ai-sdk/openai @ai-sdk/anthropicimport { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';
import { anthropic } from '@ai-sdk/anthropic';
// OpenAI
const { text } = await generateText({
model: openai('gpt-4o'),
prompt: 'Jelaskan closure dalam JavaScript',
});
// Anthropic (tinggal ganti model)
const { text: claudeText } = await generateText({
model: anthropic('claude-sonnet-4-20250514'),
prompt: 'Jelaskan closure dalam JavaScript',
});import { useChat } from '@ai-sdk/react';
function Chat() {
const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat();
return (
<div>
{messages.map(m => (
<div key={m.id}>
<strong>{m.role}:</strong> {m.content}
</div>
))}
<form onSubmit={handleSubmit}>
<input value={input} onChange={handleInputChange} placeholder="Tanya apa..." />
<button type="submit" disabled={isLoading}>Kirim</button>
</form>
</div>
);
}// app/api/chat/route.ts
import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';
export async function POST(req: Request) {
const { messages } = await req.json();
const result = streamText({
model: openai('gpt-4o'),
system: 'Kamu adalah asisten yang membantu. Jawab dalam bahasa Indonesia.',
messages,
});
return result.toDataStreamResponse();
}import { generateObject } from 'ai';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod';
const { object } = await generateObject({
model: openai('gpt-4o'),
schema: z.object({
nama: z.string(),
umur: z.number(),
hobi: z.array(z.string()),
}),
prompt: 'Buat profil karakter fiktif orang Indonesia.',
});
console.log(object);
// { nama: 'Andi', umur: 28, hobi: ['fotografi', 'masak'] }Parameter-efficient fine-tuning buat adaptasi pre-trained model.
from peft import LoraConfig, get_peft_model, TaskType
from transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.2-1B",
load_in_4bit=True, # 4-bit quantization (QLoRA)
device_map="auto"
)
lora_config = LoraConfig(
task_type=TaskType.CAUSAL_LM,
r=8, # LoRA rank (4, 8, 16, 32)
lora_alpha=16, # Scaling factor (biasanya 2x r)
lora_dropout=0.05,
target_modules=[
"q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"
]
)
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# trainable params: 1M || all params: 1B || trainable%: 0.1from trl import SFTTrainer
from transformers import TrainingArguments
from datasets import load_dataset
dataset = load_dataset("json", data_files="training_data.json")
training_args = TrainingArguments(
output_dir="./lora-output",
per_device_train_batch_size=4,
gradient_accumulation_steps=4,
learning_rate=2e-4,
max_steps=100,
save_steps=50,
logging_steps=10,
)
trainer = SFTTrainer(
model=model,
train_dataset=dataset["train"],
args=training_args,
)
trainer.train()
# Save LoRA adapter
model.save_pretrained("./my-lora-adapter")Perbandingan model populer yang sering dipake di 2025 sampai 2026.
+------------------+-----------+----------------+----------+--------+
| Model | Provider | Context Window | API Cost | Open? |
+------------------+-----------+----------------+----------+--------+
| GPT-4o | OpenAI | 128K tokens | $$$ | Tidak |
| GPT-4o mini | OpenAI | 128K tokens | $ | Tidak |
| Claude Sonnet 4 | Anthropic | 200K tokens | $$ | Tidak |
| Claude Haiku 3.5 | Anthropic | 200K tokens | $ | Tidak |
| Gemini 2.0 Flash | Google | 1M tokens | $ | Tidak |
| Gemini 2.5 Pro | Google | 1M tokens | $$ | Tidak |
| Llama 3.3 70B | Meta | 128K tokens | Self-hst | Ya |
| Llama 3.2 1B/3B | Meta | 128K tokens | Self-hst | Ya |
| Mistral Large | Mistral | 128K tokens | $$ | Ya* |
| Qwen 2.5 72B | Alibaba | 128K tokens | Self-hst | Ya |
| DeepSeek V3 | DeepSeek | 64K tokens | $ | Ya |
+------------------+-----------+----------------+----------+--------+
$ = murah, $$ = sedang, $$$ = mahal
* Sebagian model open, sebagian proprietaryCara jalanin model secara lokal atau di server sendiri.
Jalanin model open source di laptop kamu, tanpa internet.
# Install Ollama
curl -fsSL https://ollama.com/install.sh | sh
# Download dan jalanin model
ollama run llama3.2 # Model 1B-3B
ollama run mistral # Model 7B
ollama run qwen2.5 # Model Qwen
# Via API (Ollama menyediakan endpoint OpenAI-compatible)
curl http://localhost:11434/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "llama3.2",
"messages": [{"role": "user", "content": "Halo!"}]
}'# Pakai Ollama dari Python (OpenAI-compatible)
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:11434/v1",
api_key="ollama" # Bebas, nggak dicek
)
response = client.chat.completions.create(
model="llama3.2",
messages=[{"role": "user", "content": "Jelaskan OOP secara singkat"}]
)Buat production serving dengan throughput tinggi dan batching otomatis.
# Install
pip install vllm
# Serve model
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3.2-3B \
--port 8000Pola kode yang sering muncul di AI engineering.
Tambahkan retry logic biar aplikasi nggak crash kalau API ke-limit.
import time
from openai import OpenAI
client = OpenAI()
def call_with_retry(messages, max_retries=3):
for attempt in range(max_retries):
try:
return client.chat.completions.create(
model="gpt-4o",
messages=messages
)
except Exception as e:
if attempt == max_retries - 1:
raise e
wait = 2 ** attempt # Exponential backoff
print(f"Retry dalam {wait}s... ({e})")
time.sleep(wait)Hitung token sebelum dikirim, biar nggak kelebihan context window.
import tiktoken
enc = tiktoken.encoding_for_model("gpt-4o")
text = "Ini adalah contoh teks untuk dihitung tokennya."
tokens = enc.encode(text)
print(f"Jumlah token: {len(tokens)}")
# Estimasi biaya
cost_per_1k_input = 0.0025 # GPT-4o input price
estimated_cost = (len(tokens) / 1000) * cost_per_1k_input
print(f"Estimasi biaya: ${estimated_cost:.6f}")Validasi output LLM biar nggak bikin error downstream.
from pydantic import BaseModel, ValidationError
class ProductInfo(BaseModel):
name: str
price: float
stock: int
def extract_product(llm_output):
"""Parse dan validasi output LLM ke schema."""
try:
data = json.loads(llm_output)
return ProductInfo(**data)
except (json.JSONDecodeError, ValidationError) as e:
print(f"Output tidak valid: {e}")
return NoneSimpan riwayat percakapan biar model ingat konteks.
class ConversationManager:
def __init__(self, system_prompt, max_messages=20):
self.system_prompt = system_prompt
self.max_messages = max_messages
self.messages = [{"role": "system", "content": system_prompt}]
def add_message(self, role, content):
self.messages.append({"role": role, "content": content})
# Potong kalau kepanjangan (simpan system prompt + N pesan terakhir)
if len(self.messages) > self.max_messages:
self.messages = [self.messages[0]] + self.messages[-(self.max_messages - 1):]
def chat(self, user_input):
self.add_message("user", user_input)
response = client.chat.completions.create(
model="gpt-4o",
messages=self.messages
)
reply = response.choices[0].message.content
self.add_message("assistant", reply)
return reply
# Pakai
conv = ConversationManager("Kamu adalah asisten belajar programming.")
print(conv.chat("Apa itu variable?"))
print(conv.chat("Berikan contohnya dalam Python.")) # Model ingat konteks sebelumnyaToken Unit pemrosesan LLM (~4 karakter / 3/4 kata)
Context Window Maksimal token yang bisa diproses sekaligus
Temperature Kontrol kreativitas (0=konsisten, 1=kreatif)
Embedding Representasi numerik teks yang nangkap makna
Vector DB Database khusus simpan dan cari embeddings
RAG Sistem ambil data eksternal, inject ke prompt
Fine-Tuning Latih ulang model dengan data spesifik
LoRA Fine-tuning efisien, update sedikit parameter
QLoRA LoRA + quantization 4-bit, butuh GPU lebih kecil
Agent Sistem AI yang bisa ambil aksi (panggil function, dll)
Function Call Kasih tool ke LLM, model mutusin kapan dipanggil
MCP Protocol universal koneksikan AI dengan tool eksternal
Hallucination LLM ngomong hal yang salah tapi kedengeran meyakinkan
Top-p Filter kata kandidat berdasarkan probabilitas kumulatif
Max tokens Batas output yang dihasilkan model
System Prompt Instruksi tetap yang mengatur behavior model
Few-shot Kasih contoh input-output di prompt
Zero-shot Tanya langsung tanpa contoh
Chain-of-T Minta model berpikir langkah demi langkah
Embedding Dim Jumlah angka dalam vektor embedding (384, 768, 1536, dll)
Cosine Similar Ukuran kemiripan antar dua vektor (0-1)
Chunking Motong dokumen jadi bagian kecil untuk RAGLogin atau daftar akun gratis untuk membaca cheat sheet ini.