অধ্যায় 11 · প্র্যাকটিস ল্যাব ও ক্যাপস্টোন
ক্যাপস্টোন, চিট শিট ও এরপর কী
- পৃষ্ঠা 22 / 22
- 23 মিনিট পড়া
ঢাকার নাদিয়া কুড়িটা পাতা ধরে একটা প্রজেক্ট বানিয়েছেন। তাঁর টিম লিড তিনটা প্রশ্ন করেন: এটা কি পরিষ্কার মেশিনে চলে, ব্রিফে যা বলা ছিল এটা কি তা করে, আর এটা কী করে না? অন্য কেউ নাদিয়াকে জিজ্ঞেস না করেই দশ মিনিটে এই প্রশ্নগুলোর উত্তর দিতে পারলে তবেই প্রজেক্ট শেষ। এই পাতাটা সেই দশ মিনিট: ব্রিফ, সেটা যাচাই করার একটা স্ক্রিপ্ট, এক পাতার কমান্ড, সিস্টেমের একটা মানচিত্র, যে ব্যর্থতাগুলোর মুখোমুখি হবেন সেগুলো, আর সামনের পথ।
এখানে সবকিছু অফলাইনে চলে। মডেলটা ছোট একটা বিকল্প, ভাষা মডেল নয়; আসল মডেল কম অনুমানযোগ্য, আর ঠিক সে কারণেই টেস্ট করতে হয়। এই পাতা একটা ছোট ফোল্ডার capstone/ আর একটা টেস্ট ফাইল যোগ করে, আগে থেকে থাকা কিছুই বদলায় না। গ্রেড-করা অনুশীলন আছে প্র্যাকটিস ল্যাব পাতায়; এই পাতা সেগুলো আবার করে না।
যা শিখবেন
- ক্যাপস্টোন ব্রিফ, তার পাঁচটা মাইলস্টোন, প্রতিটার পেছনের আগের পাতা ও কিট মডিউলের সঠিক নাম, এবং প্রতিটা মাইলস্টোনের জন্য চালানো যায় এমন একটা গ্রহণযোগ্যতার চেক।
- গ্রেডিং রুব্রিক কীভাবে কিটে থাকা প্রমাণের সঙ্গে মেলে, আর গ্রহণযোগ্যতার চেকলিস্ট কীভাবে স্ক্রিপ্ট হয়।
- এক পাতার চিট শিট: কমান্ড, বিশ্বাসের সীমানাসহ আর্কিটেকচারের সারাংশ, আর সত্যিই ঘটিয়ে দেখা ব্যর্থতা থেকে তৈরি ট্রাবলশুটিং চেকলিস্ট।
- বিগিনার টিউটোরিয়াল ইচ্ছা করে যা বাদ দিয়েছে, কিটের সৎ সীমাবদ্ধতা, আর অ্যাডভান্সড টিউটোরিয়ালের পথ।
ক্যাপস্টোন ব্রিফ
লক্ষ্য। একটা ছোট অ্যাসিস্ট্যান্ট, যে লোকাল ডকুমেন্টের ছোট একটা সংগ্রহ নিয়ে প্রশ্নের উত্তর দেয়, প্রমাণ উদ্ধৃত করে (cite), আর উত্তর না পেলে বিরত থাকে (abstain)। ব্যবহারকারী কাল্পনিক Kestrel Cycles-এর একজন গ্রাহক; ডেটা সিনথেটিক। প্রয়োজনীয় সব ফিচার কিটে আগেই আছে, তাই ক্যাপস্টোন হলো জোড়া লাগানো আর প্রমাণ করা, নতুন কোড লেখা নয়। কোন ফিচার কোন পাতায় শেখানো হয়েছে, তা নিচের মাইলস্টোনের সঙ্গে বলা আছে।
| প্রয়োজনীয় ফিচার | কোথায় আছে |
|---|---|
| প্রোভাইডার-নিরপেক্ষ মডেল ইন্টারফেস, ডিফল্ট ফেক ক্লায়েন্ট | llm, config, errors |
| দুটো ঐচ্ছিক প্রোভাইডার অ্যাডাপ্টার | adapter_example-এর প্যাটার্ন; আসলগুলো আপনি যোগ করবেন |
| লোকাল ইনজেশন, চাঙ্কিং, সার্চযোগ্য ইনডেক্স | chunking, embeddings, index, bm25 |
| যাচাই-করা সোর্স আইডি ও অবস্থানসহ উত্তর | rag, citations |
| একটা নিরাপদ, শুধু-পড়ার টুল | tools, permissions |
| স্ট্রিমিং বা নথিভুক্ত একটা সিমুলেশন | streaming, contracts |
| নির্দিষ্ট মূল্যায়ন সেট, রিগ্রেশন টেস্ট, খরচ ও লেটেন্সির কাউন্টার | evals, gate, usage, cache, limits |
| FastAPI এন্ডপয়েন্ট, কনফিগারেশন, README, অফলাইন মোড | api, README.md |
| পাবলিক ডেমোতে শুধু সিনথেটিক ডেটা | corpus/, সিক্রেট ও ফিক্সচার স্ক্যান |
প্রোভাইডার নোট (২০২৬-১০-১২ অনুযায়ী): ব্রিফে OpenAI, Anthropic ও Google Gemini থেকে বাছা দুটো ঐচ্ছিক অ্যাডাপ্টার চাওয়া হয়েছে। Google দুটো API পথের কথা বলে: নতুন Interactions API আগে দেখানো হয়, আর
generateContent-কে লেগাসি বলা হয় কিন্তু এখনো সমর্থিত। Anthropic-এর নিজস্ব এমবেডিং নেই, তাই তার অ্যাডাপ্টার শুধু টেক্সট জেনারেশন করে আর রিট্রিভাল লোকালই থাকে। অ্যাডাপ্টারdocs/INTERFACE.md-এর চারটা কাজ মানে এবং অ্যাডাপ্টারের টেস্ট পাস করে; এই টিউটোরিয়ালের জন্য কোনোটাই চালানো হয়নি। লেখার আগে বর্তমান ডকুমেন্টেশন দেখে নিন।
পাঁচটা মাইলস্টোন, এবং প্রতিটা কীভাবে প্রমাণ করবেন
চেক বলে দিলে তবেই মাইলস্টোন শেষ, শেষ মনে হলে নয়। প্রতিটা সারিতে আছে কোন পাতা দক্ষতাটা শিখিয়েছে, কোন মডিউল জড়িত, আর capstone/accept.py-এর কোন চেক (নিচের M1 থেকে M5)।
| মাইলস্টোন | পাতা | কিট মডিউল | গ্রহণযোগ্যতার চেক |
|---|---|---|---|
| ১. ডকুমেন্ট স্কিমা, ব্যবহারকারীর সমস্যা ও গ্রহণযোগ্যতার মানদণ্ড ঠিক করুন | কনটেক্সটের মান, বাজেট ও পুনরুৎপাদনযোগ্যতা, RAG ইনজেশন ও সাইটেশন প্রবাহ | corpus/ ফ্রন্ট ম্যাটার, chunking.load_documents | M1: প্রতিটা ডকুমেন্টের আইডি অনন্য, স্ট্যাটাস ও ভাষা বৈধ |
| ২. ফেক ক্লায়েন্ট ও লোকাল রিট্রিভাল বেসলাইন বানান | প্রোভাইডার-নিরপেক্ষ LLM ক্লায়েন্ট, এমবেডিং ও সাদৃশ্য, লোকাল ইনডেক্স ও রিট্রিভালের মান | FakeClient, LocalSearch, bm25 | M2: ফেক উত্তর দেয়; লোকাল সার্চ রিটার্ন পলিসি বেছে নেয় |
| ৩. কনটেক্সট সাজানো, উত্তর তৈরি ও সাইটেশন যাচাই যোগ করুন | কনটেক্সট সাজানো ও বিশ্বাসের সীমানা, RAG ইনজেশন ও সাইটেশন প্রবাহ, RAG-এর নির্ভরযোগ্যতা ও মূল্যায়নের ডেটা | context, rag, citations | M3: আসল উত্তর আসল প্রমাণ উদ্ধৃত করে; বানানো আইডি প্রত্যাখ্যাত হয় |
| ৪. টুল যাচাই, টেস্ট ও ব্যর্থতা সামলানো যোগ করুন | টুল চুক্তি ও এক্সিকিউশন, টুলের অনুমতি ও ব্যর্থতা সামলানো, প্রম্পট ইনজেকশন ও অ্যাক্সেসের সীমানা, নিরাপদ ব্যর্থতা ও নিরাপত্তা রিগ্রেশন টেস্ট | tools, permissions, safefail | M4: চারটা খারাপ টুল কল প্রত্যাখ্যাত হয়, একটা ভালো কল চলে |
| ৫. মূল্যায়নের ফল যোগ করুন, অ্যাপ প্যাকেজ করুন, পোর্টফোলিও রিপোর্ট লিখুন | মূল্যায়ন ডেটাসেট ও নির্ধারিত টেস্ট, রুব্রিক, রিগ্রেশন ও রিলিজ গেট, প্যাকেজিং, কনফিগারেশন ও পুনরুৎপাদনযোগ্যতা, ডকুমেন্টেশন, রিলিজ ও পোর্টফোলিওর মান | evals, gate, api, release, docgen | M5: স্বয়ংক্রিয় রিলিজ চেক সব পাস করে |
তিনটা প্রয়োজনীয় ফিচার সব মাইলস্টোনের ওপর দিয়ে যায়: কনফিগারেশন (অ্যাডাপ্টার, কনফিগারেশন ও এরর হ্যান্ডলিং), স্ট্রিমিং (স্ট্রিমিং ও কাঠামোবদ্ধ ফলাফল, নির্ভরযোগ্য আউটপুট চুক্তি) ও খরচ নিয়ন্ত্রণ (খরচ ও লেটেন্সির মূল কথা, বাজেট, ক্যাশিং ও ব্যবহারের সীমা)। এগুলোর প্রমাণ A1 (অফলাইন কনফিগারেশন) আর টেস্ট, যেমন tests/test_streaming.py ও tests/test_limits.py।
স্ক্রিপ্ট হিসেবে গ্রহণযোগ্যতার চেকলিস্ট
ব্রিফ শেষ হয় ছয়টা আইটেমে: পরিষ্কার এনভায়রনমেন্টে সেটআপ কাজ করে; টেস্ট ক্রেডেনশিয়াল ছাড়াই চলে; জানা প্রশ্নে প্রত্যাশিত প্রমাণ মেলে; সমর্থনহীন প্রশ্নে বিরত থাকে; অবৈধ টুল কল প্রত্যাখ্যাত হয়; সীমাবদ্ধতা নথিভুক্ত। capstone/accept.py প্রতিটাকে একটা চেকে (A1 থেকে A6) রূপ দেয়, শুধু আগে থেকে থাকা মডিউল দিয়ে: রিলিজ চেক, মূল্যায়নের ডেটা, ইন-প্রসেস API আর অ্যাবিউজ সেট। দুটো চেক ঠিক করে "পাস" মানে কী, তাই সেগুলো পড়ুন।
# excerpt of kit/capstone/accept.py
GAPS = {"rc15": "answered by the service: secure_answer applies only the min_score threshold, not the margin check that guarded_answer (and the eval) use"}
def a3_known(listed: str | None = None) -> Result:
retriever = build_retriever(KIT / "corpus")
listed = (KIT / "docs" / "EVALUATION.md").read_text(encoding="utf-8") if listed is None else listed
cases = [c for c in load_rag_cases(KIT / "data" / "rag_cases.jsonl") if c.answerable]
found, missed = [], []
for c in cases:
(found if set(c.expected_doc_ids) <= {r.chunk.doc_id for r in retriever.retrieve(c.question)} else missed).append(c.id)
undocumented = [i for i in missed if f"| {i} |" not in listed]
return _ok(not undocumented), f"{len(found)} of {len(cases)} retrieve the expected document; misses {', '.join(missed)} are listed in EVALUATION.md" \
if not undocumented else f"undocumented misses: {undocumented}"
def a4_abstain() -> Result:
cases = [c for c in load_rag_cases(KIT / "data" / "rag_cases.jsonl") if not c.answerable]
answered = sorted(c.id for c in cases if _ask(c.question)["status"] != "refused")
detail = f"{len(cases) - len(answered)} of {len(cases)} unanswerable questions refused"
if answered != sorted(GAPS):
return "FAIL", f"{detail}; answered {answered}, listed gaps {sorted(GAPS)}"
return ("gap", f"{detail}; known gap {', '.join(GAPS)}") if GAPS else ("ok", detail)a3_known একটা মিস তখনই মেনে নেয় যখন docs/EVALUATION.md সেটা আগে থেকে তালিকাভুক্ত করেছে, তাই নতুন, জানানো-হয়নি এমন ব্যর্থতায় চেক ব্যর্থ হয়। a4_abstain ইচ্ছা করে মেনে নেওয়া, জানা একটা গ্যাপের জন্য একই কাজ করে: GAPS বাস্তবের সঙ্গে দুই দিকেই মিলতে হবে, তাই গ্যাপ ঠিক হয়ে গেলে এন্ট্রি সরানো পর্যন্ত চেক ব্যর্থ হয়। পুরো চেকলিস্ট চালান।
python -m capstone.acceptCAPSTONE ACCEPTANCE evidencedesk
[ok ] M1 document schema and acceptance criteria 13 documents, unique ids, status and lang valid
[ok ] M2 fake client and local retrieval baseline fake client answers; local search picks kc-returns-v3
[ok ] M3 context, answer and citation validation cited ['kc-returns-v3:c0'] resolve and support the claim; an invented id is rejected
[ok ] M4 tool validation and failure handling 4 of 4 bad calls rejected, one good call runs
[ok ] M5 evaluation, packaging and report 10 release checks pass (suite not run here)
[ok ] A1 fresh-environment setup works version, exact pins, lock file, data, offline default
[ok ] A2 tests run without credentials defaults need no key (pass --tests to run the suite without any key variable)
[ok ] A3 known questions retrieve expected evidence 10 of 13 retrieve the expected document; misses rc03, rc06, rc08 are listed in EVALUATION.md
[gap ] A4 unsupported questions abstain 2 of 3 unanswerable questions refused; known gap rc15
[ok ] A5 invalid tool calls are rejected 7 of 7 tool-misuse cases of the abuse set end as expected
[ok ] A6 limitations are documented LIMITATIONS.md names 6 of 6 required topics
RESULT: ACCEPTED (0 failed, 1 known gap)gap লাইনটা দেখুন। এই পাতা লেখার সময় পাওয়া এটা একটা সত্যিকারের আবিষ্কার। "Do you sell electric scooters?" প্রশ্নের উত্তর আসে ব্যাটারি চার্জ করার একটা বাক্য দিয়ে: সার্ভিস শুধু স্কোরের থ্রেশহোল্ড প্রয়োগ করে, অথচ মূল্যায়ন আরও কড়া একটা পাইপলাইন ব্যবহার করে, যেটা সেরা দুই ফলাফলের ব্যবধানও দেখে। docs/EVALUATION.md-এর সংখ্যা সেই পাইপলাইনের জন্য সত্য যেটা মাপা হয়েছে, ব্যবহারকারী যেটায় পৌঁছায় সেটার জন্য নয়; সব-সবুজ একটা চেকলিস্ট এটা লুকিয়ে ফেলত। অনুশীলনে গ্যাপটা বন্ধ করবেন আর দেখবেন একটা কেস দেখে ঠিক করা কেন ঝুঁকির। A3-তে উত্তরযোগ্য ১৩টার মধ্যে ১০টা প্রত্যাশিত ডকুমেন্ট পায়; rc13 পাওয়া যায় কিন্তু অস্পষ্টতার কারণে প্রত্যাখ্যাত হয়, তাই মূল্যায়ন চারটা ইংরেজি মিস তালিকাভুক্ত করে আর শুধু-রিট্রিভালের এই চেক তিনটা।
স্ক্রিপ্ট যা দেখাতে পারে না: উত্তরগুলো ভালো কি না। মডেল ফেক, তেরোটা প্রশ্ন ছোট নমুনা, আর "সীমাবদ্ধতা নথিভুক্ত" শুধু দেখে যে ছয়টা বিষয়ের নাম আছে। এটা ভুলে যাওয়ার বিরুদ্ধে পাহারা দেয়; বিচার মানুষের হাতেই থাকে।
গ্রেডিং রুব্রিক ও তার প্রমাণ
ক্যাপস্টোন সাতটা বিভাগে ১০০-এর মধ্যে গ্রেড হয়। প্রমাণ ছাড়া গ্রেড একটা মত মাত্র, তাই প্রতিটা সারি বলে প্রমাণ কোথায় আছে আর সেই প্রমাণ কী দেখাতে পারে না।
| বিভাগ | ওজন | কিটে প্রমাণ | যা দেখাতে পারে না |
|---|---|---|---|
| সঠিকতা ও কাজের আচরণ | ২০% | docs/DEMO.md (সফল, প্রত্যাখ্যান, সামলানো এরর); M2, M3 | আসল মডেল কেমন আচরণ করে |
| রিট্রিভাল, প্রমাণ ও সাইটেশনের মান | ২০% | docs/EVALUATION.md: রিকল, সাইটেশন বৈধতা, ব্যর্থতা; A3 | অর্থ: সাপোর্ট চেক শব্দ মেলায় |
| টেস্ট ও পুনরুৎপাদনযোগ্যতা | ২০% | python -m pytest, সঠিক পিন ও লক ফাইল, release; A1, A2 | যে প্ল্যাটফর্মে চালানো হয়নি সেটা |
| নিরাপত্তা, গোপনীয়তা ও নিরাপদ ব্যর্থতা | ১৫% | অ্যাবিউজ সেট ও tests/test_security.py, সিক্রেট স্ক্যান; A4, A5 | যে আক্রমণ কেউ লিখে রাখেনি |
| আর্কিটেকচার ও রক্ষণাবেক্ষণযোগ্যতা | ১০% | মডিউল বিন্যাস, একমুখী ইমপোর্ট, "কোনো কোর মডিউল অ্যাডাপ্টার ইমপোর্ট করে না" টেস্ট | পরের বদলের খরচ |
| খরচ-সচেতনতা ও এরর সামলানো | ৫% | usage লেজার, limits বাজেট, errors রিট্রাই নীতি | আসল দাম (টেবিলটা বানানো) |
| ডকুমেন্টেশন ও পোর্টফোলিও উপস্থাপনা | ১০% | README আর docs/-এর আটটা ফাইল, docgen --check, M5; A6 | অপরিচিত কেউ এটা পরিষ্কার পায় কি না |
ওজনের যোগফল ১০০। টেস্ট, রিট্রিভাল আর সঠিকতা মিলে ৬০ নেয়, আর মডেল নিজে কোনো বিভাগ নয়: কোর্স মডেলের চারপাশের ইঞ্জিনিয়ারিংকে গ্রেড করে, কারণ সেটাই আপনার নিয়ন্ত্রণে।
চিট শিট: কমান্ড
সবকিছু প্রজেক্ট ফোল্ডার থেকে চালান (যেটায় pyproject.toml আছে)। প্যাকেজ পিন করা আছে requirements.txt-এ; requirements.lock.txt পরীক্ষিত এনভায়রনমেন্টের তালিকা দেয়। নেটওয়ার্ক লাগে শুধু সেটআপে, তাই সেটা এখানে চালানো হয়নি।
# not run here: creates an environment and downloads packages from the network
python3.12 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
python -m pip install -r requirements.txt| কাজ | কমান্ড |
|---|---|
| সব টেস্ট | python -m pytest (শেষ লাইন পড়ুন; pyproject.toml আগেই -q দিয়ে রেখেছে) |
| অফলাইন ডেমো | python -m evidencedesk.api |
| গ্রহণযোগ্যতার চেকলিস্ট | python -m capstone.accept (--tests যোগ করলে সব API কি-ভেরিয়েবল সরিয়ে স্যুট চলে) |
| রিলিজ চেক | python -m evidencedesk.release (স্যুটসহ চালাতে --tests) |
| ডকুমেন্ট আবার তৈরি বা যাচাই | python -m evidencedesk.docgen এবং --check |
| মূল্যায়ন ও রিলিজ গেট | python -m evidencedesk.gate (অপশন --min-score, --min-margin; ব্লক হলে এক্সিট কোড 1) |
একই কমান্ড, সত্যিই চালানো। টেস্ট লাইন থেকে sed দিয়ে পার হওয়া সময় বাদ দেওয়া হয়েছে, কারণ প্রতিবার সেটা আলাদা হয়।
python -m pytest | tail -1 | sed 's/ in [0-9.]*s//'
python -m evidencedesk.api
python -m capstone.accept | tail -1
python -m evidencedesk.release --tests | grep RESULT
python -m evidencedesk.docgen --check
python -m evidencedesk.gate | sed -n '4,9p;$p'495 passed, 1 xfailed
GET /health -> 200 {"status": "alive"}
GET /ready -> 200 {"chunks": 36, "offline": true, "ready": true, "reason": ""}
POST /ask -> 200 answered req-1: Refunds go back to the original payment method within 5 business days after the warehouse receives the item. [kc-returns-v3:c2]
POST /ask -> 200 refused req-2: Not enough evidence in the help centre to answer this. Please contact Kestrel Cycles support.
POST /ask -> 401 refused req-3: I cannot help with that request. Please contact Kestrel Cycles support.
RESULT: ACCEPTED (0 failed, 1 known gap)
RESULT: READY (0 failed, 0 skipped)
docs are up to date
recall_at_k 0.882
citation_validity 1.0
abstention_correct 0.773
tool_pass 1.0
format_pass 1.0
pass_rate 0.848
GATE: GOকোনো পাতা টেস্ট যোগ করলেই টেস্টের সংখ্যা বাড়ে (প্র্যাকটিস ল্যাব নিজের টেস্ট যোগ করে), তাই নির্দিষ্ট সংখ্যা নয়, failed শব্দটা খুঁজুন। গেটের লাইনগুলোই মূল্যায়নের সেই সংখ্যা, যার দিকে রুব্রিক নির্দেশ করে।
টুল নোট (২০২৬-১০-১২ অনুযায়ী): Python 3.12 সমর্থিত থাকবে 2028-10 পর্যন্ত, Python 3.10 এর জীবনকাল শেষ হয়েছে 2026-10-01-এ, আর বর্তমান numpy-র জন্য 3.12 বা নতুন লাগে; তাই প্রজেক্ট 3.12 পিন করে। uvicorn 0.54.0 একটা বর্তমান ASGI সার্ভার হিসেবে তালিকাভুক্ত; কিট এর ওপর নির্ভর করে না এবং এখানে কোনো আসল সার্ভার চালানো হয়নি, কারণ API সবসময় ইন-প্রসেস ডাকা হয়েছে। চালানোর আগে বর্তমান ডকুমেন্টেশন দেখে নিন।
চিট শিট: এক পাতায় আর্কিটেকচার
কলার থেকে রিপ্লাই পর্যন্ত একটা রিকোয়েস্ট, আর যে দুই জায়গায় বিশ্বাস থামে। প্রম্পট গার্ডরেইল নয়: প্রতিটা সীমানা কোড দিয়ে পাহারা দেওয়া এবং টেস্ট করা।
UNTRUSTED: the caller, the documents, retrieved text, the model's words, tool output
caller --POST /ask--> api.py settings, request model, /health, /ready
(x-user-id) |
v safefail.safe_answer: identity, task, input size, one reply shape
======== boundary 1: from here on the input is treated as hostile ===============================
corpus/ --chunking--> embeddings, index --> rag.Retriever (bm25 is the keyword baseline)
| evidence labelled untrusted, injection signals flagged, secrets screened
v
context + budgets --> llm.LLMClient (fake model, or an adapter) usage ledger, cache, limits
======== boundary 2: the model is not trusted either ============================================
JSON reply --> results, contracts (stop reason, schema) --> citations (ids resolve, claim supported)
--> tools + permissions (allowlist, call limits, approval) --> secret screen
|
caller <-- {status, message, request_id} no codes, no paths, no stack traces; log redacted
Beside the request path, offline: evals + gate (compare with the baseline), release + docgen (docs)কিছু ব্যর্থ হলে আগে তীরটা খুঁজুন, তারপর যে মডিউল সেটা পাহারা দেয়, তারপর যে টেস্ট সেটা আটকে রাখে। ইমপোর্ট নিচের দিকে যায়: api থেকে safefail, security হয়ে llm-এ।
ট্রাবলশুটিং চেকলিস্ট
প্রতিটা সারি হলো লক্ষণ, সম্ভাব্য কারণ, যে চেক কারণটা নিশ্চিত করে, আর সমাধান। টেবিলের পরের সাতটা ব্যর্থতা ফেলে-দেওয়ার-মতো কপিতে ঘটিয়ে দেখা হয়েছে; বার্তাগুলো আসল।
| লক্ষণ | সম্ভাব্য কারণ | চেক | সমাধান |
|---|---|---|---|
/ready 503 দেয়, /health 200 দেয় | কর্পাস ফোল্ডার নেই বা খালি | reason ফিল্ডে এক্সেপশনের ধরন থাকে | EVIDENCEDESK_CORPUS_DIR ঠিক করুন বা ফোল্ডার ফিরিয়ে আনুন |
ইমপোর্টে বা টেস্টে DatasetDrift | ডেটা ফাইল বদলেছে কিন্তু ম্যানিফেস্টের হ্যাশ বদলায়নি | বার্তার দুটো হ্যাশ মেলান | ইচ্ছা করে ভার্সন বাড়িয়ে ম্যানিফেস্ট আবার লিখুন; এররটা কখনো লুকাবেন না |
রিলিজ চেক: exact pins ব্যর্থ, অথবা পিন টেস্ট ব্যর্থ | requirements.txt-এ একটা ঢিলা লাইন, অথবা লক ফাইলে নেই এমন পিন | ফাইলে grep -v '==' | হুবহু ভার্সনে পিন করুন; একই বদলে লক ফাইল হালনাগাদ করুন |
| রিলিজ চেক: সিক্রেটের আকারের একটা ফলাফল | কোনো ফাইলে API কি, টোকেন বা ব্যক্তিগত ডেটা | বার্তা ফাইল ও লাইন দেয়, মান কখনো নয় | সরান, আসল হলে বদলে ফেলুন, নয়তো লিখিত কারণসহ অনুমতি দিন |
out of date: <file> | তৈরি-করা ডকুমেন্ট হাতে বদলানো হয়েছে, অথবা কোড বদলেছে | python -m evidencedesk.docgen --check | docgen চালিয়ে পার্থক্য পড়ুন |
No module named 'evidencedesk' | ভুল ওয়ার্কিং ফোল্ডার, অথবা প্যাকেজ পাথে নেই | pwd এবং ls pyproject.toml | প্রজেক্ট ফোল্ডার থেকে চালান; pytest নিজেই পাথ ঠিক করে |
GATE: BLOCK | কোনো মেট্রিক সীমার নিচে নেমেছে বা ক্রিটিক্যাল কেস ব্যর্থ | block: লাইনগুলো পড়ুন; বেসলাইন ফাইলই রেফারেন্স | কারণ ঠিক করুন; মানুষ পার্থক্য রিভিউ করার পরেই বেসলাইন বদলান |
| একটা সাইটেশন প্রত্যাখ্যাত | যে আইডি নেই, যেটা দেখানো হয়নি, অথবা যে দাবি টেক্সট সমর্থন করে না | নিচের রিপোর্ট | রিট্রিভাল বা রিপ্লাই ঠিক করুন; চেক ঢিলা করবেন না |
প্রতিটা কেস একটা নতুন কপি ভাঙে, তাই যা ভাঙছেন তা ভাঙা থাকে না।
fresh() { rm -rf ../scratch && cp -r . ../scratch && cd ../scratch; } # every case breaks a throw-away copy
( fresh; echo "--- 1 corpus folder missing"
EVIDENCEDESK_CORPUS_DIR=/nonexistent python - <<'EOF'
import os
from fastapi.testclient import TestClient
from evidencedesk.api import create_app, load_app_settings
with TestClient(create_app(load_app_settings(os.environ))) as http:
for path in ("/health", "/ready"):
response = http.get(path)
print(path, response.status_code, response.json())
EOF
)
( fresh; echo "--- 2 a data file edited"
echo '{"id": "x"}' >> data/eval_extra.jsonl
python -c "from pathlib import Path; from evidencedesk.evals import load_dataset; load_dataset(Path('data/eval_manifest.json'), None)" 2>&1 | tail -1 )
( fresh; echo "--- 3 a dependency pin loosened"
sed -i 's/^numpy==.*/numpy>=2.5/' requirements.txt
python -m evidencedesk.release | grep FAIL
python -m pytest tests/test_api.py -k exact_pins | grep ^FAILED )
( fresh; echo "--- 4 a secret-shaped line"
echo 'api_key = "abcdefghijklmnop1234"' > notes.txt
python -m evidencedesk.release | grep FAIL )
( fresh; echo "--- 5 a generated document edited by hand"
echo "edit" >> docs/LIMITATIONS.md
python -m evidencedesk.docgen --check )
( fresh; echo "--- 6 started from the wrong folder"
cd .. && env -u PYTHONPATH python -m evidencedesk.api 2>&1 | tail -1 | sed 's/^.*python: //' )
( fresh; echo "--- 7 a gate threshold that breaks the baseline"
python -m evidencedesk.gate --min-score 0.9 | grep -E "^GATE|block:" )--- 1 corpus folder missing
/health 200 {'status': 'alive'}
/ready 503 {'ready': False, 'reason': 'FileNotFoundError', 'chunks': 0, 'offline': True}
--- 2 a data file edited
evidencedesk.evals.DatasetDrift: eval_extra.jsonl changed (manifest 72ed5a9aa64c773e, file 66039b58eaa0483b): bump the version, update the manifest
--- 3 a dependency pin loosened
[FAIL] exact pins not pinned exactly: ['numpy>=2.5']
FAILED tests/test_api.py::test_requirements_are_exact_pins_and_the_lock_contains_them
--- 4 a secret-shaped line
[FAIL] secrets and sensitive fixtures 1 finding(s): ['notes.txt:1 hard-coded secret']
--- 5 a generated document edited by hand
out of date: LIMITATIONS.md
--- 6 started from the wrong folder
Error while finding module specification for 'evidencedesk.api' (ModuleNotFoundError: No module named 'evidencedesk')
--- 7 a gate threshold that breaks the baseline
GATE: BLOCK
block: critical case rc09 failed its abstention check
block: citation_validity None is below the floor 0.9
block: pass_rate 0.485 is below the floor 0.8
block: citation_validity fell from 1.0 to Noneকেস 1 হলো API-তে দুটো এন্ডপয়েন্টের কারণ: চালু (200) কিন্তু প্রস্তুত নয় (503), আর reason-এ শুধু এক্সেপশনের ধরন থাকে, কারণ টেক্সটে পাথ থাকতে পারে। কেস 2 আপনাকে অলক্ষ্যে বদলে যাওয়া ডেটায় মূল্যায়ন করা থেকে আটকায়। কেস 3 একটা কারণেই দুটো স্তর ভাঙে। কেস 4 ফাইল ও লাইন ছাপে, সিক্রেট কখনো নয়। কেস 6-এ কারণ ফোল্ডার, কোড নয়। কেস 7-এ গেট নকশা অনুযায়ী কাজ করে: প্রায় সবকিছু প্রত্যাখ্যান করা একটা থ্রেশহোল্ড বেসলাইন ভাঙে, এক্সিট কোড 1।
একটা সাইটেশন তিন ভিন্ন কারণে ব্যর্থ হতে পারে, আর সমাধান আলাদা বলে চেকার সেগুলো আলাদা রাখে।
from pathlib import Path
from evidencedesk.citations import check_citations
from evidencedesk.evals import build_retriever
retriever = build_retriever(Path("corpus"))
question = "How long do I have to return a new bike?"
shown, known = retriever.retrieve(question), set(retriever.chunks)
outside = next(i for i in sorted(known) if i not in {r.chunk.id for r in shown})
good = "You can return a new bike within 30 days of delivery."
for label, claim, cited in (("invented id", good, ["kc-nope:c9"]), ("real id, not shown", good, [outside]),
("real id, wrong number", good.replace("30", "45"), ["kc-returns-v3:c0"]), ("valid", good, ["kc-returns-v3:c0"])):
r = check_citations(claim, cited, shown, known)
print(f"{label:<22} ok={r.ok} invented={r.invented} outside={r.outside} missing_numbers={r.support.numbers_missing if r.support else None}")invented id ok=False invented=('kc-nope:c9',) outside=() missing_numbers=None
real id, not shown ok=False invented=() outside=('kc-assembly-v1:c0',) missing_numbers=None
real id, wrong number ok=False invented=() outside=() missing_numbers=('45',)
valid ok=True invented=() outside=() missing_numbers=()সারি এক: মডেল একটা আইডি বানিয়েছে। সারি দুই: আইডিটা আছে কিন্তু মডেলের সামনে ছিল না। সারি তিন: আসল, দেখানো আইডি, তবু দাবিতে 45 দিন আর টেক্সটে 30 দিন। বৈধ আইডি মানেই সমর্থন নয়। সারি চারও শুধু বোঝায় যে শব্দ ও সংখ্যা অংশটায় আছে, অংশটা প্রশ্নের উত্তর দেয় তা নয়।
পরীক্ষার আগে কী দেখে নেবেন
কুইজ ১ নেয় API ও কনটেক্সটের মূল কথা (পার্ট ১ ও ২), কুইজ ২ নেয় LLM ফিচার বানানো (পার্ট ৩ থেকে ৬), আর হার্ড এক্সাম দশটা পার্ট নেয়, পরের দিকের ওপর জোর দিয়ে। হার্ড এক্সামের প্রতিটা পরিস্থিতির থিমের জন্য কিটে অনুশীলনের জায়গা আছে।
| পরিস্থিতির থিম | যা দিয়ে অনুশীলন করবেন |
|---|---|
| ভুল সাইটেশন | citations.check_citations ও tests/test_citations.py (ওপরের রিপোর্ট) |
| বিকৃত স্ট্রিমিং রেসপন্স | tests/test_streaming.py, tests/test_contracts.py |
| অপ্রাসঙ্গিক চাঙ্ক ফেরত দেওয়া রিট্রিভাল | docs/EVALUATION.md-এর ব্যর্থতাগুলো; tests/test_bm25.py |
| অবৈধ টুল আর্গুমেন্ট | M4, tests/test_tools.py |
| বারবার পেইড কল | tests/test_permissions.py (বারবার একই কল), tests/test_limits.py, tests/test_cache.py |
| প্রম্পট ইনজেকশন ফিক্সচার | data/abuse/abuse_set.jsonl, tests/test_security.py |
| ব্যর্থ রিগ্রেশন টেস্ট | ওপরের কেস 2 ও কেস 7, tests/test_gate.py, tests/test_evals.py |
প্রশ্নে বিচার চাওয়া হয়: একটা এরর বা আউটপুট দেওয়া হলে কারণ কী, আর আপনি কী বদলাবেন? মডেলের নাম, দাম ও SDK সিগনেচার পরীক্ষায় আসে না।
এরপর কী: অ্যাডভান্সডের পথ
অ্যাডভান্সড এই একই প্রজেক্টকে KnowledgeOps-এ বাড়ায়। আপনার ব্যর্থতাগুলোই প্রথম অধ্যায়গুলোর কারণ।
| অ্যাডভান্সড অধ্যায় | এই প্রজেক্ট থেকে যা নেয় |
|---|---|
| অ্যাডভান্সড RAG: হাইব্রিড রিট্রিভাল ও রিরাংকিং | রিট্রিভালের মিসগুলো: rc03-এর দরকার সুনির্দিষ্ট শব্দের সার্চ, rc06, rc08, rc13-এর দরকার অর্থ-সচেতন র্যাংকিং। |
| MCP সার্ভার, ক্লায়েন্ট ও আন্তঃকার্যক্ষমতা | টুল রেজিস্ট্রি একটা প্রোটোকল সার্ভার হয়। আপনার অ্যালাউলিস্ট ও যাচাই তখনো খাটে। |
| AI এজেন্ট: পরিকল্পনা, মেমরি ও মানুষের নিয়ন্ত্রণ | একটা টুল ধাপ হয় স্টেট, বাজেট ও মানুষের অনুমোদনসহ একটা লুপ। |
| মজবুত মূল্যায়ন ও LLM-as-a-Judge | 33টা কেস আর একটা নির্দিষ্ট রুব্রিক হয় বড়, আলাদা-রাখা সেট আর ক্যালিব্রেট-করা জাজ। |
| ফাইন-টিউনিংয়ের মূল কথা, LoRA ও PEFT | ফাইন-টিউনিং কখন কাজে লাগে, আর হারানো তথ্যের প্রথম সমাধান কেন নয়। |
| LLMOps: লগিং, ট্রেসিং, খরচ ও মনিটরিং | ইউসেজ লেজার আর রিড্যাক্ট-করা লগ লাইন হয় ট্রেস, মেট্রিক ও অ্যালার্ট। |
| AI নিরাপত্তা: ইনজেকশন, ডেটা ফাঁস ও গার্ডরেইল | অ্যাবিউজ সেট বাড়ে; ডেটা ফাঁস ও টুলের অপব্যবহারে আরও গভীর নিয়ন্ত্রণ আসে। |
| ডিপ্লয়মেন্ট, স্ট্রিমিং API ও স্কেলিং | ইন-প্রসেস টেস্ট ক্লায়েন্ট হয় আসল সার্ভিস; x-user-id-এর জায়গায় আসল অথেনটিকেশন লাগে। |
| অ্যাডভান্সড কনটেক্সট ও রিট্রিভাল অপারেশন | নিয়ন্ত্রিত ইনজেশন, হালনাগাদ থাকা, অনুমতি-সচেতন রিট্রিভাল। |
| প্রোডাকশন ক্যাপস্টোন ইন্টিগ্রেশন ও রিলিজ | সবকিছু একসঙ্গে, রিলিজের জন্য প্রস্তুত হওয়ার প্রমাণসহ। |
বিগিনার টিউটোরিয়াল ইচ্ছা করে যা বাদ দিয়েছে। আসল প্রোভাইডার কল (অ্যাডাপ্টার স্কেচ মাত্র), আসল এমবেডিং মডেল, হাইব্রিড সার্চ ও রিরাংকিং, MCP, এজেন্ট, ফাইন-টিউনিং, ট্রেসিং, আসল সার্ভার, আসল অথেনটিকেশন, এবং ক্লাউড-নির্দিষ্ট সবকিছু। মডেল প্রশিক্ষণ ও বড় অবকাঠামো এই পথের নয়, Level 1-এর অন্য পথের।
এই কিটের সৎ সীমাবদ্ধতা। নিজের পোর্টফোলিওতেও এগুলো বলুন:
- মডেল একটা ফেক, তার উত্তর রেকর্ড-করা বা নিয়মভিত্তিক। আসল মডেলের মান এখানে কিছুই মাপে না।
- এমবেডারটা একটা খেলনা, যা অক্ষর মেলায়, অর্থ নয়। এটাই মিসগুলো ব্যাখ্যা করে, আর একটা টেস্ট নথিভুক্ত প্রত্যাশিত ব্যর্থতা।
- কর্পাস সিনথেটিক ও ছোট (১৩টা ডকুমেন্ট, ৩৬টা চাঙ্ক)। বাংলা ডকুমেন্ট, প্রশ্ন এবং এই বাংলা টিউটোরিয়াল এআই দিয়ে লেখা, কোনো বাংলাভাষী সম্পাদক রিভিউ করেননি; বাংলার ফলকে প্রমাণ নয়, স্মোক টেস্ট ধরুন।
- মূল্যায়ন সেট ছোট এবং আলাদা-রাখা কোনো অংশ নেই। একটা সার্ভিস গ্যাপ (
rc15) দেখিয়েছে যে যে পাইপলাইন মাপা হয়েছে সেটা শিপ-করা পাইপলাইন নয়। - এক অপারেটিং সিস্টেমে ইন-প্রসেস চালানো হয়েছে। সার্ভার, কনকারেন্সি, লোড বা আসল অথেনটিকেশন নেই।
নিরাপত্তা নোট (২০২৬-১০-১২ অনুযায়ী): UK NCSC 2025-12-08-এ লিখেছে প্রম্পট ইনজেকশন হয়তো কখনোই পুরোপুরি ঠেকানো যাবে না, তাই নকশা দিয়ে সীমিত করতে হবে সফল ইনজেকশন কী করতে পারে। OWASP LLM অ্যাপ্লিকেশনের ঝুঁকি সংস্করণ ধরে প্রকাশ করে (2025 সংস্করণ নিশ্চিত; 2026 সংস্করণ শুধু একটা গৌণ সূত্রে দেখা গেছে): ঝুঁকির উল্লেখ করুন নাম ও সংস্করণ দিয়ে, নম্বর দিয়ে নয়। অ্যাডভান্সডের জন্য: MCP Python SDK-র একটা 2.x রিলিজ আছে অথচ 1.x এখনো রিলিজ হয়, এবং 2026 সালের জুলাইয়ের বেশ কিছু উচ্চ-তীব্রতার অ্যাডভাইজরি 1.x-এ ঠিক হয়েছে; 2.x-এ ফিক্সগুলো আছে কি না নিশ্চিত নয়, তাই ভার্সন পিন করুন ও অ্যাডভাইজরি পড়ুন। বর্তমান ডকুমেন্টেশন দেখে নিন।
কাজের জায়গায় এটা কোথায় দেখা যায়
আক্রার কোয়ামে অন্য একটা টিমের বানানো প্রোটোটাইপের দায়িত্ব নিলেন। কোড পড়ার আগেই তিনি গ্রহণযোগ্যতার স্ক্রিপ্ট, রিলিজ চেক আর গেট চালান, তারপর সীমাবদ্ধতার ফাইল পড়েন। বিশ মিনিটে তিনি জানেন কী কাজ করে, কী দাবি করা হয়েছে কিন্তু পরীক্ষা হয়নি, আর আগে কী ঠিক করতে হবে। টিমগুলো একে বলে "definition of done" বা রিলিজ প্রস্তুতির রিভিউ; আপনারটা একটা স্ক্রিপ্ট, আর সেটা অডিট ও আপনার পোর্টফোলিওর কাজেও লাগে।
সাধারণ ভুল
- ACCEPTED-কে "ভালো" পড়া। চেকলিস্ট প্রমাণ করে নিয়ন্ত্রণ আছে আর জানা কেস ঠিক চলে। আসল ব্যবহারকারী বা আসল মডেলে মান প্রমাণ করে না। রিপোর্টে সেটা বলুন।
- জানা গ্যাপ লুকানো। কারণসহ তালিকাভুক্ত করা সবুজ চেকের চেয়ে শক্ত। তালিকাটা টেস্টযোগ্য রাখুন, যাতে ঠিক-হওয়া বা নতুন গ্যাপে চেক ব্যর্থ হয়।
- এক পাইপলাইন মাপা, আরেকটা শিপ করা। চেক চালান সেই পথে যেখানে ব্যবহারকারী পৌঁছায়। মূল্যায়ন আর সার্ভিস একই কোডে রাখুন।
- ব্যর্থ কেস দেখে টিউন করা। একটা প্রশ্ন ঠিক করে বলে বাছা থ্রেশহোল্ড সেই প্রশ্নেই খাপ খাইয়ে নেওয়া। আগে কেস বাড়ান, তারপর বাছুন।
- মোট সংখ্যায় ভরসা। হাতে লেখা টেস্ট সংখ্যা বা স্কোর পুরনো হয়। ব্যর্থতা আর তৈরি-করা সংখ্যা পড়ুন, আর ম্যানুয়াল রিলিজ চেকলিস্টও (git ইতিহাস, লাইসেন্স) রাখুন।
নিজে চেষ্টা করুন
- সহজ। ডকুমেন্টেশন, রিলিজ ও পোর্টফোলিওর মান আবার দেখুন। প্রজেক্টের একটা কপিতে সিক্রেটের আকারের হার্ড-কোড করা একটা লাইনসহ ফাইল যোগ করুন। অনুমান করুন গ্রহণযোগ্যতার স্ক্রিপ্টের কোন সারিগুলো ব্যর্থ হবে আর শেষ লাইনে কী লেখা থাকবে, তারপর চালান।
- মাঝারি। বাজেট, ক্যাশিং ও ব্যবহারের সীমা আবার দেখুন।
create_app-কে এমন একটা লোডার দিন যার রিট্রিভারের ন্যূনতম স্কোর 0.36।data/rag_cases.jsonl-এর ১৬টা কেসে 0.3 আর 0.36 তুলনা করুন: উত্তরযোগ্য কয়টা প্রশ্নের উত্তর আসে, আর উত্তরহীন কোনটার উত্তর আসে? ডিফল্ট কেন এখনই বদলাবেন না? - কঠিন। নিরাপদ ব্যর্থতা ও নিরাপত্তা রিগ্রেশন টেস্ট আবার দেখুন।
rc15-এর জন্য দুটো টেস্টসহtests/test_gap.pyলিখুন: একটা strictxfail, যা প্রত্যাশা করে ডিফল্ট সার্ভিস সেটা প্রত্যাখ্যান করবে, আর একটা, যা কড়া লোডারে পাস করে। কেউ ডিফল্ট ঠিক করলে প্রথম টেস্টের কী হয়?
উত্তর
সহজ। ফাইলটা শুধু রিলিজ চেক দেখে, তাই একটা সারি ব্যর্থ হয় (M5) এবং ফল NOT ACCEPTED; জানা গ্যাপ তবু জানানো হয়।
rm -rf ../scratch && cp -r . ../scratch && cd ../scratch
echo 'password = "abcdefghijklmnop1234"' > notes.txt
python -m capstone.accept | grep -E "FAIL|RESULT"[FAIL] M5 evaluation, packaging and report 10 release checks, failing: ['secrets and sensitive fixtures']
RESULT: NOT ACCEPTED (1 failed, 1 known gap)মাঝারি। দুই মানেই উত্তরযোগ্য ১৩টার ১১টার উত্তর আসে (একই দুটো মিস, rc03 ও rc06); বদলায় শুধু rc15, আর 0.36-এ সেটা প্রত্যাখ্যাত হয়। মনে হয় বিনামূল্যে, কিন্তু মানটা এসেছে একটা কেস দেখে। তৈরি-করা docs/NEXT-STEP.md একই কথা বলে: আরও উত্তরহীন প্রশ্ন (বাংলাতেও) যোগ করুন, সুইপ আবার চালান, তারপর বাছুন। আরও ভালো হয় সার্ভিসকে সেই পাইপলাইন ব্যবহার করালে যেটা মূল্যায়ন মাপে।
from pathlib import Path
from fastapi.testclient import TestClient
from evidencedesk.api import create_app
from evidencedesk.chunking import chunk_corpus
from evidencedesk.citations import load_rag_cases
from evidencedesk.rag import Retriever
cases = load_rag_cases(Path("data/rag_cases.jsonl"))
def loader(min_score):
return lambda settings: Retriever(chunk_corpus(settings.corpus_dir), clock=lambda: "2026-10-13T09:00:00Z", min_score=min_score)
for min_score in (0.3, 0.36):
with TestClient(create_app(loader=loader(min_score))) as http:
status = {c.id: http.post("/ask", json={"question": c.question}, headers={"x-user-id": "mateo"}).json()["status"] for c in cases}
print(min_score, "answered:", sum(status[c.id] == "answered" for c in cases if c.answerable), "of", sum(c.answerable for c in cases),
"| unanswerable but answered:", [c.id for c in cases if not c.answerable and status[c.id] != "refused"])0.3 answered: 11 of 13 | unanswerable but answered: ['rc15']
0.36 answered: 11 of 13 | unanswerable but answered: []কঠিন। strict প্রত্যাশিত ব্যর্থতা হলো নথিভুক্ত একটা গ্যাপ, যাকে স্যুট সৎ রাখে।
# file: tests/test_gap.py
import pytest
from fastapi.testclient import TestClient
from evidencedesk.api import create_app
from evidencedesk.chunking import chunk_corpus
from evidencedesk.rag import Retriever
Q = "Do you sell electric scooters?"
def status(loader=None):
kw = {"loader": loader} if loader else {}
with TestClient(create_app(**kw)) as http:
return http.post("/ask", json={"question": Q}, headers={"x-user-id": "mateo"}).json()["status"]
@pytest.mark.xfail(strict=True, reason="known gap: the service answers it (accept.GAPS lists it)")
def test_default_service_refuses_it():
assert status() == "refused"
def test_a_stricter_threshold_refuses_it():
strict = lambda s: Retriever(chunk_corpus(s.corpus_dir), clock=lambda: "2026-10-13T09:00:00Z", min_score=0.36)
assert status(strict) == "refused"python -m pytest tests/test_gap.py | tail -1 | sed 's/ in [0-9.]*s//'1 passed, 1 xfailedকেউ ডিফল্ট সার্ভিস ঠিক করলে প্রথম টেস্ট অপ্রত্যাশিতভাবে পাস করে, আর strict মোড সেটাকে ব্যর্থতা বানায়। তখন মানুষটাকে মার্কার আর GAPS-এর এন্ট্রি একসঙ্গে মুছতে হয়, ফলে তালিকা আর টেস্ট কখনো আলাদা কথা বলতে পারে না।
পাস চেকলিস্ট:
- সহজ: আপনি শুধু M5, NOT ACCEPTED, 1 failed অনুমান করেছেন, আর বলতে পারেন A1 কেন ব্যর্থ হয় না।
- মাঝারি: উত্তরযোগ্য প্রশ্নে উত্তরের সংখ্যা একই, 0.36-এ
rc15-এর আর উত্তর আসে না, আর কারণে আছে একটা কেস দেখে থ্রেশহোল্ড বাছার ঝুঁকির কথা। - কঠিন: আউটপুট শেষ হয় একটা পাস আর একটা প্রত্যাশিত ব্যর্থতায়, আর আপনি strict মোড ব্যাখ্যা করতে পারেন।
- পুরো ক্যাপস্টোন: ০টা ক্রেডেনশিয়াল লাগে,
capstone.acceptগ্যাপসহ ACCEPTED, রিলিজ চেক স্যুটসহ READY, ডকুমেন্ট হালনাগাদ, আর সীমাবদ্ধতার ফাইল আপনি যা সত্যিই চালিয়েছেন তার সঙ্গে মেলে।
সারসংক্ষেপ
- ক্যাপস্টোন হলো আপনার আগে বানানো প্রজেক্টই, যা প্রমাণ হয় পাঁচটা মাইলস্টোন চেক আর স্ক্রিপ্ট হিসেবে চলা ছয় আইটেমের গ্রহণযোগ্যতার চেকলিস্ট দিয়ে।
- প্রমাণ দিয়ে গ্রেড করুন: প্রতিটা রুব্রিক বিভাগ একটা টেস্ট, তৈরি-করা ডকুমেন্ট বা রিলিজ চেকের দিকে নির্দেশ করে, এবং বলে সেটা কী দেখাতে পারে না।
- একটা চিট শিটে আছে কমান্ড, দুই বিশ্বাস-সীমানাসহ রিকোয়েস্টের পথ, আর আপনার ঘটিয়ে-দেখা ব্যর্থতা থেকে তৈরি ট্রাবলশুটিং টেবিল।
- সৎ সীমাবদ্ধতা ডেলিভারেবলের অংশ: ফেক মডেল, খেলনা এমবেডার, ছোট সিনথেটিক কর্পাস, এআই-লেখা বাংলা, শুধু ইন-প্রসেস রান, আর তালিকাভুক্ত একটা সার্ভিস গ্যাপ।
- অ্যাডভান্সড শুরু হয় আপনার ব্যর্থতা থেকে: ভালো রিট্রিভাল, প্রোটোকল, এজেন্ট, গভীর মূল্যায়ন, অপারেশন, নিরাপত্তা ও ডিপ্লয়মেন্ট, একই কোড বেসে।
এরপর: LLM দিয়ে AI ইঞ্জিনিয়ারিং: অ্যাডভান্সড এই প্রজেক্টকে নিয়ে যায় প্রোডাকশন-মুখী রিট্রিভাল, MCP, এজেন্ট, মূল্যায়ন, ফাইন-টিউনিং, LLMOps, নিরাপত্তা ও ডিপ্লয়মেন্টে। বিগিনার আপনি শেষ করলেন: রিপোজিটরি, রিপোর্ট আর সীমাবদ্ধতার তালিকা রেখে দিন, কারণ অ্যাডভান্সড সেখান থেকেই শুরু হয়।