Chapterبەش 2 · Lectureوانە 2.1
Meaning as Numbers: Vectors and Embeddingsمانا وەک ژمارە: ئاڕاستەبڕەکان و ئیمبەدینگەکان
Why words must become numbers, vectors as lists, embeddings learned from use and the embedding space, cosine similarity and Euclidean distance in Python, search by meaning with embedding models (November 2026) and vector databases, and retrieval-augmented generation (RAG) with a prompt builder you can run, plus the limits: bias, weaker Kurdish, stale indexes and leaks.
بۆچی وشە دەبێت ببێت بە ژمارە، وەک لیست، کە لە بەکارهێنانەوە فێر دەبن و ، و لە Pythonـدا، گەڕان بەپێی واتا بە (مانگی 11ی 2026) و و (RAG) لەگەڵ دروستکەرێکی کە دەتوانیت کاری پێ بکەیت، هەروەها سنوورەکان: ، کوردیی لاوازتر، پێڕستی کۆن و دزەکردن.
What you will learnچی فێر دەبیت
- Explain why AI turns text into vectors, and what an embedding and an embedding space are.
- Compute cosine similarity and Euclidean distance with Python lists, and read what they mean.
- Explain semantic search, embedding models and vector databases, and why word counting is not enough.
- Describe the RAG pipeline and build a grounded RAG prompt in Python.
- Name the limits of embeddings and RAG: bias, weaker Kurdish, stale indexes and leaks.
- ڕوون بکەیتەوە بۆچی دەق دەکات بە و و چین.
- و بە Python بژمێریت و واتاکەیان بخوێنیتەوە.
- ، و ڕوون بکەیتەوە و بۆچی ژماردنی وشە بەس نییە.
- ڕێڕەوی RAG وەسف بکەیت و RAG بە Python دروست بکەیت کە پشت بە سەرچاوە دەبەستێت.
- سنوورەکانی و RAG ناو ببەیت: ، کوردیی لاوازتر، پێڕستی کۆن و دزەکردن.
Words must become numbersوشە دەبێت ببێت بە ژمارە
A computer can only calculate with numbers. To a computer the word «هەولێر» (Erbil) is just six character codes: 1607, 1749, 1608, 1604, 1742 and 1585 in Unicode (Unicode and UTF-8). Those numbers say which letters are written, not what the word means: nothing in them shows that Erbil is a city, close in meaning to Sulaymaniyah and far from a laptop.
تەنیا دەتوانێت بە ژمارە حیساب بکات. بۆ وشەی «هەولێر» تەنیا شەش کۆدی پیتە: 1607، 1749، 1608، 1604، 1742 و 1585 لە (Unicode و UTF-8). ئەو ژمارانە دەڵێن کام پیتانە نووسراون، نەک وشەکە چ واتایەکی هەیە: هیچ شتێکیان پیشان نادات کە هەولێر شارە، لە واتادا لە سلێمانی نزیکە و لە لاپتۆپ دوورە.
So AI turns words, sentences and even pictures into a different kind of numbers: lists that carry meaning. These lists are embeddings. In the last lesson they were the first step inside the model (inside the model); here you learn to compare them and to use them: to search Shilan's bookshop catalogue by meaning, and to let a model answer from her own documents (RAG).
بۆیە وشە، ڕستە و تەنانەت وێنەش دەکات بە جۆرێکی تر لە ژمارە: لیستگەلێک کە واتا هەڵدەگرن. ئەم لیستانە ن. لە وانەی پێشوودا یەکەم هەنگاو بوون لە ناو (ناو مۆدێل)؛ لێرە فێر دەبیت بەراوردیان بکەیت و بەکاریان بهێنیت: بۆ گەڕان لە لیستی کتێبەکانی کتێبخانەکەی شیلان بەپێی واتا و بۆ ئەوەی لە بەڵگەنامەکانی خۆیەوە وەڵام بداتەوە (RAG).
A vector is a list of numbersئاڕاستەبڕ لیستێکی ژمارەیە
In maths a vector is an arrow with a direction and a length; in programming it is simply a list of numbers. [3, 4] means "3 steps right, 4 steps up". Its length is (Pythagoras; the notation is in length and unit vectors), and in Python math.hypot(3, 4) gives 5.0. Each number is one dimension: two numbers are a point on a map, three a point in a room. An embedding has hundreds or thousands of dimensions. We cannot draw that, but Python handles a list of 1,024 numbers as easily as a list of two.
لە بیرکاریدا تیرێکە کە ئاڕاستە و درێژیی هەیە؛ لە بەرنامەسازیدا تەنیا لیستێکی ژمارەیە. [3, 4] واتە «3 هەنگاو بۆ ڕاست، 4 هەنگاو بۆ سەرەوە». درێژییەکەی ـە (فیساغۆرس؛ نیشانەکان لە درێژی و ئاڕاستەبڕی یەکەکاندا هاتوون) و لە Pythonـدا math.hypot(3, 4) 5.0 دەدات. هەر ژمارەیەک یەک : دوو ژمارە خاڵێکن لەسەر نەخشە، سێ ژمارە خاڵێک لە ژوورێکدا. سەدان یان هەزاران هەیە. ناتوانین ئەوە بکێشین، بەڵام Python لیستێکی 1,024 ژمارەیی بە هەمان ئاسانیی لیستێکی دوو ژمارەیی بەڕێوە دەبات.
Embeddings: numbers learned from useئیمبەدینگەکان: ژمارەگەلێک کە لە بەکارهێنانەوە فێر دەبن
An embedding is a vector that a model learned for a token, a word, a piece of text or a picture; nobody types the numbers. Take «کوردستان». At the start of training it gets random numbers, for example [0.23, 0.45, 0.12, 0.78, 0.91, …] (an illustration). During training the model meets «کوردستان» again and again in the same sentences as «هەولێر», «شاخ» (mountain) and «کەلتوور» (culture). Each time it nudges their vectors so they help to predict the text, and words used in similar ways drift close together. After training, nearness means relatedness, and the distance between two vectors says how related two words are.
کە بۆ ، وشەیەک، پارچە دەقێک یان وێنەیەک فێری بووە؛ کەس ژمارەکان نانووسێت. «کوردستان» وەربگرە. لە سەرەتای ڕاهێناندا وەردەگرێت، بۆ نموونە [0.23, 0.45, 0.12, 0.78, 0.91, …] (تەنیا نموونە). لە کاتی ڕاهێناندا چەندین جار «کوردستان» لە هەمان ڕستەدا لەگەڵ «هەولێر»، «شاخ» و «کەلتوور» دەبینێت. هەر جارێک کەمێک دەجووڵێنێت بۆ ئەوەی یارمەتیی پێشبینیکردنی دەقەکە بدەن و ئەو وشانەی بە شێوەی لێکچوو بەکار دێن لە یەکتر نزیک دەبنەوە. دوای ڕاهێنان، نزیکی واتە پەیوەندی و دووریی نێوان دوو دەڵێت دوو وشە چەند پەیوەندییان پێکەوە هەیە.
So a model is not given meaning like a book on a shelf: it is trained on data, and its embeddings are part of what it learns. Real vectors are long: 256 to 1,024 numbers for word embeddings, and thousands inside large language models. The famous word2vec method (Mikolov and others, 2013) learned word vectors from 1.6 billion words in less than a day.
کەواتە واتا وەک کتێبێک لەسەر ڕەفە نادرێت بە : لەسەر ڕادەهێنرێت و بەشێکن لەوەی فێری دەبێت. لە ڕاستیدا درێژن: 256 تا 1,024 ژمارە بۆ وشە و هەزاران ژمارە لە ناو . ڕێگای ناسراوی word2vec (Mikolov و هاوکارانی، 2013) لە ماوەی کەمتر لە ڕۆژێکدا وشەی لە 1.6 ملیار وشەوە فێر بوو.


Embeddings: numbers learned from useئیمبەدینگەکان: ژمارەگەلێک کە لە بەکارهێنانەوە فێر دەبن
Like shops in the bazaarوەک دوکانەکانی بازاڕ
In an old bazaar such as Erbil's Qaysari, shops of the same trade often stand together: jewellers in one alley, cloth sellers in another, spice sellers in a third. If you know where one jeweller is, the others are close by. An embedding gives every word an address in the same way, so things with similar meaning end up as neighbours.
لە بازاڕێکی کۆنی وەک قەیسەریی هەولێر، دوکانەکانی هەمان پیشە زۆرجار پێکەوەن: زەڕنگەرەکان لە کۆڵانێک، قوماشفرۆشەکان لە کۆڵانێکی تر و بەهاراتفرۆشەکان لە سێیەمیان. ئەگەر بزانیت یەکێک لە زەڕنگەرەکان لە کوێیە، ئەوانی تر لە نزیکییەوەن. بە هەمان شێوە ناونیشانێک دەداتە هەر وشەیەک، بۆیە ئەو شتانەی واتایان لێک دەچێت دەبن بە دراوسێ.
Where the analogy stops workingسنووری ئەم نموونەیە
In the bazaar people chose the places, on a flat map. Embedding addresses are learned, not chosen, and have hundreds of dimensions, so one word can be near several groups at once: Erbil is near other cities and also near citadel and history.
لە بازاڕدا خەڵک شوێنەکانیان هەڵبژاردووە، لەسەر نەخشەیەکی تەخت. ناونیشانەکانی فێر دەبن، هەڵنابژێردرێن و سەدان هەیە، بۆیە یەک وشە دەتوانێت لە یەک کاتدا لە چەند گرووپێک نزیک بێت: هەولێر لە شارەکانی تر نزیکە و لە قەڵا و مێژووش.
Shilan uses the same idea for her catalogue: books about similar things get nearby vectors, so a customer who likes one can be shown its neighbours (other uses).
شیلان هەمان بیرۆکە بۆ لیستی کتێبەکانی بەکار دەهێنێت: کتێبەکانی بابەتی لێکچوو نزیک وەردەگرن، بۆیە دەکرێت دراوسێکانی کتێبێک پیشانی کڕیارێک بدرێن کە حەزی لەو کتێبەیە (بەکارهێنانی تر).
The embedding space and its dimensionsفەزای ئیمبەدینگ و ڕەهەندەکانی
All the embeddings of one model live in one imagined space, its embedding space, and each number is one dimension. Picture Kurdish dishes on a 2-D map: from savoury (left) to sweet (right), and from plain (bottom) to filled (top). Dolma and kubba sit together (savoury and filled), baklava and kulicha together (sweet and filled), and kebab and bread lower down. This map is made by hand, so its two dimensions have names.
هەموو یەک لە یەک فەزای خەیاڵیدا دەژین کە پێی دەڵێن . هەر ژمارەیەک یەک . خواردنە کوردییەکان لەسەر نەخشەیەکی دوو ڕەهەندی بهێنە بەرچاو: لە سوێرەوە (چەپ) بۆ شیرین (ڕاست) و لە سادەوە (خوارەوە) بۆ پڕکراو (سەرەوە). دۆڵمە و کوبە پێکەوەن (سوێر و پڕکراو)، بەقڵاوە و کلێچە پێکەوەن (شیرین و پڕکراو) و کەباب و نان لە خوارەوەن. ئەم نەخشەیە بە دەست دروست کراوە، بۆیە دوو ناویان هەیە.
Real dimensions have no neat names like sweetness: the model learns them, and a meaning is spread over many numbers, as Google's Machine Learning Crash Course explains. There are also many more: as of November 2026 the Voyage 4 models, which Anthropic's documentation points to, give 1,024 numbers by default (also 256, 512 or 2,048), and OpenAI's text-embedding-3-small gives 1,536 (-large 3,072).
لە ڕاستیدا ناوی ڕوونی وەک شیرینییان نییە: فێریان دەبێت و واتایەک بەسەر چەندین ژمارەدا بڵاوە، وەک خولی خێرای Google ڕوونی دەکاتەوە. زۆر زیاتریشن: لە مانگی 11ی 2026دا Voyage 4، کە بەڵگەنامەکانی Anthropic ئاماژەیان بۆ دەکەن، بە شێوەی بنەڕەتی 1,024 ژمارە دەدەن (هەروەها 256، 512 یان 2,048) و text-embedding-3-smallـی OpenAI 1,536 دەدات (-large 3,072).
How close? Distance and directionچەند نزیک؟ دووری و ئاڕاستە
There are two common ways to compare two vectors a and b:
دوو ڕێگەی باو هەن بۆ بەراوردکردنی دوو a و b:
- Euclidean distance: the straight-line distance between the two points, ; Python's
math.dist(a, b). Small means similar. - Cosine similarity: how closely the two arrows point the same way, whatever their lengths: . The top is the dot product: multiply matching numbers and add (two products of vectors). The bottom multiplies the two lengths. 1 means the same direction, 0 unrelated (at right angles), −1 opposite.
- : دووریی هێڵی ڕاست لە نێوان دوو خاڵەکەدا، ؛
math.dist(a, b)ـی Python. بچووک واتە لێکچوو. - : دوو تیرەکە چەند بەرەو هەمان ئاڕاستە دەڕۆن، درێژییەکانیان هەرچییەک بێت: . سەرەوە ە: ژمارە بەرامبەرەکان لێک بدە و کۆیان بکەرەوە (دوو لێکدانی ئاڕاستەبڕ). خوارەوە دوو درێژییەکە لێک دەدات. 1 واتە هەمان ئاڕاستە، 0 بێپەیوەندی (ستوون لەسەر یەک) و −1 پێچەوانە.
Same direction, so the cosine is 1, although b is twice as long; their distance is √5 ≈ 2.24.
هەمان ئاڕاستە، بۆیە 1ـە، هەرچەندە b دوو هێندە درێژە؛ دوورییان √5 ≈ 2.24ـە.
From the same square, two friends walk towards the citadel, one 100 m and the other 300 m. They went the same way (cosine 1) but stand at different places (a distance of 200 m).
لە هەمان گۆڕەپانەوە، دوو هاوڕێ بەرەو قەڵا دەڕۆن، یەکێکیان 100 m و ئەوی تر 300 m. هەمان ڕێگەیان گرت ( 1)، بەڵام لە دوو شوێنی جیاوازدان (دووریی 200 m).
Where the analogy stops workingسنووری ئەم نموونەیە
Embeddings have hundreds of directions, not one street. Many providers normalise their vectors to length 1; then cosine and the dot product are the same number, and distance gives the same ranking (Anthropic's and OpenAI's embedding pages say so).
سەدان ئاڕاستەیان هەیە، نەک یەک شەقام. زۆرێک لە دابینکەران دەکەنە درێژیی 1؛ ئەو کاتە و هەمان ژمارەن و دووری هەمان ڕیزبەندی دەدات (لاپەڕەکانی Anthropic و OpenAI ئەمە دەڵێن).
Cosine similarity in Pythonلێکچوونی کۆساین لە Pythonـدا
Python 3.12 added math.sumprod(), which computes a dot product in one call; math.hypot() gives a vector's length and math.dist() the distance between two points. The vectors below have only four hand-made numbers, so we can read them; real embeddings are learned and much longer.
Python 3.12 math.sumprod()ـی زیاد کرد کە بە یەک بانگکردن دەژمێرێت؛ math.hypot() درێژیی دەدات و math.dist() دووریی نێوان دوو خاڵ. خوارەوە تەنیا چوار ژمارەی دەستکردیان هەیە بۆ ئەوەی بتوانین بیانخوێنینەوە؛ ڕاستەقینە فێر دەبێت و زۆر درێژترە.
import math
def cosine(a, b):
"""Cosine similarity: 1 = same direction, 0 = unrelated."""
return math.sumprod(a, b) / (math.hypot(*a) * math.hypot(*b))
# Hand-made 4-number vectors (real embeddings are learned and much longer).
# city mountain food computer
vectors = {
"Erbil": [0.9, 0.3, 0.2, 0.1],
"Sulaymaniyah": [0.9, 0.4, 0.2, 0.1],
"Halgurd": [0.2, 0.9, 0.0, 0.0],
"kebab": [0.2, 0.0, 0.9, 0.0],
"laptop": [0.1, 0.0, 0.0, 0.9],
}
query = vectors["Erbil"]
ranked = sorted(vectors, key=lambda w: cosine(query, vectors[w]), reverse=True)
for word in ranked:
print(f"{word:13} {cosine(query, vectors[word]):.3f}")
print("distance Erbil-Sulaymaniyah:", round(math.dist(query, vectors["Sulaymaniyah"]), 3))Erbil 1.000 Sulaymaniyah 0.996 Halgurd 0.501 kebab 0.401 laptop 0.204 distance Erbil-Sulaymaniyah: 0.1
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 5
Dot product divided by the two lengths: the cosine formula in one line.
دابەش لەسەر دوو درێژییەکە: هاوکێشەی لە یەک دێڕدا.
- Lineدێڕی 8
The four positions are given names here only to make the example readable.
چوار شوێنەکە لێرە تەنیا بۆ ئەوە ناویان لێ نراوە کە نموونەکە بخوێنرێتەوە.
- Lineدێڕی 18
sorted(..., key=..., reverse=True)puts the most similar word first.sorted(..., key=..., reverse=True)لێکچووترین وشە دەخاتە پێشەوە.
Sulaymaniyah points almost the same way as Erbil (0.996); Halgurd, a mountain, and kebab are only half related; laptop is far. This ranking is exactly what search by meaning does, with learned embeddings instead of hand-made ones.
سلێمانی نزیکەی بەرەو هەمان ئاڕاستەی هەولێر دەڕوات (0.996)؛ هەڵگورد (شاخێک) و کەباب تەنیا نیوە پەیوەندیدارن؛ لاپتۆپ دوورە. ئەم ڕیزبەندییە ڕێک ئەو کارەیە کە گەڕان بەپێی واتا دەیکات، بە فێربوو لەبری دەستکرد.
Search by meaningگەڕان بەپێی واتا
An ordinary keyword search finds texts that contain your words. Semantic search finds texts that mean what you asked: each document gets one embedding (a whole sentence or paragraph becomes one vector), the question gets one too, and the nearest documents win. So cheap phone can find a page about affordable mobiles although no word matches. Google Search has used such meaning-based systems since RankBrain in 2015 (how AI changed Google Search).
گەڕانی ئاسایی بە وشە ئەو دەقانە دەدۆزێتەوە کە وشەکانی تۆیان تێدایە. ئەو دەقانە دەدۆزێتەوە کە واتای پرسیارەکەت دەگەیەنن: هەر بەڵگەنامەیەک یەک وەردەگرێت (ڕستەیەک یان بڕگەیەکی تەواو دەبێت بە یەک )، پرسیارەکەش یەکێک و نزیکترین بەڵگەنامەکان دەبەنەوە. بۆیە مۆبایلی هەرزان دەتوانێت لاپەڕەیەک لەبارەی تەلەفۆنی کەمنرخ بدۆزێتەوە، هەرچەندە هیچ وشەیەک یەک ناگرێتەوە. گەڕانی Google لە RankBrainـەوە لە 2015 سیستەمی لەم جۆرەی بەکار هێناوە (ژیریی دەستکرد چۆن گەڕانی Googleـی گۆڕی).
Embedding models do this job: they output vectors, not text. As of November 2026, examples are Voyage 4 (Anthropic makes no embedding model and points to Voyage AI), Google's Gemini Embedding 2 (text, pictures, video, audio and PDFs in one space), OpenAI's text-embedding-3 models and Mistral Embed. Vectors from two different embedding models live in different spaces and cannot be compared.
ئەم کارە دەکەن: دەدەن، نەک دەق. لە مانگی 11ی 2026دا نموونەکان ئەمانەن: Voyage 4 (Anthropic خۆی نییە و ئاماژە بۆ Voyage AI دەکات)، Gemini Embedding 2ـی Google (دەق، وێنە، ڤیدیۆ، دەنگ و PDF لە یەک فەزادا)، text-embedding-3ـی OpenAI و Mistral Embed. دوو جیاواز لە دوو فەزای جیاوازدان و بەراورد ناکرێن.
import voyageai
vo = voyageai.Client() # reads the VOYAGE_API_KEY environment variable
result = vo.embed(["Stories for young readers", "A cookbook of Kurdish food"],
model="voyage-4", input_type="document")
print(len(result.embeddings[0])) # 1024 numbers per textWhy counting words is not enoughبۆچی ژماردنی وشە بەس نییە
Before learned embeddings, a simple way to turn a text into a vector was to count words: one number for every word of a vocabulary (a bag of words). Here is that idea for six book descriptions in Shilan's catalogue:
پێش فێربوو، ڕێگایەکی سادە بۆ گۆڕینی دەقێک بۆ ژماردنی وشەکان بوو: یەک ژمارە بۆ هەر وشەیەکی وشەنامەیەک (bag of words). ئەمە ئەو بیرۆکەیە بۆ وەسفی شەش کتێب لە لیستی کتێبەکانی شیلان:
import math
def cosine(a, b):
lengths = math.hypot(*a) * math.hypot(*b)
return math.sumprod(a, b) / lengths if lengths else 0.0
books = {
"B1": "a cookbook of kurdish food dolma and kebab",
"B2": "stories for children about animals in the mountains",
"B3": "a history of the erbil citadel",
"B4": "learn python programming step by step",
"B5": "short stories for young readers",
"B6": "kurdish poems about the mountains",
}
vocabulary = sorted({w for text in books.values() for w in text.split()})
def count_vector(text):
words = text.split()
return [words.count(v) for v in vocabulary] # one number per vocabulary word
def search(query, top=2):
print("query:", query, "| words it knows:", [w for w in query.split() if w in vocabulary])
q = count_vector(query)
ranked = sorted(books, key=lambda b: cosine(q, count_vector(books[b])), reverse=True)
for b in ranked[:top]:
print(f" {b} {cosine(q, count_vector(books[b])):.2f} {books[b]}")
print(len(vocabulary), "words in the vocabulary")
search("stories about mountains")
search("tales for kids")28 words in the vocabulary query: stories about mountains | words it knows: ['stories', 'about', 'mountains'] B2 0.61 stories for children about animals in the mountains B6 0.52 kurdish poems about the mountains query: tales for kids | words it knows: ['for'] B5 0.45 short stories for young readers B2 0.35 stories for children about animals in the mountains
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 5
A vector of only zeros has length 0; returning 0.0 avoids dividing by zero.
کە تەنیا سفری تێدایە درێژیی 0ـە؛ گەڕاندنەوەی 0.0 ڕێ لە دابەشکردن بەسەر سفردا دەگرێت.
- Lineدێڕی 16
The vocabulary: every different word of all six descriptions, sorted.
وشەنامەکە: هەموو وشە جیاوازەکانی هەر شەش وەسفەکە، ڕیزکراو.
- Lineدێڕی 20
words.count(v): how many times each vocabulary word appears in this text.words.count(v): هەر وشەیەکی وشەنامەکە چەند جار لەم دەقەدا دێت.
The first search works: stories, about and mountains appear in the right books. The second fails quietly: tales and kids are not in the vocabulary, so the query vector only knows for, and B5 wins because of one small word, not because of its meaning. A learned embedding model places tales for kids near stories for children and stories for young readers, because people use these words in similar ways. That is why embeddings exist.
گەڕانی یەکەم کار دەکات: stories، about و mountains لە کتێبە دروستەکاندا هەن. گەڕانی دووەم بە بێدەنگی شکست دەهێنێت: tales و kids لە وشەنامەکەدا نین، بۆیە پرسیارەکە تەنیا for دەناسێت و B5 بەهۆی یەک وشەی بچووکەوە دەباتەوە، نەک بەهۆی واتاکەیەوە. فێربوو tales for kids لە نزیک stories for children و stories for young readers دادەنێت، چونکە خەڵک ئەم وشانە بە شێوەی لێکچوو بەکار دەهێنن. بۆیە هەن.
Vector databases: finding the nearest quicklyبنکەدراوەکانی ئاڕاستەبڕ: دۆزینەوەی نزیکترین بە خێرایی
Shilan has six books; a library or a company may have millions of pieces of text. Comparing a question with every one of them is slow. A vector database stores each vector with its id and its text, and builds an index that finds the nearest neighbours of a query vector quickly; it is the same idea as the nearest neighbour, at a much larger scale. Most use approximate nearest-neighbour search: they look first in the most promising part of the space, so they are very fast and almost always find the best matches. Some are separate products; others are an extra feature of an ordinary database.
شیلان شەش کتێبی هەیە؛ کتێبخانەیەک یان کۆمپانیایەک لەوانەیە ملیۆنان پارچە دەقی هەبێت. بەراوردکردنی پرسیارێک لەگەڵ هەموویاندا هێواشە. هەر لەگەڵ ژمارەی ناسنامە و دەقەکەی هەڵدەگرێت و پێڕستێک دروست دەکات کە بە خێرایی پرسیارێک دەدۆزێتەوە؛ هەمان بیرۆکەیە کە لە نزیکترین دراوسێـدا هاتووە، بە قەبارەیەکی زۆر گەورەتر. زۆربەیان گەڕانی نزیکەیی بەکار دەهێنن: سەرەتا لە بەڵێندارترین بەشی فەزاکەدا دەگەڕێن، بۆیە زۆر خێران و نزیکەی هەمیشە باشترین هاوتاکان دەدۆزنەوە. هەندێکیان بەرهەمی سەربەخۆن؛ هەندێکی تر تایبەتمەندییەکی زیادەی ئاسایین.
RAG: answering from your own documentsRAG: وەڵامدانەوە لە بەڵگەنامەکانی خۆتەوە
A language model only knows its training data, which stops at a cut-off date and never included Shilan's price list. Retrieval-augmented generation (RAG; Lewis and others, 2020) fixes this in two parts:
تەنیا دەزانێت، کە لە ڕێکەوتێکدا دەوەستێت و هەرگیز لیستی نرخەکانی شیلانی تێدا نەبووە. (RAG؛ Lewis و هاوکارانی، 2020) ئەمە بە دوو بەش چارەسەر دەکات:
- Indexing (once, and again when the documents change)ئامادەکردن (یەکجار و دیسان کاتێک بەڵگەنامەکان دەگۆڕێن)
Cut the documents into chunks of a few paragraphs (chunking), make an embedding for every chunk and store the vectors with their text in a vector database.
بەڵگەنامەکان بکە بە پارچەی چەند بڕگەیی ()، بۆ هەر پارچەیەک دروست بکە و لەگەڵ دەقەکانیان لە هەڵبگرە.
- Answering (every question)وەڵامدانەوە (بۆ هەر پرسیارێک)
Embed the question, fetch the k nearest chunks (for example k = 3), put them into the prompt with the instruction "answer only from these sources and name the source", and let the model write the answer.
پرسیارەکە بکە بە ، k نزیکترین پارچە بهێنە (بۆ نموونە k = 3)، بیانخەرە ناو لەگەڵ ڕێنمایی «تەنیا لەم سەرچاوانە وەڵام بدەرەوە و ناوی سەرچاوەکە ببە» و با وەڵامەکە بنووسێت.
RAG is like an open-book exam: you do not memorise the whole book; you find the right page and answer from it, and you can show the teacher where you found it.
RAG وەک تاقیکردنەوەیەکی کتێب-کراوەیە: هەموو کتێبەکە لەبەر ناکەیت؛ لاپەڕە دروستەکە دەدۆزیتەوە و لێیەوە وەڵام دەدەیتەوە و دەتوانیت پیشانی بدەیت لە کوێ دۆزیتەوە.
Where the analogy stops workingسنووری ئەم نموونەیە
A student who opens the wrong page still answers confidently. RAG is only as good as the chunks it retrieves, so check the cited source.
خوێندکارێک کە لاپەڕەی هەڵە دەکاتەوە هێشتا بە دڵنیاییەوە وەڵام دەداتەوە. RAG تەنیا هێندەی ئەو پارچانە باشە کە دەیانهێنێتەوە، بۆیە سەرچاوە ناوبراوەکە بپشکنە.


Building a RAG prompt in Pythonدروستکردنی هەوێنێکی RAG بە Python
Calling a model needs an API key, but the important part, building the prompt, is plain Python. Shilan's shop information is cut into four chunks. A toy retrieval counts shared words (a real system would compare embeddings), keeps the top 2 and builds the prompt with an f-string:
بانگکردنی پێویستی بە هەیە، بەڵام بەشە گرنگەکە، دروستکردنی ، Pythonـی سادەیە. زانیارییەکانی دوکانەکەی شیلان کراون بە چوار پارچە. هێنانەوەیەکی بچووک وشە هاوبەشەکان دەژمێرێت (سیستەمێکی ڕاستەقینە بەراورد دەکات)، دوو باشترینیان دەهێڵێتەوە و بە f-string دروست دەکات:
chunks = {
"hours": "The shop is open from 9:00 to 21:00, Saturday to Thursday.",
"delivery": "We deliver in Sulaymaniyah within two days; delivery costs 3,000 dinars.",
"returns": "You can return a book within 14 days if you keep the receipt.",
"payment": "We accept cash and bank cards.",
}
def words(text):
for mark in ".,;?":
text = text.replace(mark, "")
return set(text.lower().split())
def score(question, text):
"""Toy retrieval: count shared words (a real system compares embeddings)."""
return len(words(question) & words(text))
question = "Can I return a book after 10 days?"
top = sorted(chunks, key=lambda c: score(question, chunks[c]), reverse=True)[:2]
sources = "\n".join(f"[{name}] {chunks[name]}" for name in top)
prompt = f"""Answer the customer's question using ONLY the sources below.
Name the source you used in brackets. If the sources do not say, answer "I don't know".
Sources:
{sources}
Question: {question}"""
print(prompt)Answer the customer's question using ONLY the sources below. Name the source you used in brackets. If the sources do not say, answer "I don't know". Sources: [returns] You can return a book within 14 days if you keep the receipt. [delivery] We deliver in Sulaymaniyah within two days; delivery costs 3,000 dinars. Question: Can I return a book after 10 days?
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 15
&between two sets keeps the words they share (sets).&لە نێوان دوو ئەو وشانە دەهێڵێتەوە کە هاوبەشن.- Lineدێڕی 18
Sort the chunk names by score, highest first, and keep the first two: the top-k step with k = 2.
ناوی پارچەکان بەپێی نمرە ڕیز بکە، بەرزترین یەکەم و دوو یەکەمیان بهێڵەرەوە: هەنگاوی top-k بە k = 2.
- Lineدێڕی 21-27
A triple-quoted f-string: instructions, then the named sources, then the question.
f-stringـێکی سێ کەوانەیی: ڕێنمایی، پاشان سەرچاوە ناوبراوەکان، پاشان پرسیارەکە.
Three details matter. The instruction says only from the sources. Every chunk carries a name, so the answer can cite it and Shilan can check it. And I don't know is allowed, so the model has an honest way out when the sources are silent. The delivery chunk was retrieved only because it shares the word days: retrieval is never perfect, which is why the instruction matters.
سێ وردەکاری گرنگن. ڕێنماییەکە دەڵێت تەنیا لە سەرچاوەکانەوە. هەر پارچەیەک ناوێکی هەیە، بۆیە وەڵامەکە دەتوانێت ناوی ببات و شیلان دەتوانێت بیپشکنێت. هەروەها نازانم ڕێگەپێدراوە، بۆیە ڕێگایەکی ڕاستگۆیانەی هەیە کاتێک سەرچاوەکان هیچ ناڵێن. پارچەی delivery تەنیا لەبەر ئەوە هێنرایەوە کە وشەی daysـی تێدایە: هێنانەوە هەرگیز تەواو نییە، بۆیە ڕێنماییەکە گرنگە.
Other uses, and the limitsبەکارهێنانی تر و سنوورەکان
Embeddings do more than search: recommender systems (customers who liked this also liked …), grouping similar messages (clustering), finding duplicate questions, and sorting customer messages into topics. Know their limits too:
لە گەڕان زیاتر دەکەن: (ئەو کڕیارانەی ئەمەیان بەدڵ بوو ئەمانەشیان بەدڵ بوو …)، کۆکردنەوەی نامە لێکچووەکان (کۆکردنەوە)، دۆزینەوەی پرسیاری دووپاتە و پۆلێنکردنی نامەکانی کڕیاران بەپێی بابەت. سنوورەکانیشیان بزانە:
- Bias: embeddings learn from human text, including its stereotypes (bias in algorithms).
- Weaker Kurdish: less Kurdish training text means less precise Kurdish vectors; test with your own Kurdish examples.
- A stale index: if the price list changes and nobody re-embeds it, RAG answers from old chunks.
- Private documents leaking: a shared vector database can return one user's documents to another. The OWASP Top 10 for LLM Applications 2025 lists vector and embedding weaknesses (LLM08): keep permissions per user and accept data only from trusted sources.
- RAG reduces, not removes, invented answers: a model can still misread or mix sources (limits and safety).
- : لە دەقی مرۆڤەوە فێر دەبن، لەگەڵ وێنە چەسپاوەکانیشی (لاسەنگیی ئەلگۆریزم).
- کوردیی لاوازتر: دەقی ڕاهێنانی کوردیی کەمتر واتە کوردیی کەمتر ورد؛ بە نموونە کوردییەکانی خۆت تاقییان بکەرەوە.
- پێڕستی کۆن: ئەگەر لیستی نرخەکان بگۆڕێت و کەس دیسان نەیکات بە ، RAG لە پارچە کۆنەکانەوە وەڵام دەداتەوە.
- دزەکردنی بەڵگەنامەی تایبەت: هاوبەش دەتوانێت بەڵگەنامەکانی بداتە تر. OWASP Top 10 for LLM Applications 2025 لاوازییەکانی ئاڕاستەبڕ و ئیمبەدینگ (LLM08) لە لیستەکەیدا دادەنێت: مۆڵەتەکان بۆ هەر جیا بکەرەوە و تەنیا لە سەرچاوەی جێی متمانە وەربگرە.
- RAG وەڵامی هەڵبەستراو کەم دەکاتەوە، نایسڕێتەوە: هێشتا دەتوانێت سەرچاوەکان هەڵە بخوێنێتەوە یان تێکەڵیان بکات (سنوور و سەلامەتی).
Common mistakesهەڵە باوەکان
A programming mistake: comparing vectors of different lengths. math.sumprod refuses:
هەڵەیەکی بەرنامەسازی: بەراوردکردنی درێژیی جیاواز. math.sumprod ڕەتی دەکاتەوە:
import math
erbil = [0.9, 0.3, 0.2, 0.1]
duhok = [0.9, 0.5, 0.2] # one number is missing
print(math.sumprod(erbil, duhok))Traceback (most recent call last):
File "cosine_mistake.py", line 5, in <module>
print(math.sumprod(erbil, duhok))
~~~~~~~~~~~~^^^^^^^^^^^^^^
ValueError: Inputs are not the same lengthFix: every vector must come from the same embedding model with the same number of dimensions. Check with len(a) == len(b) before comparing; never pad or cut vectors by hand.
چارەسەر: هەموو دەبێت لە هەمان و بە هەمان ژمارەی بێت. پێش بەراوردکردن بە len(a) == len(b) بیپشکنە؛ هەرگیز بە دەست درێژ یان کورت مەکەرەوە.
Exercisesڕاهێنانەکان
Compute the cosine similarity of [1, 0] and [1, 1]. What angle is that?
[1, 0] و [1, 1] بژمێرە. ئەمە چ گۆشەیەکە؟
Show answerوەڵامەکە پیشان بدە
0.707 is the cosine of 45°: the arrows are half-way between the same direction (1) and unrelated (0).
0.707 کۆساینی 45°ـە: تیرەکان لە نیوەی ڕێگای نێوان هەمان ئاڕاستە (1) و بێپەیوەندی (0)دان.
A question has the vector q = [0.8, 0.1, 0.1]. Three chunks have A = [0.7, 0.2, 0.1], B = [0.1, 0.9, 0.0] and C = [0.4, 0.0, 0.6]. Which chunk does a RAG system retrieve first? Use cosine() from cosine.py.
پرسیارێک q = [0.8, 0.1, 0.1]ـی هەیە. سێ پارچە A = [0.7, 0.2, 0.1]، B = [0.1, 0.9, 0.0] و C = [0.4, 0.0, 0.6]ـیان هەیە. سیستەمێکی RAG یەکەمجار کام پارچە دەهێنێتەوە؟ cosine() لە cosine.py بەکار بهێنە.
Show answerوەڵامەکە پیشان بدە
A: cosine 0.988 (distance 0.141). C: 0.649, B: 0.231. A points almost the same way as the question, so it is retrieved first; B is about something else.
A: 0.988 (دووری 0.141). C: 0.649، B: 0.231. A نزیکەی بەرەو هەمان ئاڕاستەی پرسیارەکە دەڕوات، بۆیە یەکەمجار دەهێنرێتەوە؛ B لەبارەی شتێکی ترە.
Aram's college gives a 120-page handbook: registration, exams, the library, fees and the IT rules. Karwan wants a RAG helper for students. How should he chunk it? Why not one chunk for the whole book, or one chunk per sentence?
کۆلێژەکەی ئارام ڕێبەرێکی 120 لاپەڕەیی دەدات: ناونووسین، تاقیکردنەوەکان، کتێبخانە، کرێکان و یاساکانی IT. کاروان یاریدەدەرێکی RAG بۆ خوێندکاران دەوێت. چۆن بیکات بە پارچە؟ بۆچی نەک یەک پارچە بۆ هەموو کتێبەکە یان یەک پارچە بۆ هەر ڕستەیەک؟
Show answerوەڵامەکە پیشان بدە
Cut it by headings into chunks of a few paragraphs (about half a page), keep the section title in each chunk, and store the page number as the source name. One chunk for the whole book gives one vector that matches every question equally badly and fills the context window; one chunk per sentence loses the context ("it costs 50,000 dinars": what does?). After every new edition of the handbook, run the indexing again.
بەپێی سەردێڕەکان بیکە بە پارچەی چەند بڕگەیی (نزیکەی نیو لاپەڕە)، ناونیشانی بەشەکە لە هەر پارچەیەکدا بهێڵەرەوە و ژمارەی لاپەڕە وەک ناوی سەرچاوە هەڵبگرە. یەک پارچە بۆ هەموو کتێبەکە یەک دەدات کە بە یەکسانی و بە خراپی لەگەڵ هەموو پرسیارێک یەک دەگرێتەوە و پڕ دەکات؛ یەک پارچە بۆ هەر ڕستەیەک کۆنتێکست لەدەست دەدات («50,000 دینارە»: چی؟). دوای هەر چاپێکی نوێی ڕێبەرەکە، ئامادەکردنەکە دیسان بکەرەوە.
Using the prompt that rag_prompt.py printed, what should a good model answer to Can I return a book after 10 days?, and what should it answer to Do you sell school bags?
بە بەکارهێنانی ئەو rag_prompt.py چاپی کرد، باش دەبێت چ وەڵامێک بداتەوە بۆ Can I return a book after 10 days? و چ وەڵامێک بۆ Do you sell school bags?
Show answerوەڵامەکە پیشان بدە
First question: "Yes, you can return it, because returns are allowed within 14 days if you keep the receipt [returns]." Second question: the retrieved chunks say nothing about bags, so the honest answer is "I don't know"; Shilan can then add a chunk about school supplies.
پرسیاری یەکەم: «بەڵێ، دەتوانیت بیگەڕێنیتەوە، چونکە گەڕاندنەوە لە ماوەی 14 ڕۆژدا ڕێگەپێدراوە ئەگەر پسوولەکە بهێڵیتەوە [returns].» پرسیاری دووەم: پارچە هێنراوەکان هیچ لەبارەی جانتا ناڵێن، بۆیە وەڵامی ڕاستگۆیانە «نازانم»ـە؛ پاشان شیلان دەتوانێت پارچەیەک لەبارەی کەلوپەلی قوتابخانە زیاد بکات.
Summaryپوختە
- A vector is a list of numbers; each number is one dimension. An embedding is a vector learned by a model, so that things with similar meaning get nearby vectors.
- All embeddings of a model live in its embedding space (about 1,024 learned dimensions, November 2026); vectors from different models cannot be compared.
- Cosine similarity compares directions (1 same, 0 unrelated); Euclidean distance compares positions (small = close). In Python:
math.sumprod,math.hypot,math.dist(3.12+ forsumprod). - Semantic search finds meaning, not just words; embedding models make the vectors and a vector database finds the nearest ones fast.
- RAG: chunk → embed → store; then question → embed → top-k chunks → prompt "answer only from these, name the source" → answer. It reduces invented answers, but bias, weaker Kurdish, stale indexes and data leaks remain.
- لیستێکی ژمارەیە؛ هەر ژمارەیەک یەک . کە فێری دەبێت، بۆ ئەوەی شتە لێکچووەکان نزیک وەربگرن.
- هەموو لە دەژین (نزیکەی 1,024 فێربوو، مانگی 11ی 2026)؛ جیاواز بەراورد ناکرێن.
- ئاڕاستەکان بەراورد دەکات (1 هەمان، 0 بێپەیوەندی)؛ شوێنەکان بەراورد دەکات (بچووک = نزیک). لە Pythonـدا:
math.sumprod،math.hypot،math.dist(3.12+ بۆsumprod). - واتا دەدۆزێتەوە، نەک تەنیا وشە؛ دروست دەکەن و بە خێرایی نزیکترینەکان دەدۆزێتەوە.
- RAG: ← ← هەڵگرتن؛ پاشان پرسیار ← ← نزیکترین پارچەکان ← «تەنیا لەمانەوە وەڵام بدەرەوە، ناوی سەرچاوە ببە» ← وەڵام. وەڵامی هەڵبەستراو کەم دەکاتەوە، بەڵام ، کوردیی لاوازتر، پێڕستی کۆن و دزەکردنی دەمێننەوە.
Next: how to ask a model well, including how to write the instructions of a RAG prompt: Prompt engineering.
داهاتوو: چۆن بە باشی داوا لە بکەیت، لەوانەش چۆن ڕێنماییەکانی RAG بنووسیت: ئەندازیاریی هەوێن.
Lesson complete!وانەکە تەواو بوو!
Well done. Review the key terms, then go on to the next lesson.دەستخۆش. سەیرێکی زاراوە سەرەکییەکان بکەرەوە، پاشان بڕۆ بۆ وانەی داهاتوو.
Key termsزاراوە سەرەکییەکان
Prompt Engineering: Asking a Model Wellئەندازیاریی هەوێن: چۆن بە باشی داوا لە مۆدێل بکەیت
Related lecturesوانە پەیوەندیدارەکان
- Vectors and Matrices: Arrows, Bold Letters, Aᵀ, A⁻¹ and detئاڕاستەبڕەکان و ماتریکسەکان: تیر، پیتی تۆخ، Aᵀ، A⁻¹ و det
- Machine Learning Basics (Supplementary)بنەماکانی فێربوونی ئامێر (زیادە)
- How Search Engines Workبزوێنەرەکانی گەڕان چۆن کار دەکەن
- AI in Cybersecurity: Bias, Privacy, Surveillance and Deepfakesژیریی دەستکرد لە ئاسایشی سایبەردا: لاسەنگی، تایبەتێتی، چاودێری و دیپفەیکەکان
- Neural Networks and Deep Learningتۆڕە دەمارییەکان و فێربوونی قووڵ
- ASCII and Character CodesASCII و کۆدەکانی نووسە
References and further readingسەرچاوەکان و خوێندنەوەی زیاتر
- Mikolov, Chen, Corrado and Dean (2013): Efficient Estimation of Word Representations in Vector Space (word2vec)
- Google Machine Learning Crash Course: Embeddings, embedding space
- Claude docs: Embeddings (no Anthropic embedding model; Voyage 4: 1,024 dimensions by default; normalised vectors; checked 2026-11-10)
- OpenAI API docs: Embeddings guide (text-embedding-3-small 1,536 and -large 3,072 dimensions; cosine similarity)
- Google Gemini API: Models (Gemini Embedding 2, multimodal)
- Mistral AI: Models overview (Mistral Embed, Codestral Embed)
- Lewis and others (2020): Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks
- OWASP Top 10 for LLM Applications 2025: LLM08 Vector and Embedding Weaknesses
- Python docs: math (sumprod 3.12+, hypot, dist)
This lecture is a first edition. The Kurdish text and terminology are waiting for review by Kurdish IT teachers.ئەم وانەیە چاپی یەکەمە. دەقە کوردییەکە و زاراوەکانی چاوەڕێی پێداچوونەوەی مامۆستایانی کوردی بواری IT ن.