[{"data":1,"prerenderedAt":229},["ShallowReactive",2],{"apod-preview":3,"content":7},{"url":4,"date":5,"title":6},"https:\u002F\u002Fapod.nasa.gov\u002Fapod\u002Fimage\u002F2607\u002Fcorona_australis_1024.jpg","2026-07-22","The Corona Australis Molecular Cloud and the Chandelier Cluster",{"siteName":8,"seo":9,"header":22,"nav":25,"footer":38,"hero":51,"ask":55,"answer":70,"suggest":89,"a11y":94,"states":99,"howItWorks":107,"about":129,"faq":184,"sibling":222,"taurus":225},"APOD Ask",{"index":10,"howItWorks":13,"about":16,"faq":19},{"title":11,"description":12},"APOD Ask: grounded answers from NASA's APOD archive","Ask an astronomy question and get an answer grounded in real NASA Astronomy Picture of the Day texts, with the sources.",{"title":14,"description":15},"How it works: embed, retrieve, generate | APOD Ask","How APOD Ask turns a question into a grounded answer: embed, retrieve, rank, generate. Retrieval you can actually see.",{"title":17,"description":18},"About: a hands-on RAG learning project | APOD Ask","A hands-on RAG project over NASA APOD: Gemini embeddings, an Upstash vector store, and answers grounded in real APOD texts.",{"title":20,"description":21},"FAQ: what you can ask and how RAG works | APOD Ask","What you can ask, what RAG is, why you sometimes only get closest matches, and how Smart search and Star Trek mode work.",{"brand":8,"github":23,"githubUrl":24},"GitHub ↗","https:\u002F\u002Fgithub.com\u002FMilenoi\u002Fnuxt-nasa-rag",[26,29,32,35],{"label":27,"link":28},"Ask","\u002F",{"label":30,"link":31},"How it works","\u002Fhow-it-works",{"label":33,"link":34},"FAQ","\u002Ffaq",{"label":36,"link":37},"About","\u002Fabout",{"stages":39,"idleLabel":44,"meta":45,"status":46},[40,41,42,43],"Query","Retrieve","Rank","Answer","idle","embeddings · retrieval · NASA APOD",{"idle":44,"loading":47,"answer":48,"empty":49,"error":50},"Searching…","Answer ready","No matches","Signal lost",{"eyebrow":52,"title":53,"subtitle":54},"Natural-language APOD search.","Ask the Stars","Ask anything about astronomy. Answers from real NASA APOD texts, with their images and videos.",{"placeholder":56,"inputLabel":57,"submit":27,"examplesToggle":58,"emptyHint":59,"examples":60,"loading":64,"personalityLabel":65,"personalityLabelShort":66,"personalityHint":67,"rewriteLabel":68,"rewriteHint":69},"e.g. How do stars form?","Your astronomy question","Need inspiration?","Come on, space may be empty, but you still have to ask something.",[61,62,63],"What is a planetary nebula?","A colorful nebula shaped like an animal","How does a supernova happen?","Searching the cosmos…","Star Trek answer mode","Star Trek","On: answers get a playful Star Trek bridge-officer voice. Off: cool and factual, straight from the sources.","Smart search","On: suggests cleaned-up versions of your question (typos fixed, wording tightened) to pick from before searching, so a misspelled or vague query still finds matches. Off: your text is searched exactly as typed.",{"heading":43,"aboutHeading":71,"aboutNote":72,"backToQuestion":73,"noMatchHeading":74,"closestHeading":75,"closestHeadingShort":76,"noAnswerNote":77,"sourcesHeading":78,"newSearch":79,"sourcesCount":80,"topMatch":81,"match":82,"askedLabel":83,"sourceLabel":84,"viewOriginal":85,"prevSource":86,"nextSource":87,"showInHero":88},"About this picture","NASA's original APOD description for this picture, not the AI answer.","Back to your question:","No match","Closest matches","Closest","No direct answer in the APOD texts, but these came closest to what you asked.","Sources","New search","APOD pictures","Top match","Match","You asked","Source","View original","Previous source","Next source","Show {title} in the hero",{"askedLabel":83,"heading":90,"intro":91,"keepOriginal":92,"loading":93},"Did you mean?","Smart search tidied up your question. Pick a version, or search exactly what you typed.","No, search what I typed","Tidying up your wording…",{"answerReady":95,"noResults":96,"requestError":97,"suggestionsReady":98},"Answer ready.","No matching results found.","The request failed.","Suggestions ready. Pick one, or keep your original.",{"emptyHeading":100,"nonsense":101,"nonsensePlain":102,"error":103,"errorHeading":104,"retry":105,"retryOther":106},"Nothing crossed the event horizon.","Come on, don't waste Melanie's tokens on that one. Ask me something actually about space.","That does not look like an astronomy question. Try asking about something in the night sky.","Something went wrong reaching the stars. Please try again.","The signal fell into a black hole.","Try again","Ask something else",{"tagline":30,"heading":108,"lead":109,"steps":110,"footnote":126,"showCode":127,"hideCode":128},"Retrieval-Augmented Generation, in plain sight","Every answer is built in four small steps, from your question to a grounded reply. You can follow exactly how retrieval-augmented generation turns a question into an answer drawn only from real NASA texts.",[111,115,118,122],{"role":40,"color":112,"name":113,"desc":114},"cyan","Embed the question","Your question is turned into a list of 768 numbers (a vector) by Google's multilingual Gemini embedding model. The same model already turned every APOD description into a vector, so a German question can still find an English text. Meaning becomes math the computer can compare. (With Smart search on, you first pick from cleaned-up versions of your question, typos fixed, before this step.)",{"role":41,"color":112,"name":116,"desc":117},"Find the closest texts","That question-vector goes to the Upstash Vector database, which compares it against every stored APOD vector by cosine similarity and hands back the closest ones. The closer two vectors point, the closer their meaning.",{"role":42,"color":119,"name":120,"desc":121},"purple","Keep the best matches","Upstash already hands the matches back sorted by similarity, so this step just takes the top five and applies one cheap guard: if even the closest match scores far too low, skip the model and treat that input as invalid. Scores alone can't tell gibberish from a real question (random text often scores high), so the real judgement is the model's, in the next step. How do we know the cutoff and the top-five are any good? An offline eval (`npm run eval`) asks a set of questions whose right answer we already know and grades how often, and how near the top, the right picture is found (the standard search metrics Recall@K and MRR), so those knobs are set from numbers, not guesses.",{"role":43,"color":123,"name":124,"desc":125},"green","Generate a grounded answer","The question and the top texts go to Google Gemini. It used to answer in free text with NONSENSE \u002F NO_MATCH markers parsed by hand, brittle and unable to prove which pictures were used; now it fills a fixed JSON form, checked by a schema, so the reply can't drift and invented citations are dropped. An optional Star Trek toggle changes only the tone, never the facts.","Built with Nuxt 4 and Google Gemini, a sibling to the","Show code","Hide code",{"tagline":130,"heading":131,"lead1":132,"lead2":133,"lead3":134,"journey":135,"techStackLabel":154,"techStack":155,"freeTierNote":177,"cta":178,"creditText":179,"builtBy":180,"creditSep":181,"viridisUrl":182,"viridisLabel":183},"A learning project","Learning RAG by building it by hand","I'm a frontend developer, curious about how AI actually works under the hood. Instead of reaching for a framework that hides everything, I wanted to build Retrieval-Augmented Generation from the ground up, so I could actually explain what embedding, retrieval and grounded generation each do, in my own words.","So every moving part here is deliberately visible: the embedding step calls a hosted model, the similarity search ranks stored vectors by cosine distance (I first wrote this by hand, then moved it to a hosted vector database), and the language model is told to answer only from the retrieved NASA texts. To check the search rather than trust it blindly, I also built a small eval by hand using the standard search metrics (Recall@K and MRR): it asks questions whose right answer I already know and grades how often, and how near the top, the right picture comes back.","It was also my chance to practise Clean Architecture in a Nuxt app: the query and ingest flows are both split into a domain, use cases with ports, and infrastructure adapters, so the core logic never depends on Gemini, Upstash or NASA directly. Arguably over-engineered for a demo this size, but that was exactly the point, to learn the pattern by building it by hand.",{"label":136,"steps":137},"How it got here",[138,142,146,150],{"dropped":139,"reason":140,"now":141},"Local Transformers.js embeddings (Xenova\u002Fparaphrase-multilingual-MiniLM-L12-v2), in the function.","Too heavy for Netlify's 250 MB function limit.","Google Gemini embeddings: hosted, tiny to ship.",{"dropped":143,"reason":144,"now":145},"Hand-written cosine over one plain JSON file.","Lovely to learn on, but it will not scale.","A hosted vector database (Upstash Vector), live now.",{"dropped":147,"reason":148,"now":149},"A free-text answer with NONSENSE \u002F NO_MATCH markers, parsed by pattern-matching.","Brittle to read, and it never verified which pictures were actually cited.","A schema-constrained JSON reply, validated with Zod, with its cited sources checked.",{"dropped":151,"reason":152,"now":153},"Guessing the retrieval thresholds (how similar counts, how many to fetch) by eye.","No way to tell whether a tweak actually helped or hurt.","A small offline eval that grades retrieval (Recall@K + MRR) so the knobs are set from numbers.","Stack",[156,159,162,165,168,171,174],{"label":157,"value":158},"Framework","Nuxt 4 + Vue, Nitro server routes",{"label":160,"value":161},"Embeddings","Google Gemini: gemini-embedding-001 (multilingual, 768-dim)",{"label":163,"value":164},"Vector store","Upstash Vector (was hand-written cosine over JSON first)",{"label":166,"value":167},"Language model","Google Gemini: gemini-flash-latest (free tier), structured JSON output validated with Zod",{"label":169,"value":170},"Data","NASA Astronomy Picture of the Day API",{"label":172,"value":173},"Ingest","Manual backfill script + a daily Netlify function",{"label":175,"value":176},"Hosting","Netlify","This is deliberately a free-tier demo, so it can hit the daily quota. A hobby project, built to learn and to show, not to run up costs.","View the source on GitHub ↗","A sibling to the","Built by Melanie Stief, forever half-hoping for a NASA badge, or at least a window seat past the atmosphere. Until the universe sends the invite, building small things about the cosmos will have to do.","·","https:\u002F\u002Fviridis.de","viridis.de",{"tagline":185,"heading":186,"lead":187,"items":188},"Questions & answers","What this is, and how to use it","A few things worth knowing before you ask: what the site does, why it sometimes says no, and what the two toggles change.",[189,192,195,198,204,207,210,213,216,219],{"q":190,"a":191},"What can I ask here?","Anything about astronomy. The answer is built only from real NASA Astronomy Picture of the Day (APOD) descriptions, and the pictures behind it are always shown as sources. It covers roughly the last three years of APOD entries.",{"q":193,"a":194},"What is RAG (Retrieval-Augmented Generation)?","Instead of letting the language model answer from memory, the site first retrieves the most relevant real APOD texts and then asks the model to answer only from those. The retrieval grounds the generation, so answers stay tied to real sources instead of being made up.",{"q":196,"a":197},"Why does it only use NASA APOD texts?","Grounding every answer in a fixed, trusted set of texts is the whole point of the demo. It keeps answers honest and lets you check each claim against the source picture, rather than trusting a model's general knowledge.",{"q":199,"a":200,"link":201},"Why NASA?","Honestly, because NASA's open APIs are a genuine pleasure to work with. You get a free API key in seconds, with no approval process and no credit card, and the Astronomy Picture of the Day feed was a perfect fit for a small demo: real, well-written explanations, each paired with a striking image. Get your own key at",{"url":202,"label":203},"https:\u002F\u002Fapi.nasa.gov\u002F","api.nasa.gov",{"q":205,"a":206},"Why do I sometimes get no direct answer, just closest matches?","If the APOD archive does not actually cover your question, the site shows the closest pictures instead of inventing an answer. That is deliberate: it would rather admit a gap than guess.",{"q":208,"a":209},"What does Smart search do?","With Smart search on, your question is first cleaned up (typos fixed, vague wording tightened) and you pick from the suggested versions before searching. It helps a misspelled or fuzzy query still find matches. Off, your text is searched exactly as typed.",{"q":211,"a":212},"What is Star Trek answer mode?","A playful toggle that gives the answer a Star Trek bridge-officer voice. It changes only the tone, never the facts or the sources.",{"q":214,"a":215},"Is my question stored?","No. Your question is sent to the server only to create the search embedding and the grounded answer. It is not saved to a database or tied to an account, and there is no login or tracking of what you ask.",{"q":217,"a":218},"Why does it sometimes fail or hit a limit?","It runs on free API tiers on purpose, so it can reach Google Gemini's daily quota. When that happens the site says so honestly instead of faking an answer. Try again later, once the quota resets.",{"q":220,"a":221},"What was the motivation behind building something like this?","Nothing ambitious. It is a small project to get a little closer to the big black box that AI and RAG can feel like, no more and no less. I just wanted to understand a bit of what actually happens between a question going in and an answer coming out. And building something like this alongside my day job was simply a lot of fun.",{"label":223,"url":224},"APOD caching demo","https:\u002F\u002Fnuxt-cache-project.netlify.app\u002F",{"label":226,"labelMoved":227,"egg":228},"Taurus","Not Taurus anymore","Aldebaran, the eye of Taurus. Melanie's birthday is in April, so she is a Taurus.",1785762118740]