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)⁩ لەگەڵ دروستکەرێکی کە دەتوانیت کاری پێ بکەیت، هەروەها سنوورەکان: ، کوردیی لاوازتر، پێڕستی کۆن و دزەکردن.

19 min read19 خولەک خوێندنەوە · 16 stepsهەنگاو

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)⁩.

The word هەولێر (Erbil) with two arrows. Upper box, Unicode codes, which letters are written: 1607 1749 1608 1604 1742 1585; no meaning, they do not say that Erbil is a city. Lower box, an embedding, what the word means (learned): [0.9, 0.3, 0.2, 0.1, …]; close to Sulaymaniyah [0.9, 0.4, 0.2, 0.1, …]; far from laptop [0.1, 0.0, 0.0, 0.9, …].وشەی «هەولێر» بە دوو تیرەوە. چوارگۆشەی سەرەوە، کۆدەکانی Unicode، کام پیتانە نووسراون: 1607 1749 1608 1604 1742 1585؛ بێ واتا، ناڵێن هەولێر شارە. چوارگۆشەی خوارەوە، ئیمبەدینگێک، واتای وشەکە (فێربوو): [0.9, 0.3, 0.2, 0.1, …]؛ نزیکە لە سلێمانی [0.9, 0.4, 0.2, 0.1, …]؛ دوورە لە لاپتۆپ [0.1, 0.0, 0.0, 0.9, …].
Character codes name the letters; an embedding carries meaning (example numbers).کۆدی پیتەکان ناوی پیتەکان دەبەن؛ واتا هەڵدەگرێت (ژمارەکان نموونەن).CêIT

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 32+42=5\sqrt{3^2 + 4^2} = 5 (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 هەنگاو بۆ سەرەوە». درێژییەکەی 32+42=5\sqrt{3^2 + 4^2} = 5ـە (فیساغۆرس؛ نیشانەکان لە درێژی و ئاڕاستەبڕی یەکەکاندا هاتوون) و لە Pythonـدا math.hypot(3, 4) 5.0 دەدات. هەر ژمارەیەک یەک : دوو ژمارە خاڵێکن لەسەر نەخشە، سێ ژمارە خاڵێک لە ژوورێکدا. سەدان یان هەزاران هەیە. ناتوانین ئەوە بکێشین، بەڵام Python لیستێکی ⁦1,024⁩ ژمارەیی بە هەمان ئاسانیی لیستێکی دوو ژمارەیی بەڕێوە دەبات.

Left: a grid from 0 to 5 with an arrow from the origin to the point (3, 4), labelled [3, 4]; dashed lines show 3 right and 4 up, and the arrow is labelled length 5. Right: four cards. [3, 4]: 2 dimensions, a point on a map. [3, 4, 2]: 3 dimensions, a point in a room. [0.9, 0.3, 0.2, 0.1]: 4 dimensions, we cannot draw it. [0.012, −0.031, …]: 1,024 dimensions, a typical embedding (2026). Below: math.hypot(3, 4) gives 5.0.چەپ: تۆڕێک لە 0 تا 5 لەگەڵ تیرێک لە سەرەتاوە بۆ خاڵی (3, 4)، کە نووسراوە [3, 4]؛ هێڵی پچڕپچڕ 3 بۆ ڕاست و 4 بۆ سەرەوە پیشان دەدەن و لەسەر تیرەکە نووسراوە درێژی 5. ڕاست: چوار کارت. [3, 4]: 2 ڕەهەند، خاڵێک لەسەر نەخشە. [3, 4, 2]: 3 ڕەهەند، خاڵێک لە ژوورێکدا. [0.9, 0.3, 0.2, 0.1]: 4 ڕەهەند، ناتوانین بیکێشین. [0.012, −0.031, …]: 1,024 ڕەهەند، ئیمبەدینگێکی ئاسایی (2026). خوارەوە: math.hypot(3, 4) 5.0 دەدات.
Two numbers can be drawn as an arrow; an embedding has far more.دوو ژمارە دەکرێت وەک تیرێک بکێشرێن؛ زۆر زیاتری هەیە.CêIT

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⁩ ملیار وشەوە فێر بوو.

An animation in four frames of a 2-D map. At the start (random numbers) ten words are scattered: Kurdistan, Erbil, mountain, culture, bread, tea, rice, computer, phone and internet. During training they drift. After training three groups sit inside dashed ellipses: Kurdistan, Erbil, mountain and culture; computer, phone and internet; bread, tea and rice. Note: a 2-D picture of vectors that really have hundreds of numbers.
An animation in four frames of a 2-D map. At the start (random numbers) ten words are scattered: Kurdistan, Erbil, mountain, culture, bread, tea, rice, computer, phone and internet. During training they drift. After training three groups sit inside dashed ellipses: Kurdistan, Erbil, mountain and culture; computer, phone and internet; bread, tea and rice. Note: a 2-D picture of vectors that really have hundreds of numbers.
Training moves the vectors of words that are used together closer.ڕاهێنان ئەو وشانەی پێکەوە بەکار دێن لە یەکتر نزیک دەکاتەوە.CêIT

Embeddings: numbers learned from useئیمبەدینگەکان: ژمارەگەلێک کە لە بەکارهێنانەوە فێر دەبن

Like shops in the bazaarوەک دوکانەکانی بازاڕ

Neighbours by meaningدراوسێ بەپێی واتا

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⁩).

A hand-made 2-D map with a horizontal axis from savoury to sweet and a vertical axis from plain to filled. Points: kubba (کوبە) and dolma (دۆڵمە) top left inside a green ellipse labelled savoury and filled; kulicha (کلێچە) and baklava (بەقڵاوە) top right inside an orange ellipse labelled sweet and filled; kebab (کەباب) and bread (نان) bottom left and middle; halva (حەلاوە) bottom right. A box: real embedding spaces have about 1,024 dimensions, learned, with no neat names.نەخشەیەکی دوو ڕەهەندیی دەستکرد بە تەوەرەیەکی ئاسۆیی لە سوێرەوە بۆ شیرین و تەوەرەیەکی ستوونی لە سادەوە بۆ پڕکراو. خاڵەکان: کوبە و دۆڵمە لە سەرەوەی چەپ لە ناو هێلکەیییەکی سەوزدا کە نووسراوە سوێر و پڕکراو؛ کلێچە و بەقڵاوە لە سەرەوەی ڕاست لە ناو هێلکەیییەکی پرتەقاڵیدا کە نووسراوە شیرین و پڕکراو؛ کەباب و نان لە خوارەوەی چەپ و ناوەڕاست؛ حەلاوە لە خوارەوەی ڕاست. چوارگۆشەیەک: فەزای ئیمبەدینگی ڕاستەقینە نزیکەی 1,024 ڕەهەندی هەیە، فێربوو و بێ ناوی ڕوون.
Similar dishes are neighbours on this hand-made meaning map.خواردنە لێکچووەکان لەسەر ئەم نەخشە دەستکردەی واتا دراوسێن.CêIT

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, (a1−b1)2+⋯+(an−bn)2\sqrt{(a_1-b_1)^2 + \cdots + (a_n-b_n)^2}; Python's math.dist(a, b). Small means similar.
  • Cosine similarity: how closely the two arrows point the same way, whatever their lengths: cos⁡θ=a⋅b∥a∥ ∥b∥\cos\theta = \frac{a\cdot b}{\|a\|\,\|b\|}. 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.
  • : دووریی هێڵی ڕاست لە نێوان دوو خاڵەکەدا، (a1−b1)2+⋯+(an−bn)2\sqrt{(a_1-b_1)^2 + \cdots + (a_n-b_n)^2}؛ math.dist(a, b)ـی Python. بچووک واتە لێکچوو.
  • : دوو تیرەکە چەند بەرەو هەمان ئاڕاستە دەڕۆن، درێژییەکانیان هەرچییەک بێت: cos⁡θ=a⋅b∥a∥ ∥b∥\cos\theta = \frac{a\cdot b}{\|a\|\,\|b\|}. سەرەوە ە: ژمارە بەرامبەرەکان لێک بدە و کۆیان بکەرەوە (دوو لێکدانی ئاڕاستەبڕ). خوارەوە دوو درێژییەکە لێک دەدات. 1 واتە هەمان ئاڕاستە، 0 بێپەیوەندی (ستوون لەسەر یەک) و ⁦−1⁩ پێچەوانە.
a=[1,2], b=[2,4]:a⋅b=1⋅2+2⋅4=10,cos⁡θ=105 20=1010=1a=[1,2],\ b=[2,4]:\quad a\cdot b = 1\cdot 2 + 2\cdot 4 = 10,\quad \cos\theta = \frac{10}{\sqrt{5}\,\sqrt{20}} = \frac{10}{10} = 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⁩ـە.

Everyday analogyنموونەیەک لە ژیانی ڕۆژانەوە

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 ئەمە دەڵێن).

Two panels on grids. Left, same direction, different length: a = [1, 2] and b = [2, 4] lie on one line; cosine = 1.00, distance = 2.24. Right, nearer but another direction: a = [1, 2] and c = [2, 0.5]; cosine = 0.65, distance = 1.80. A dashed line joins the arrow tips in each panel.دوو بەش لەسەر تۆڕ. چەپ، هەمان ئاڕاستە، درێژیی جیاواز: a = [1, 2] و b = [2, 4] لەسەر یەک هێڵن؛ cosine = 1.00، distance = 2.24. ڕاست، نزیکترە بەڵام ئاڕاستەی جیاوازە: a = [1, 2] و c = [2, 0.5]؛ cosine = 0.65، distance = 1.80. هێڵێکی پچڕپچڕ سەری تیرەکان لە هەر بەشێکدا بەیەکەوە دەبەستێت.
c is nearer by distance, but b is more similar by direction.c بەپێی دووری نزیکترە، بەڵام b بەپێی ئاڕاستە لێکچووترە.CêIT

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() دووریی نێوان دوو خاڵ. خوارەوە تەنیا چوار ژمارەی دەستکردیان هەیە بۆ ئەوەی بتوانین بیانخوێنینەوە؛ ڕاستەقینە فێر دەبێت و زۆر درێژترە.

Rank words by cosine similarity to Erbilڕیزکردنی وشەکان بەپێی لێکچوونی کۆساین لەگەڵ هەولێرcosine.pyPYTHONType in a terminalلە تێرمیناڵدا بینووسە
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))
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)⁩؛ هەڵگورد (شاخێک) و کەباب تەنیا نیوە پەیوەندیدارن؛ لاپتۆپ دوورە. ئەم ڕیزبەندییە ڕێک ئەو کارەیە کە گەڕان بەپێی واتا دەیکات، بە فێربوو لەبری دەستکرد.

Horizontal bars of cosine similarity to Erbil from the program's output: Erbil 1.000, Sulaymaniyah 0.996, Halgurd 0.501, kebab 0.401, laptop 0.204. Note: 1 means the same direction; near 0 means unrelated.ستوونی ئاسۆیی لێکچوونی کۆساین لەگەڵ هەولێر لە دەرخستەی بەرنامەکەوە: Erbil 1.000، Sulaymaniyah 0.996، Halgurd 0.501، kebab 0.401، laptop 0.204. تێبینی: 1 واتە هەمان ئاڕاستە؛ نزیک لە 0 واتە بێپەیوەندی.
The program's ranking as a chart.ڕیزبەندیی وەک چارتێک.CêIT

Why 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). ئەمە ئەو بیرۆکەیە بۆ وەسفی شەش کتێب لە لیستی کتێبەکانی شیلان:

Word-count vectors and cosine rankingئاڕاستەبڕی ژمارەی وشە و ڕیزکردن بە کۆساینword_search.pyPYTHONType in a terminalلە تێرمیناڵدا بینووسە
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")
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 دادەنێت، چونکە خەڵک ئەم وشانە بە شێوەی لێکچوو بەکار دەهێنن. بۆیە هەن.

A table of word-count vectors over the vocabulary words about, children, for, mountains, readers, stories, young and more. B2 (stories for children about animals…): 1 1 1 1 0 1 0. B5 (short stories for young readers): 0 0 1 0 1 1 1. B6 (kurdish poems about the mountains): 1 0 0 1 0 0 0. The query tales for kids: only for is 1, highlighted. Note: tales and kids are not in the vocabulary, so they become invisible; only for is left.خشتەیەکی ئاڕاستەبڕی ژمارەی وشە بەسەر وشەکانی وشەنامەدا: about، children، for، mountains، readers، stories، young و زیاتر. B2 (stories for children about animals…): 1 1 1 1 0 1 0. B5 (short stories for young readers): 0 0 1 0 1 1 1. B6 (kurdish poems about the mountains): 1 0 0 1 0 0 0. پرسیاری tales for kids: تەنیا for 1ـە و دیاری کراوە. تێبینی: tales و kids لە وشەنامەکەدا نین، بۆیە نابینرێن؛ تەنیا for دەمێنێتەوە.
Words outside the vocabulary are invisible to a word-count vector.ئەو وشانەی لە دەرەوەی وشەنامەکەن بۆ ژمارەی وشە نابینرێن.CêIT

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.

شیلان شەش کتێبی هەیە؛ کتێبخانەیەک یان کۆمپانیایەک لەوانەیە ملیۆنان پارچە دەقی هەبێت. بەراوردکردنی پرسیارێک لەگەڵ هەموویاندا هێواشە. هەر لەگەڵ ژمارەی ناسنامە و دەقەکەی هەڵدەگرێت و پێڕستێک دروست دەکات کە بە خێرایی پرسیارێک دەدۆزێتەوە؛ هەمان بیرۆکەیە کە لە نزیکترین دراوسێـدا هاتووە، بە قەبارەیەکی زۆر گەورەتر. زۆربەیان گەڕانی نزیکەیی بەکار دەهێنن: سەرەتا لە بەڵێندارترین بەشی فەزاکەدا دەگەڕێن، بۆیە زۆر خێران و نزیکەی هەمیشە باشترین هاوتاکان دەدۆزنەوە. هەندێکیان بەرهەمی سەربەخۆن؛ هەندێکی تر تایبەتمەندییەکی زیادەی ئاسایین.

Left: rows of a vector database, each with an id, a vector and its text: B1 [0.12, −0.40, …] kurdish food…, B2 [0.33, 0.08, …] stories for…, B3, B4, B5 and millions more. Right: a cloud of points with a star for the question's vector; a dashed circle around it marks the most promising area, and lines join the star to its 3 nearest points. Labels: search the most promising area first (approximate); the question's vector: return the 3 nearest.چەپ: ڕیزەکانی بنکەدراوەیەکی ئاڕاستەبڕ، هەریەکە بە ژمارەی ناسنامە، ئاڕاستەبڕێک و دەقەکەی: B1 [0.12, −0.40, …] kurdish food…، B2 [0.33, 0.08, …] stories for…، B3، B4، B5 و ملیۆنانی تر. ڕاست: هەورێک لە خاڵ و ئەستێرەیەک بۆ ئاڕاستەبڕی پرسیارەکە؛ بازنەیەکی پچڕپچڕ بە دەوریدا بەڵێندارترین ناوچە دیاری دەکات و هێڵەکان ئەستێرەکە بە 3 نزیکترین خاڵەوە دەبەستنەوە. نووسینەکان: سەرەتا لە بەڵێندارترین ناوچەدا بگەڕێ (نزیکەیی)؛ ئاڕاستەبڕی پرسیارەکە: 3 نزیکترین بگەڕێنەوە.
Store vectors with their text; return the nearest ones fast. لەگەڵ دەقەکانیان هەڵبگرە؛ نزیکترینەکان بە خێرایی بگەڕێنەوە.CêIT

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⁩) ئەمە بە دوو بەش چارەسەر دەکات:

  1. 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.

    بەڵگەنامەکان بکە بە پارچەی چەند بڕگەیی ()، بۆ هەر پارچەیەک دروست بکە و لەگەڵ دەقەکانیان لە هەڵبگرە.

  2. 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⁩)، بیانخەرە ناو لەگەڵ ڕێنمایی «تەنیا لەم سەرچاوانە وەڵام بدەرەوە و ناوی سەرچاوەکە ببە» و با وەڵامەکە بنووسێت.

Everyday analogyنموونەیەک لە ژیانی ڕۆژانەوە

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 تەنیا هێندەی ئەو پارچانە باشە کە دەیانهێنێتەوە، بۆیە سەرچاوە ناوبراوەکە بپشکنە.

An animation of the RAG pipeline in six frames. Top row, 1 Indexing: documents, chunks, embedding model, vector database light up in turn. Bottom row, 2 Answering: question, embedding, top-k chunks (a dashed arrow comes down from the vector database), prompt with sources and question, language model, and answer with source. The captions say: Shilan's shop documents (prices, delivery, returns, opening hours); cut them into chunks; embed every chunk and store it; a question arrives, embed it and fetch the nearest chunks; put the chunks into the prompt; the answer comes from the shop's own documents and names its source.
An animation of the RAG pipeline in six frames. Top row, 1 Indexing: documents, chunks, embedding model, vector database light up in turn. Bottom row, 2 Answering: question, embedding, top-k chunks (a dashed arrow comes down from the vector database), prompt with sources and question, language model, and answer with source. The captions say: Shilan's shop documents (prices, delivery, returns, opening hours); cut them into chunks; embed every chunk and store it; a question arrives, embed it and fetch the nearest chunks; put the chunks into the prompt; the answer comes from the shop's own documents and names its source.
RAG: index the documents once, then retrieve and answer for every question.RAG: یەکجار بەڵگەنامەکان ئامادە بکە، پاشان بۆ هەر پرسیارێک بهێنەوە و وەڵام بدەرەوە.CêIT

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 دروست دەکات:

Retrieve the top 2 chunks and build the promptدوو نزیکترین پارچە بهێنەوە و هەوێنەکە دروست بکەrag_prompt.pyPYTHONType in a terminalلە تێرمیناڵدا بینووسە
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)
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ـی تێدایە: هێنانەوە هەرگیز تەواو نییە، بۆیە ڕێنماییەکە گرنگە.

The printed prompt as a card in three coloured bands. Band 1, instructions: answer using only the sources below, name the source in brackets, answer I don't know if the sources do not say. Band 2, 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. Band 3: Question: Can I return a book after 10 days? Labels at the side explain each band.هەوێن چاپکراوەکە وەک کارتێک بە سێ پشتێنەی ڕەنگاوڕەنگ. پشتێنەی 1، ڕێنمایی: تەنیا لە سەرچاوەکانی خوارەوە وەڵام بدەرەوە، ناوی سەرچاوە لە ناو کەوانەدا بنووسە، ئەگەر سەرچاوەکان نەیڵێن بڵێ نازانم. پشتێنەی 2، سەرچاوەکان: [returns] دەتوانیت لە ماوەی 14 ڕۆژدا کتێب بگەڕێنیتەوە ئەگەر پسوولەکە بهێڵیتەوە؛ [delivery] لە ماوەی دوو ڕۆژدا لە سلێمانی دەیگەیەنین؛ گەیاندن 3,000 دینارە. پشتێنەی 3: پرسیار: دەتوانم دوای 10 ڕۆژ کتێبێک بگەڕێنمەوە؟ نووسینەکانی تەنیشت هەر پشتێنەیەک ڕوون دەکەنەوە.
The three parts of a RAG prompt.سێ بەشەکەی RAG.CêIT

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 وەڵامی هەڵبەستراو کەم دەکاتەوە، نایسڕێتەوە: هێشتا دەتوانێت سەرچاوەکان هەڵە بخوێنێتەوە یان تێکەڵیان بکات (سنوور و سەلامەتی).
Two columns. Uses: search by meaning; recommendations (you may also like); grouping similar messages; finding duplicates; RAG, answers from your documents. Limits: bias learned from human text; weaker Kurdish vectors; a stale index, old chunks and old answers; private documents leaking to other users; RAG reduces, not removes, invented answers.دوو ستوون. بەکارهێنانەکان: گەڕانی واتایی؛ پێشنیارکردن (لەوانەیە ئەمەشت بەدڵ بێت)؛ کۆکردنەوەی نامە لێکچووەکان؛ دۆزینەوەی دووپاتەکان؛ RAG، وەڵام لە بەڵگەنامەکانی خۆتەوە. سنوورەکان: لاسەنگی کە لە دەقی مرۆڤەوە فێر بووە؛ ئاڕاستەبڕی کوردیی لاوازتر؛ پێڕستی کۆن، پارچەی کۆن و وەڵامی کۆن؛ دزەکردنی بەڵگەنامەی تایبەت بۆ بەکارهێنەرانی تر؛ RAG وەڵامی هەڵبەستراو کەم دەکاتەوە، نایسڕێتەوە.
What embeddings are used for, and what to watch. بۆ چی بەکار دێن و ئاگاداری چی بیت.CêIT

Common mistakesهەڵە باوەکان

A programming mistake: comparing vectors of different lengths. math.sumprod refuses:

هەڵەیەکی بەرنامەسازی: بەراوردکردنی درێژیی جیاواز. math.sumprod ڕەتی دەکاتەوە:

Wrong: one number is missingهەڵە: ژمارەیەک ونەcosine_mistake.pyPYTHONType in a terminalلە تێرمیناڵدا بینووسە
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))

Fix: 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ڕاهێنانەکان

ExerciseڕاهێنانCosine by handکۆساین بە دەست

Compute the cosine similarity of [1, 0] and [1, 1]. What angle is that?

[1, 0] و [1, 1] بژمێرە. ئەمە چ گۆشەیەکە؟

Show answerوەڵامەکە پیشان بدە
a⋅b=1⋅1+0⋅1=1,∥a∥=1,∥b∥=2,cos⁡θ=12≈0.707a\cdot b = 1\cdot 1 + 0\cdot 1 = 1,\quad \|a\| = 1,\quad \|b\| = \sqrt{2},\quad \cos\theta = \frac{1}{\sqrt{2}} \approx 0.707

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)⁩دان.

ExerciseڕاهێنانPick the nearestنزیکترین هەڵبژێرە

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 لەبارەی شتێکی ترە.

ExerciseڕاهێنانChunk a college handbookڕێبەرێکی کۆلێژ بکە بە پارچە

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⁩ دینارە»: چی؟). دوای هەر چاپێکی نوێی ڕێبەرەکە، ئامادەکردنەکە دیسان بکەرەوە.

ExerciseڕاهێنانRead the RAG outputدەرخستەی RAG بخوێنەوە

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+ for sumprod).
  • 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زاراوە سەرەکییەکان

Next lessonوانەی داهاتوو

Prompt Engineering: Asking a Model Wellئەندازیاریی هەوێن: چۆن بە باشی داوا لە مۆدێل بکەیت

References and further readingسەرچاوەکان و خوێندنەوەی زیاتر

This lecture is a first edition. The Kurdish text and terminology are waiting for review by Kurdish IT teachers.ئەم وانەیە چاپی یەکەمە. دەقە کوردییەکە و زاراوەکانی چاوەڕێی پێداچوونەوەی مامۆستایانی کوردی بواری IT ن.

Appearanceڕووکار

Modeدۆخ
Styleشێواز
Coloursڕەنگەکان

Saved on this device only.تەنیا لەسەر ئەم ئامێرە پاشەکەوت دەکرێت.