Wiki › Project

ask.chaipat.cc, the ask-me-anything site

Project · app · 2026 · Key work

ask.chaipat.cc is the site you are reading: a portfolio you search instead of scroll. You can find a project, open its live site, inspect its source or learn about it, as well as ask about Chaipat, his work, his skills or this site itself. He started it in April 2026 and works on it continuously. It is the part of the chaipat.cc research network that answers questions about his work; the root address, chaipat.cc, is his library of books.

Its question view answers like a search engine does: a short answer on top, the sources under it, a knowledge panel beside it, and tabs for images, the SPARQL queries behind the answer and a timeline. A graph view draws the whole graph and its ontology as a network to walk through.

The knowledge graph supplies facts about his work, and the wiki supplies explanations. Factual answers can be checked in the SPARQL tab, where the queries used and their rows are shown.

History

The site grew out of the personal site he started in his first year at university, in 2022. It has been rebuilt many times on top of that first version, and parts of the old codebase are still in it. The present version, an ask-me-anything page over a knowledge graph, began in April 2026; the wiki, the timeline, the graph view and the time questions came after.

In November 2026 the site changed its address. It had been served at chaipat.cc since it began; it moved to ask.chaipat.cc, and chaipat.cc became a library of books about his life. Every older address redirects to the same page here, and the namespaces of the knowledge graph moved with the site, to https://ask.chaipat.cc/ns# for the vocabulary and https://ask.chaipat.cc/id/ for the entities. One of those books, Nenrin (年輪), a picture scroll, tells the whole history of the site as a picture scroll.

In the same month the question engine was rebuilt in layers. It now says how sure it is of an answer, says so when the graph has nothing on a technology and shows what he does use instead, and suggests what to ask next. Its design is written up as a short paper, with pseudocode, flowcharts and references, in the question engine's article, and it is measured against two sets of questions by the search evaluation.

He uses AI coding assistants as tools in that work. He decides what the site does and how it looks, and every change goes through the same tests in a real browser before it is published. The graph-backed factual answers are read with SPARQL; explanations can also quote the wiki.

How a question is answered

Before any question is asked, the graph is loaded and the reasoner adds what the ontology implies (see Reasoning), so every step below works on the stated facts and the inferred ones together. A typed question then goes through one pipeline, the question engine:

  1. Understand. Entity linking finds the things the question names (projects, skills, roles, games, techniques) by their names, short names and aliases. The question is then sorted into a kind: a list, a how or why question, a definition, a question about a period of time, a question about him, or a question about this site. If the question as typed finds little, the page tries a spelling correction, using Damerau–Levenshtein edit distance against the site's own vocabulary. A correction that finds more is applied with Showing results for …; otherwise it is only suggested.
  2. Retrieve. Candidates come from two places at once: the graph neighbours of what was named, and passages of the wiki ranked with BM25 by the wiki full-text search. Some neighbours exist only through reasoning: "where has he used BM25?" follows one inferred relation, deals with, instead of six specific ones.
  3. Fuse. The candidate lists are merged with reciprocal rank fusion, weighted by the kind of question, and key work is nudged ahead of side projects.
  4. Answer. Facts and lists come from SPARQL over the graph, inferred facts included, and the SPARQL tab says how many rows came from reasoning. How and why come from the wiki section that covers it. "What is X" comes from Wikipedia next to what he did with X. A question about a technology the graph does not have is answered by saying so: the graph lists no such work, followed by what he does use in the same category.
  5. Judge. Every plan carries a confidence, decided by the route the answer took: exact for an authored or graph answer, strong when the question names something the site knows, weak when only word overlap found it, none when nothing matched. It is what would decide whether a model may be asked, and no model is.
  6. Suggest. After an answer, a few follow-up questions come from one hop around what it was about, each kept only if the engine can answer it confidently.

Questions about time are answered from the time data: "this year", "two months ago", "since last year", "in March 2025" or "21 Oct 2024 – 1 May 2025" become a range of dates, and a work counts when it had commits on a day inside it, read from the months of work kept for every repository.

Finding entities and choosing resources

Not every request is a question. Someone who types a project's name usually wants to go somewhere: its live site, its source code or its page here. The site keeps a catalog of every entity in the graph, with its names, short names and aliases, its type, its description and the places it can send you. Product names such as Wordplay, Graph Laboratory and Project SKY // Lab are aliases in the graph, so they are found the same way as everything else.

Each entity offers up to three resources:

About
its page in this wiki. Every entity has one, even without a written article.
Live
the running site, only where the graph states a live address for it.
Source
its repository.

Any other link, such as a publication or a store listing, stays a related link and is never treated as a live app.

Which resource is offered first follows what was asked: going somewhere prefers live, asking for code prefers source, and learning about something prefers about. When the preferred one is missing, the about page is offered instead. All of this is decided locally, by fixed rules, from the graph. No language model is involved: a model fallback exists in the code but is switched off (see the question engine), and it could never choose or rewrite a destination.

One answer and its evidence

A focused question gets one answer, composed from graph facts, a passage of the article it is about, or a Wikipedia extract. The sources listed under an answer are only what was actually read to write it. Related things, including the technologies shown in the knowledge panel, are not counted as sources.

The buttons that open a site, its source or its page are kept apart from the prose, so the answer does not repeat them. A count or a list does not turn its first result into the destination for the whole answer: each result keeps its own link.

The code, the graph, the ontology and the wiki have to stay in step for any of this to hold, so the build records a fingerprint of each and a deploy is refused when one is stale. The page builder describes how.

When it does not know

A search box that always answers is a search box that sometimes makes things up. This one is built to say less. Every answer carries a confidence, decided by the route it took and not by a score: an authored answer or a graph answer is exact, an answer about something the question names is strong, an answer found only because some words overlap is weak, and no answer is none. A weak answer is a guess, and the engine knows it is one.

The commonest honest answer is about absence. Ask about a technology the graph has no work with and the answer says that the graph lists no such work, then shows what he does use in the same category and his key work in it; the SPARQL tab shows the query that found nothing, so the absence can be checked too. It never claims he lacks a skill, only that the graph lists no work.

It does not always manage. A question unrelated to him that happens to share words with an article can still be answered from that article, and the paper counts how often. A fix exists in the code: a model fallback that would ask a language model about weak answers, give it only the evidence the engine retrieved and discard its answer unless the answer survives checking. It is switched off, because it has never been evaluated against a live model, and while it is off no question leaves the server.

The knowledge graph

The graph is written in RDF Turtle and described by a small OWL ontology of its own (the cj: vocabulary): the same kind of knowledge graphs he builds in his research, pointed at his own work. It lives in four files:

FileWhat it holds
me.ttlWritten by hand: roles, studies, key projects, and the parts of this site
github.ttlGenerated from his GitHub repositories: dates of first and last commit, commit counts, languages, themes and how prominent each work is
wiki.ttlDrawn from the wiki: the techniques, datasets, services, formats and games each article mentions
time.ttlGenerated from the commit histories: the years of his work, and every work's months of work with their commits and days

The Turtle parser reads them and the SPARQL engine queries them, both in the browser and in the build scripts, so a page, its answer and the CV can never disagree. Before every deploy the graph is validated against the ontology, and the fact check confirms that every fact taken from an article is supported by that article.

Reasoning

The ontology is not only a rulebook. When the graph loads, the reasoner applies it, a small form of RDFS and OWL reasoning that repeats until nothing new follows:

Subclasses
every project is a work.
Subproperties
implementing a technique or reading a file format both mean the work deals with that concept.
Symmetric properties
related works go both ways.
Inverse properties
a component of this site means this site has that component.

The answers therefore come from the knowledge graph and what the ontology says it implies. In the SPARQL tab, a query says how many of its rows exist only through reasoning, and the wiki's infoboxes mark inferred facts.

The ontology has grown with the site:

  • Version 1.3 added components: a large work can be described part by part, each part with its own source file and the techniques it implements. This site is the first work described that way.
  • Versions 1.5 and 1.6 added time, aligned with OWL-Time: years, and months of work with their commits and active days, so the graph knows not only that a work exists but when it was worked on.
  • Version 1.12 added property chains: the skills a role or a year drew on are inferred from the work done in it, never written down by hand, so "what did he do at NARIT" and "what did he do in 2025" name the skills behind the work.
  • Version 1.13 separated a work's live address and its source from its other links.
  • Version 1.14, the current one, records a digest of each component's source files, so a page about a part of the site can tell when its code has changed.

The parts of the site

PartSourceWhat it does
Question enginesrc/engine.jsEntity linking, intents, rank fusion, confidence, absent technologies, spelling, follow-up questions
SPARQL enginesrc/kg.jsSPARQL over the graph, in the browser
Turtle parsersrc/turtle.jsTurtle files to triples
Reasonersrc/reason.jsFacts the ontology implies
Wiki full-text searchsrc/search.jsBM25 over wiki passages
Timeline viewsrc/timeline.jsRoles and work over time
Graph viewsrc/graph.jsThe graph and the ontology as a network
Time datascripts/build-time-ttl.mjsYears and months of work, for questions about when
Page builderscripts/build-pages.mjsPrerendered pages, JSON-LD and the sitemap
Fact checkscripts/factcheck.mjsWiki facts against their articles
CV builderscripts/build-cv.mjsThe CV page and its PDF
Question logapi/log.jsQuestions and votes, for finding bad answers
Search evaluationscripts/eval-search.mjsRegression and held-out question sets, and a record of what visitors asked that went badly
Model fallbackapi/ask.jsA checked fallback to a hosted language model; switched off
Contact formapi/mail.jsMessages sent from the Mail page
Easter eggssrc/eggs.jsA few queries that do something else
Logo and doodlessrc/brand.jsThe cj mark, and its costumes on special days
Offline supportsw.jsKeeps the site answering without a connection
Accessibility audittests/audit.mjsNames, contrast, tap targets and speed, checked weekly

The wiki, the timeline and the graph

Every entity in the graph has a page in this wiki. Some have a written article like this one; the rest are generated from the graph, with an infobox, the works linked to them and, for general things, a summary from Wikipedia. The page builder also prerenders every page as plain HTML with JSON-LD structured data and lists them in an XML sitemap, so search engines can read the wiki without running any JavaScript.

The timeline draws every role and every piece of work on one axis, each work as a line from its first commit to its last. Clicking a year, a role or a theme narrows it down and asks the matching question.

The graph view shows the same graph as a network. It opens on an overview of his key work, the themes and the skills they share, and opening anything brings its neighbours in; the places come from a force-directed layout settled once at deploy time. A second view draws the ontology itself: its classes, how they nest and the properties between them.

Stack

There is no framework: the page is plain JavaScript, HTML and CSS, hosted on Vercel. A few small Node.js functions sit behind it. The question log keeps typed questions in Postgres on Neon, Redis enforces rate limits and keeps a short cache of the popular questions, and the contact form forwards messages through Resend. On every push, GitHub Actions validate the graph, check the pages in a real browser with Playwright, and print the CV to PDF. Every day they refresh the site's own dates and months of work, and every week the accessibility audit runs.

A service worker caches the site's code, the graph and the search index for offline lookup; external sites, the question log, votes and mail still require a connection.

Privacy

Typed questions are logged as text, with the kind of question and whether it was answered, to find questions the site gets wrong. No IP address is stored with them, and there are no cookies, ads or trackers. Recent searches stay in your own browser. No question is sent to a language model: the model fallback is switched off, and while it is off a question goes nowhere except into the log entry above. (A message sent from the contact form is a different thing: it is forwarded to his inbox.)

KiWiS is the readable knowledge layer of the same research network, and the knowledge-graph explorer is its workspace for large graphs. The library at chaipat.cc is the front door of the network and tells his life as books. This site is the place for finding those entities, choosing their resources and asking about the work behind them.

The logo is the letters cj, for the cj: vocabulary the whole graph is written in, drawn as a tiny graph: the dot of the j is a node, linked to the c. On some days it dresses up. There are a few easter eggs too; try "askew" or "donut".

In the knowledge graph

ask.chaipat.cc and the 54 things it is linked to. Open any dot for its page, or explore it in the full graph.

21 more works: open them in the graph view21SPARQL · skill · Built withKnowledge graphs · skill · Built withOWL · skill · Built withVercel · skill · Built withRedis · skill · Built withPlaywright · skill · Built withRDFS and OWL reasoning · technique · ImplementsForce-directed layout · technique · ImplementsEntity linking · technique · ImplementsDamerau–Levenshtein distance · technique · ImplementsOkapi BM25 · technique · ImplementsReciprocal rank fusion · technique · ImplementsEdit distance · technique · ImplementsOWL-Time · technique · ImplementsService worker · technique · ImplementsOntology and knowledge graphs · theme · ThemesNeon serverless Postgres · service or platform · Works withResend email API · service or platform · Works withRDF Turtle · dataset or file format · File formatsJSON-LD · dataset or file format · File formatsXML sitemap · dataset or file format · File formatsKnowledge-graph explorer · work · RelatedGraph explorerKIWIS · work · RelatedKIWISchaipat.cc, the library of books · work · Relatedchaipat.ccNenrin (年輪), a picture scroll · work · links hereNenrinJavaScript · skill · Built withJavaScriptGitHub Actions · skill · Built withGitHub ActionsNode.js · skill · Built withNode.jsPostgreSQL · skill · Built withPostgreSQLHTML and CSS · skill · Built withHTML/CSSWeb applications · theme · ThemesWeb applicationsWeb browser · service or platform · Runs onWeb browserPDF · dataset or file format · File formatsPDF ask.chaipat…
54 linked in the graph: 25 works11 skills9 techniques2 themes3 services and platforms4 datasets and file formats
When
2023202420252026
Apr 2026 – Nov 2026 · 411 commits

As data

Everything on this page is read from triples in the knowledge graph. These are the 59 it states about ask.chaipat.cc, and 37 more its ontology implies; the console runs SPARQL over the whole graph, here in your browser.

Download
@prefix id: <https://ask.chaipat.cc/id/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix cj: <https://ask.chaipat.cc/ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

id:ThisSite
    a cj:Project ;
    rdfs:label "ask.chaipat.cc, the ask-me-anything site" ;
    cj:shortLabel "ask.chaipat.cc" ;
    skos:altLabel "this site" ,
                  "this website" ,
                  "ask me anything" ,
                  "ask.chaipat.cc site" ;
    cj:context id:ChaipatCC ;
    cj:kind "app" ;
    cj:theme id:ThemeOntology , id:ThemeWeb ;
    cj:uses id:JavaScript ,
            id:HTMLCSS ,
            id:SPARQL ,
            id:OWL ,
            id:KnowledgeGraphs ,
            id:NodeJS ,
            id:Vercel ,
            id:PostgreSQL ,
            id:Redis ,
            id:GitHubActions ,
            id:Playwright ;
    cj:url "https://ask.chaipat.cc"^^xsd:anyURI ;
    cj:liveUrl "https://ask.chaipat.cc"^^xsd:anyURI ;
    cj:begun "2022"^^xsd:gYear ;
    cj:origin "It grew out of the personal site he started in his first year at university, in 2022, and has been rebuilt many times on top of it; parts of that first codebase are still in it. It was served at chaipat.cc until November 2026, when it moved to ask.chaipat.cc and the library of books took the root address." ;
    cj:firstCommit "2026-04-24"^^xsd:date ;
    cj:lastCommit "2026-11-11"^^xsd:date ;
    cj:commitCount 411 ;
    cj:description "This site: a portfolio for finding entities and their live sites, about pages and source code, as well as asking questions about his work. A Turtle knowledge graph supplies facts to a browser SPARQL engine and a shared resource catalog, next to a wiki with full-text search, a timeline and a graph view of the graph and its ontology." ;
    cj:tier 1 ;
    cj:keyRank 5 ;
    cj:implements id:EntityLinking ,
                  id:DamerauLevenshtein ,
                  id:BM25 ,
                  id:ReciprocalRankFusion ,
                  id:EditDistance ,
                  id:OntologyReasoning ,
                  id:ForceDirectedLayout ,
                  id:OWLTime ,
                  id:ServiceWorker ;
    cj:integrates id:Neon , id:Resend ;
    cj:runsOn id:Browser ;
    cj:handles id:TurtleFormat ,
               id:JSONLD ,
               id:Sitemap ,
               id:PDFFormat ;
    cj:relatedTo id:KIWIS , id:GraphExplorer , id:Library ;
    cj:article "https://ask.chaipat.cc/wiki/ThisSite"^^xsd:anyURI ;
    cj:activeIn id:Y2026 ;
    cj:activity _:b156 ,
                _:b157 ,
                _:b158 ,
                _:b159 ,
                _:b160 ,
                _:b161 .