<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[MarketDX]]></title><description><![CDATA[MarketDX]]></description><link>https://marketdx.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Wed, 23 Sep 2026 19:07:56 GMT</lastBuildDate><atom:link href="https://marketdx.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Cutting MCP Round-Trips with Jev (Part 3)]]></title><description><![CDATA[The ping-pong problem MCP pays every day
MarketDX lets AI assistants (like Claude) pull market data through MCP — a set of "tools" the LLM can call itself: find stocks, pull financials, run screens, a]]></description><link>https://marketdx.hashnode.dev/mcp-optimization-round-trip-resolver-jev-3-en</link><guid isPermaLink="true">https://marketdx.hashnode.dev/mcp-optimization-round-trip-resolver-jev-3-en</guid><category><![CDATA[jev]]></category><category><![CDATA[AI]]></category><category><![CDATA[Artificial Intelligence]]></category><category><![CDATA[llm]]></category><category><![CDATA[vector embeddings]]></category><category><![CDATA[Vector Search]]></category><dc:creator><![CDATA[Niran Pravithana]]></dc:creator><pubDate>Sat, 19 Sep 2026 06:22:05 GMT</pubDate><content:encoded><![CDATA[<h2>The ping-pong problem MCP pays every day</h2>
<p>MarketDX lets AI assistants (like Claude) pull market data through <strong>MCP</strong> — a set of "tools" the LLM can call itself: find stocks, pull financials, run screens, and so on.</p>
<p>Sounds simple, but one step is quietly expensive: <strong>turning a human phrase into the values the system actually understands.</strong></p>
<p>Take a real question:</p>
<blockquote>
<p><em>"Retail stocks whose current assets are accelerating sharply"</em></p>
</blockquote>
<p>Before it can screen anything, the system has to convert three pieces into tokens the database knows:</p>
<ul>
<li>"current assets" → <code>CurrentAssets</code></li>
<li>"accelerating sharply" → <code>accelerating</code></li>
<li>"retail" → <code>2550</code> (a GICS code)</li>
</ul>
<p>We do this with a family of <code>find_*</code> tools (<code>find_fsconcept</code>, <code>find_fspattern</code>, <code>find_gics</code>, …). The trouble is how they work:</p>
<ol>
<li>The LLM calls <code>find_fsconcept("current assets")</code> → the system returns a <strong>list of candidates (top-k)</strong>, maybe 10 of them</li>
<li>The LLM <strong>reads them and picks</strong> the right one</li>
<li>Repeat with <code>find_fspattern</code> → top-k → pick</li>
<li>Repeat with <code>find_gics</code> → top-k → pick</li>
<li><strong>Only then</strong> call the real screening tool with the chosen values</li>
</ol>
<p>Count the round-trips: <strong>four back-and-forths</strong> before the real work even starts. Each one has network latency, and — worse — <strong>the LLM has to burn reasoning tokens reading the top-k and deciding every single time.</strong></p>
<p>That's the "ping-pong" MCP hits on nearly every query. The more complex the question (several concepts), the more rounds, and the longer the user waits.</p>
<h3>How <code>find_*</code> works inside (vector search 101)</h3>
<p>First, how does <code>find_*</code> turn "current assets" into <code>CurrentAssets</code>? This is the heart of the story.</p>
<p>The key technique is a <strong>vector embedding</strong> — it turns the <em>meaning</em> of text into a long list of numbers (a vector with thousands of dimensions). Text with similar meaning ends up with vectors that sit close together in that space.</p>
<p>We do two things:</p>
<ol>
<li><strong>Prepare once, ahead of time:</strong> every concept in the catalog ("Total Revenue", "Current Assets", "Gross Margin", …) is turned into a vector by an embedding model (we use Gemini's) and stored.</li>
<li><strong>At query time:</strong> take the user's phrase ("current assets"), embed it the same way, and find its <strong>nearest neighbours</strong> (by cosine similarity) — closer vector = closer meaning.</li>
</ol>
<p>Sort by closeness, take the top k = the <strong>top-k</strong>. (There's also a first pass that matches exact words/aliases — <em>lexical match</em> — before the semantic step, but the idea is the same: "return the ~10 most similar candidates.")</p>
<p><strong>Here's the weakness:</strong> "close in vector space" doesn't always mean "correct." Near-meaning terms — "return on equity" vs "dividend per share", "allowance for doubtful accounts" vs "provision for doubtful accounts" — have vectors so close they get mixed together in the top-k, and sometimes the <em>wrong</em> one even ranks higher than the right one. That's exactly why the system <em>doesn't dare</em> commit to a single answer.</p>
<h3>Why return top-k at all?</h3>
<p>Good question — why doesn't <code>find_*</code> just return one answer and be done?</p>
<p>Because <strong>rank 1 isn't always right.</strong> We measured it on <code>find_fspattern</code> (which matches financial-statement "patterns"): blindly trusting the vector's #1 is correct only <strong>71%</strong> of the time — but the right answer is somewhere in the <strong>top-10 100%</strong> of the time.</p>
<pre><code>find_fspattern (51 patterns):
  trust rank 1 blindly     → 71% correct
  answer is in top-10      → 100%
</code></pre>
<p>See that 71% → 100% gap? <strong>That's why top-k exists</strong> — the system isn't confident enough to commit, so it hands the choices back to the LLM. And that handoff <em>is</em> the ping-pong.</p>
<hr />
<h2>The idea: move "the choosing" to the server</h2>
<p>If the problem is "the system won't choose, so it punts to the LLM" — what if we had something that <strong>dares to choose</strong>, on the server side?</p>
<p>That's where Jev comes in. From Parts 1–2 we know it's a fast, cheap "decision model": give it options and a question, and it returns <strong>one answer plus a confidence score</strong> — no long text to generate.</p>
<p>So the new shape is:</p>
<pre><code>Before:  user → LLM picks route → find_* returns top-k → LLM picks → call real tool   (ping-pong)
After:   user → LLM sends raw phrase into the tool → tool lets Jev choose → carry on   (one round)
</code></pre>
<p>The LLM sends "current assets" straight into the screening tool; the tool calls Jev internally to turn it into <code>CurrentAssets</code>, then screens — <strong>cutting out the whole "return top-k, let the LLM pick" detour.</strong></p>
<p>The question is whether Jev chooses accurately enough to do this. We tried two scenarios.</p>
<hr />
<h2>Small catalog: let Jev pick from the whole set at once</h2>
<p><code>find_fspattern</code> has 51 patterns total — small enough to hand the entire set to Jev as options and let it choose in one shot.</p>
<p><strong>Results:</strong></p>
<pre><code>find_fspattern (51 patterns, Thai &amp; English queries):
  Jev picks once            → 92.9% correct
  vector rank 1 (old way)   → 71.4% correct
</code></pre>
<p>Jev leaves the old rank-1 in the dust and gets close to the 100% ceiling that normally requires the LLM to re-pick — <strong>but in a single shot, no ping-pong.</strong></p>
<h3>Surprise: most of the "misses" were our fault</h3>
<p>At first we had a case that looked like a Jev miss: the query <em>"the stock's value doubled"</em> — Jev answered "higher than the rest" instead of "compound growth."</p>
<p>We nearly blamed Jev — until we looked at <strong>what we'd fed it.</strong> We were only sending each pattern's <em>short definition</em>, and the compound-growth definition talked only about "annual rate (CAGR)" — the word "doubled" never appeared. Yet the real database had another description field spelling out <em>"the value doubles or triples."</em></p>
<p><strong>The fix:</strong> feed the full description that the search itself actually uses — and Jev got it right immediately.</p>
<blockquote>
<p>This echoes what we learned in Part 2: <strong>before blaming the model, look at what you fed it.</strong> Almost every "miss" turned out to be context we didn't fully supply, or a reference answer of ours that was too narrow.</p>
</blockquote>
<hr />
<h2>The main case: too many candidates to fit — vector + Jev</h2>
<p>This is the common, important one: <strong>most catalogs are too big to hand to Jev whole.</strong> The financial-concept finder (<code>find_fsconcept</code>) has <strong>428 entries</strong> (statement lines + ratios + valuation multiples); the stock finder has tens of thousands; the economic-data finder tens of thousands more.</p>
<p>Dumping all 428 into Jev at once won't work (expensive and over the limit). But we don't have to throw away what we have — <strong>let the existing vector search pre-filter first:</strong></p>
<pre><code>raw phrase → [vector search narrows to top-15] → [Jev picks 1 of 15] → token
</code></pre>
<p>Vector search does what it's good at (narrow thousands to ten); Jev does what it's good at (pick the right one out of ten) — <strong>and the choosing still happens on the server, no ping-pong back to the LLM.</strong></p>
<p><strong>Results:</strong></p>
<pre><code>find_fsconcept (428 entries, English queries):
  vector rank 1 (old way)      → 68% correct
  vector top-15 → Jev picks    → 100% correct
</code></pre>
<p>Jev fixed <strong>every</strong> case the vector mis-ranked — genuinely hard ones, like:</p>
<ul>
<li>"ผลตอบแทนผู้ถือหุ้น" or "return on equity (ROE)" in English — vector guessed "dividend per share" → Jev picked <code>roe</code></li>
<li>"หนี้ที่มีภาระดอกเบี้ยรวม" or "total interest-bearing debt" in English — vector guessed "accrued interest" → Jev picked <code>total_debt</code></li>
<li>"งานระหว่างก่อสร้าง", "เงินลงทุนที่ถือจนครบกำหนด", "กำไรขาดทุนเบ็ดเสร็จอื่นสะสม" or "construction in progress", "held-to-maturity investments", "accumulated other comprehensive income" — deep accounting terms the vector drifted on, but Jev picked correctly</li>
</ul>
<p>Even more impressive, it got the <em>type</em> right: <em>"gross profit"</em> → the statement line (<code>gross_profit</code>), while <em>"gross margin"</em> → the ratio (<code>gross_margin</code>). Different things — Jev doesn't confuse them.</p>
<hr />
<h2>And the cost? — vector + Jev is still cheaper</h2>
<p>You might assume adding Jev makes it more expensive. The opposite is true.</p>
<table>
<thead>
<tr>
<th>Approach</th>
<th>Options Jev reads</th>
<th>Cost / 1,000 calls</th>
</tr>
</thead>
<tbody><tr>
<td>Whole catalog (51)</td>
<td>51</td>
<td>$0.35</td>
</tr>
<tr>
<td><strong>vector filter → Jev (10–15)</strong></td>
<td>~10</td>
<td><strong>$0.08</strong></td>
</tr>
</tbody></table>
<p>Pre-filtering with vectors is <strong>~4× cheaper</strong>, because Jev's cost is driven by the length of the options you feed it — reading 10 options is far cheaper than reading 400.</p>
<p>On top of that, the vector's embedding cost is nearly zero, because we store the vectors of previously-seen queries permanently (repeat query = no recompute). And Jev itself bills for input only, output is free, and it's several times cheaper than a general LLM.</p>
<p><strong>In round-trips:</strong> from <strong>4 rounds → 1.</strong> The user gets an answer noticeably faster, and the client-side LLM doesn't have to break focus to sift top-k on every question — it can spend those tokens on what matters. <strong>That's a genuinely better MCP experience.</strong></p>
<hr />
<h2>Lessons worth keeping (the real ones)</h2>
<p>Shipping this for real means being honest about the limits. We found four.</p>
<p><strong>1. The context you feed matters more than you think.</strong>
Almost every Jev "miss" was us feeding an incomplete description, or a reference answer that was too narrow. Fixing the descriptions in the database improves the <em>whole</em> system — vector and Jev both consume the same descriptions.</p>
<p><strong>2. "Asking to confirm" has to be smart, or it destroys the UX you just fixed.</strong>
Sometimes Jev genuinely isn't sure — the question is ambiguous, or two options are neck-and-neck. We designed the tool to look at the <em>shape</em> of the confidence, not just one number:</p>
<ul>
<li>clearly confident → use it</li>
<li>borderline but usable → answer anyway, with a note on how it interpreted the phrase (don't block)</li>
<li>two options genuinely close <em>and</em> genuinely different → <em>then</em> ask the user to confirm (rare)</li>
</ul>
<p>The principle: only ask to confirm when "the right answer exists but Jev can't pick it cleanly" — not every time it's unsure. Otherwise you're back to ping-pong.</p>
<p><strong>3. Multiple languages → translate to English first (and this is a vector limitation, not Jev's).</strong>
Testing deep accounting terms across languages, we found the Thai word for <em>goodwill</em> (ค่าความนิยม) fell to rank 45 in the vector search — out of the top-15, so Jev never saw it as an option. On the surface it looks like Jev failed.</p>
<p>But we proved it's a <strong>cross-language weakness of the embedding, not Jev</strong> — ask the same term in English ("goodwill") and it ranks #1 instantly; Jev even knows that のれん (Japanese) means goodwill. Luckily our MCP tools already require the client to translate to English before sending — so this doesn't bite in practice.</p>
<p><strong>4. Razor-thin accounting distinctions — Jev sails through.</strong>
We built the meanest test we could: pairs of terms that differ by a hair but mean different things.</p>
<table>
<thead>
<tr>
<th>Distinction to make</th>
<th>Jev got it right?</th>
</tr>
</thead>
<tbody><tr>
<td>treasury stock ↔ buybacks</td>
<td>✅</td>
</tr>
<tr>
<td>provision (P&amp;L) ↔ allowance (balance sheet)</td>
<td>✅</td>
</tr>
<tr>
<td>deferred tax asset ↔ deferred tax liability</td>
<td>✅</td>
</tr>
<tr>
<td>current ↔ non-current</td>
<td>✅</td>
</tr>
<tr>
<td>interest-bearing debt ↔ total liabilities ↔ borrowings (excl. leases)</td>
<td>✅</td>
</tr>
</tbody></table>
<p><strong>25 brutal pairs — Jev scored 100% at an average confidence of 0.998</strong>, versus the vector's rank-1 at 48%. This is the scariest failure mode (being confidently wrong), and Jev passed it comfortably in English.</p>
<hr />
<h2>Conclusion: when to collapse a resolver with Jev</h2>
<p>From what we've tried, the playbook is clear:</p>
<ul>
<li><strong>Small catalog (a few dozen):</strong> let Jev pick from the whole set in one shot.</li>
<li><strong>Large catalog (hundreds / thousands / tens of thousands):</strong> use vector search to pre-filter to ~10–15, then let Jev pick — <strong>you still collapse the round-trips <em>and</em> pay less.</strong></li>
<li><strong>Add a cache shortcut:</strong> phrases you've resolved before (e.g., "current assets" → <code>CurrentAssets</code>) get stored, so next time you return instantly without calling Jev again.</li>
</ul>
<p>All of this turns MCP from "four rounds of ping-pong per question" into "one round" — faster, cheaper, and lighter on the client LLM.</p>
<p><strong>A caveat:</strong> don't flip everything in one day. The safe path is to run Jev <strong>in parallel</strong> with the old resolver on real traffic for a while, compare the results, watch the confidence distribution, then enable it piece by piece — and keep a fallback in case Jev is slow or down (we measure ~1 second normally, but with a tail that can spike into the tens of seconds).</p>
<p>Still, the direction is clear: <strong>a resolver is the "round-trip tax" MCP pays on every query — Jev pays that tax for you.</strong> And no matter how many candidates there are, the vector + Jev pairing collapses it, both faster and cheaper.</p>
]]></content:encoded></item><item><title><![CDATA[Putting Jev to Work: Results, Cost, and Lessons (Part 2)]]></title><description><![CDATA[The task we chose
MarketDX turns financial news into an impact graph. At its core is a step that reads each article and classifies + scores it — and it runs on every article that flows in. It's the hi]]></description><link>https://marketdx.hashnode.dev/putting-jev-to-work-results-cost-and-lessons-en</link><guid isPermaLink="true">https://marketdx.hashnode.dev/putting-jev-to-work-results-cost-and-lessons-en</guid><category><![CDATA[jev]]></category><category><![CDATA[AI]]></category><category><![CDATA[llm]]></category><category><![CDATA[fintech]]></category><category><![CDATA[Artificial Intelligence]]></category><dc:creator><![CDATA[Niran Pravithana]]></dc:creator><pubDate>Sat, 19 Sep 2026 06:08:04 GMT</pubDate><content:encoded><![CDATA[<h2>The task we chose</h2>
<p>MarketDX turns financial news into an impact graph. At its core is a step that <strong>reads each article and classifies + scores it</strong> — and it runs on <strong>every article</strong> that flows in. It's the highest-volume LLM task in the system, so if Jev can take it over, the savings are the biggest. That made it the right place for a real test. It breaks into four sub-decisions:</p>
<ol>
<li><p><strong>News type</strong> — what kind of story is this (earnings / M&amp;A / legal / macro / …)?</p>
</li>
<li><p><strong>Impact (1–5)</strong> — how much should an investor care?</p>
</li>
<li><p><strong>Link to an investment theme (megatrend)</strong> — which trend does this move?</p>
</li>
<li><p><strong>Impact detail</strong> — direction (positive/negative), strength, and the channel it acts through.</p>
</li>
</ol>
<p>We tested them one at a time and read the actual output every time. Here's what happened.</p>
<hr />
<h2>Part 1: News type — better than the number suggests</h2>
<p>We gave Jev a Choice of 16 types and compared it to what the current system had assigned. The headline was "74% agreement" — which sounds ordinary. <strong>But reading the actual disagreements flipped the picture:</strong></p>
<ul>
<li><p>Most "mismatches" were <strong>genuinely ambiguous boundaries</strong> (e.g., "analyst raises price target" vs "analyst revises earnings estimate") where Jev's answer was just as defensible.</p>
</li>
<li><p>In some cases <strong>Jev was more correct</strong> — the old system had classified two near-identical stories as <em>different</em> types (inconsistent); Jev classified them the same, and closer to the actual content.</p>
</li>
</ul>
<p><strong>The one real trap:</strong> Jev was reluctant to answer "noise / not real news" — it kept trying to force a "real" category. <strong>The fix was a policy tweak</strong>: tell it plainly that "noise is a normal, common answer — don't force a category just because a keyword matches." The result:</p>
<ul>
<li>On a <strong>fresh, unseen</strong> set of 45 articles: it caught junk correctly <strong>20/20</strong>, and <strong>never once</strong> wrongly flagged real news as junk (<strong>0/25</strong>).</li>
</ul>
<p>Lesson: Jev's biases are fixable by clarifying the <em>policy</em> — no example-feeding required.</p>
<hr />
<h2>Part 2: Impact — a bias we found, fixed, and a production bug it caught</h2>
<p>Asked to score 1–5 directly (a single Score question), Jev had a <strong>central bias</strong> — nearly everything landed on 3, and it <strong>never assigned 1</strong> (noise). Useless as a gate.</p>
<p><strong>The fix that worked — break it into sub-questions and combine them ourselves.</strong> Instead of one fuzzy "how important is this," we asked several yes/no questions (is there genuinely new information? is it unusually large? is it surprising? is it wide-reaching? is it promotional/PR?) and <strong>combined the answers into a score with a formula we control.</strong> Now the scores spread realistically, it can assign 1 to noise again, and it cleanly filters ads/spam.</p>
<p><strong>The surprise:</strong> along the way, <strong>Jev caught a bug in the existing system</strong> — a genuine earnings report from a major industry bellwether had been tagged "short news / unimportant" by a length-based rule, while Jev correctly rated it high. Strong proof that "chase the old system" is the wrong goal.</p>
<hr />
<h2>Part 3: Linking to investment themes — a lesson about <em>context</em> and <em>drilling down</em></h2>
<p>This was the hardest part: there are <strong>25 top-level themes and ~300 sub-nodes across three levels</strong>, and most articles <strong>don't move any theme at all</strong>.</p>
<p><strong>The first attempt failed:</strong> asking broadly "does this move any theme?" — Jev could barely tell movers from non-movers, because the question was too abstract.</p>
<p><strong>What fixed it (two things):</strong></p>
<ol>
<li><p><strong>Add context, not just names.</strong> Theme names alone are short and ambiguous, so we included each theme's description and examples in the question.</p>
</li>
<li><p><strong>Ask per-theme and drill top-down</strong> — pick the top-level theme first → then the sub-theme → then deeper (a drill-down).</p>
</li>
</ol>
<p>With those two changes the picture turned strongly positive — <strong>Jev almost never links a story to the wrong theme</strong> (very high precision).</p>
<p><strong>A "product taste" call we had to make:</strong> should linking be <em>strict</em> (only stories that truly move a whole theme) or <em>broad coverage</em> (a company in that sector counts too)? We chose <strong>"broad coverage, but nothing jarring — if a reader would go 'huh, that doesn't belong,' don't link it."</strong> Once we framed the question that way, Jev delivered exactly that — it links stories that fit (an airline under Aviation, a gold miner under Critical Materials) and rejects the off-topic ones, without ever spraying to the wrong theme.</p>
<p><strong>Drilling to the specific sub-node:</strong> when it went down to pick the exact node, Jev hit <strong>80% exact / 90% right-subtree</strong>, and in several cases it was <strong>more precise than the old system</strong> (which stopped at "Precious Metals" where Jev correctly drilled to "Gold").</p>
<p><strong>Impact detail:</strong> direction (positive/negative) and strength worked well. The "channel" field looked noisy at first — until we realized we'd <em>modelled it wrong</em>: one event hits several channels at once (a solar subsidy is <em>pricing</em> + <em>demand</em> + <em>capital</em>). Once we let it return <strong>multiple channels (multi-label)</strong> instead of forcing one, the problem disappeared.</p>
<hr />
<h2>Four lessons</h2>
<ol>
<li><p><strong>Don't judge a new AI by "does it match the old one."</strong> The old one can be wrong too (we caught several of its bugs). Read the real output and decide.</p>
</li>
<li><p><strong>Jev's biases are fixable through the <em>policy</em> in the prompt</strong> — no example-feeding (which would cause overfitting).</p>
</li>
<li><p><strong>Decompose hard judgments and combine them yourself</strong> — both impact (many yes/no questions) and theme-linking (top-down drill-down) beat asking in one shot.</p>
</li>
<li><p><strong>Add context, and allow multiple answers</strong> where reality is multi-valued (impact channels, news types).</p>
</li>
</ol>
<hr />
<h2>Cost comparison (rough numbers, per 1,000 decisions)</h2>
<p>Assume one news-classification decision, ~1,200 tokens in, a short answer out:</p>
<table>
<thead>
<tr>
<th>Option</th>
<th>Input price</th>
<th>Output price</th>
<th><strong>~per 1,000 articles</strong></th>
</tr>
</thead>
<tbody><tr>
<td>Gemini Flash (mid LLM)</td>
<td>~$0.30/M</td>
<td>~$2.50/M</td>
<td><strong>~$0.49</strong></td>
</tr>
<tr>
<td>DeepSeek flash</td>
<td>~$0.14/M</td>
<td>~$0.50/M</td>
<td><strong>~$0.19</strong></td>
</tr>
<tr>
<td>OpenAI nano (small)</td>
<td>~$0.10/M</td>
<td>~$0.40/M</td>
<td><strong>~$0.13</strong></td>
</tr>
<tr>
<td><strong>Jev</strong></td>
<td><strong>$0.042/M</strong></td>
<td><strong>free</strong></td>
<td><strong>~$0.05</strong></td>
</tr>
</tbody></table>
<ul>
<li><p><strong>Jev is the cheapest</strong> — roughly <strong>3–10× less</strong> than the small/mid LLMs, partly because output is free (the more parallel questions you ask, the bigger the edge).</p>
</li>
<li><p>Compared to <strong>vector embeddings</strong> (a similarly cheap option) it's a different job: embeddings tell you "what's similar," they can't <em>decide</em>; Jev decides. The best pattern is to use both — cheap embedding shortlist → Jev decides.</p>
</li>
</ul>
<blockquote>
<p>These are ballpark figures at 2026 prices, and real cost depends on prompt length. Treat them as <em>orders of magnitude</em>, not exact accounting.</p>
</blockquote>
<p><strong>On speed:</strong> Jev runs ~1s per call (with occasional multi-second spikes) — fine for per-item decisions, but <strong>don't loop it over millions of items directly</strong>; shortlist first with something cheaper.</p>
<hr />
<h2>When to use Jev</h2>
<p><strong>Use Jev when</strong> the work is a clear <em>decision</em> (classify / score / yes-no), volume is high, and you want calibrated confidence to gate on. Jev is <strong>cheaper, fast enough, and its output is locked to your options</strong> (it can't hallucinate something out of range).</p>
<p><strong>Stick with an LLM when</strong> you need writing, explanation, translation, or multi-step reasoning — Jev can't do those and isn't meant to.</p>
<p><strong>The overall result:</strong> across MarketDX's news classification and scoring, <strong>Jev matched or beat the existing LLM system on almost every axis</strong> (handling noise/spam, not mislinking themes, precise sub-node drilling) at several times lower cost.</p>
<p><strong>An honest caveat before going live:</strong> all of this was judged by us (with Claude Opus) reading a sample of a few hundred articles — not because the quality is unproven, but because scale, drift, and edge cases need confirmation on real traffic. Before flipping a switch you'd want to run it in parallel with the old system for a while, keep a standard sample set to watch quality, and account for the occasional latency spike and slight run-to-run variance.</p>
<p>Bottom line: for high-volume decisions, <strong>Jev is worth investing in</strong> — not to replace LLMs wholesale, but to take over the <em>decision</em> parts, which turn out to be far more common than you'd think.</p>
]]></content:encoded></item><item><title><![CDATA[Is Jev Smart Enough? Testing a Decision-Model AI (Part 1)]]></title><description><![CDATA[What is Jev?
The AI models most of us know — GPT, Claude, Gemini, DeepSeek — work by generating text one token at a time. You ask, they write an answer. That's powerful for writing, summarizing, trans]]></description><link>https://marketdx.hashnode.dev/is-jev-smart-enough-language-and-world-knowledge-en</link><guid isPermaLink="true">https://marketdx.hashnode.dev/is-jev-smart-enough-language-and-world-knowledge-en</guid><category><![CDATA[jev]]></category><category><![CDATA[llm]]></category><category><![CDATA[nlp]]></category><category><![CDATA[Artificial Intelligence]]></category><dc:creator><![CDATA[Niran Pravithana]]></dc:creator><pubDate>Sat, 19 Sep 2026 06:02:27 GMT</pubDate><content:encoded><![CDATA[<h2>What is Jev?</h2>
<p>The AI models most of us know — GPT, Claude, Gemini, DeepSeek — work by <strong>generating text one token at a time</strong>. You ask, they write an answer. That's powerful for writing, summarizing, translating, or reasoning step by step.</p>
<p>But a huge amount of real software doesn't need <em>text</em> — it needs a <strong>decision</strong>:</p>
<ul>
<li><p>What kind of news is this?</p>
</li>
<li><p>How important is it, on a scale of 1–5?</p>
</li>
<li><p>Should we process this content, or drop it?</p>
</li>
</ul>
<p><strong>Jev</strong> (from TypeSafe AI) is built specifically for that. It doesn't write prose. It <strong>picks an answer from a set you define and returns a typed result with a confidence score</strong> — instantly.</p>
<p>It has exactly three question types:</p>
<ul>
<li><p><strong>Choice</strong> — pick one option from a defined set (with a probability for each)</p>
</li>
<li><p><strong>Score</strong> — rate against ordered levels you describe</p>
</li>
<li><p><strong>Noul</strong> — yes/no, returned as a probability from 0 to 1</p>
</li>
</ul>
<p>There's an interesting economic wrinkle too: <strong>Jev bills for input only — output is free</strong> — and it's fast (roughly ~1 second in our tests), because it never has to write text token by token.</p>
<p><strong>The core question we set out to answer:</strong> can a model that <em>only makes decisions</em> be smart and accurate enough to replace tasks we run on big LLMs today? Part 1 starts at the foundation — <strong>does it actually understand language and possess real knowledge?</strong> — before Part 2 tries it on a real workload.</p>
<hr />
<h2>What MarketDX does?</h2>
<p>MarketDX is a platform that <strong>turns financial news into an impact graph</strong> — it reads a story and works out which assets and investment themes it moves, in which direction, and how that ripples out to related players. Under the hood there are a <em>lot</em> of "decision" steps, and many of them run on every single article that comes in. That means shaving cost off each decision compounds fast — which is exactly why Jev caught our attention.</p>
<hr />
<h2>How we tested?</h2>
<p>Two ground rules shaped everything, and they change how you should read the results:</p>
<p><strong>1. Judge quality by reading the output yourself, not by "does it match the old system."</strong> Our current system is <em>also</em> an LLM (which is sometimes wrong). Measuring "how often does Jev agree with the LLM" tells you how <em>similar</em> it is, not how <em>good</em>. The goal is to be <strong>better</strong>, not identical — so we read the actual results and judged them ourselves.</p>
<p><strong>2. Write the prompt without leaking the answer.</strong> It's fine to state the <em>task definition</em> in the prompt (e.g., "treat these as the same meaning even if politeness or slang differs"). What we do <strong>not</strong> do is drop in example sentences that give away the expected answer — that inflates the results and hides real weaknesses.</p>
<hr />
<h2>Test 1: Language — does it understand <em>meaning</em> across languages?</h2>
<p><strong>The question:</strong> does Jev know that <em>"Have you eaten yet?"</em> (polite) and <em>"Yo, you grubbed yet?"</em> (slang) mean the same thing? And in how many languages?</p>
<p><strong>Method:</strong> we hand-wrote sentences in <strong>23 languages</strong> (English, Chinese, Japanese, Arabic, Hindi, Korean, Thai, Taiwanese Hokkien, and more). For each language, three variants, then asked Jev whether the pairs "carry the same core meaning":</p>
<ul>
<li><p><strong>A vs B</strong> — polite ↔ slang, same meaning → should score <strong>high</strong></p>
</li>
<li><p><strong>A vs N</strong> — very similar wording but a different intent (e.g., "Have you eaten yet?" [asking] vs "Oh, you've eaten already?" [surprised confirmation]) → genuinely borderline</p>
</li>
<li><p><strong>A vs C</strong> — different topic entirely ("have you eaten?" vs "are you hungry?") → should score <strong>low</strong></p>
</li>
</ul>
<p><strong>Results (averaged across all 23 languages, scores 0–1):</strong></p>
<table>
<thead>
<tr>
<th>Pair</th>
<th>"same meaning" score</th>
<th>Reading</th>
</tr>
</thead>
<tbody><tr>
<td>polite ↔ slang (truly same)</td>
<td><strong>0.89</strong></td>
<td>✅ knows they're the same</td>
</tr>
<tr>
<td>close wording, different intent</td>
<td><strong>0.64</strong></td>
<td>🟡 borderline — as it should be</td>
</tr>
<tr>
<td>different topic</td>
<td><strong>0.20</strong></td>
<td>✅ knows they differ</td>
</tr>
</tbody></table>
<p><strong>What it means:</strong> Jev <strong>ranks the gradient correctly</strong> (clearly-same &gt; borderline &gt; different) in almost every language, and it does so across all 23 including slang — not just English. Impressively, it separates "are you hungry?" from "have you eaten?" even though the sentences overlap heavily.</p>
<p><strong>Real weaknesses we found:</strong></p>
<ul>
<li><p><strong>Low-resource dialects</strong> (Taiwanese Hokkien) are the weakest — it can't slice fine distinctions as sharply as major languages.</p>
</li>
<li><p><strong>Ambiguous idioms</strong> — e.g., British "have your tea" (which can mean the evening meal <em>or</em> the drink) — Jev takes the literal reading.</p>
</li>
</ul>
<p><strong>A useful side-finding:</strong> we fired the identical request three times; the billed token count stayed the same every time → <strong>Jev has no prompt cache</strong> (unlike several LLMs). To save money you shrink the input or batch several questions into one request, not repeat-and-cache.</p>
<hr />
<h2>Test 2: World knowledge — shallow and deep</h2>
<p><strong>The question:</strong> beyond understanding language, does it actually <em>know things</em> — both general knowledge and deep, specialized knowledge?</p>
<p><strong>Method:</strong> a 4-option multiple-choice exam, <strong>75 questions</strong>, across 3 difficulty tiers × 15 subjects (accounting, law, finance, medicine, physics, history, philosophy, and more):</p>
<ul>
<li><p><strong>General</strong> — broad common knowledge</p>
</li>
<li><p><strong>Shallow</strong> — what a student in that field should know</p>
</li>
<li><p><strong>Deep</strong> — genuinely specialized: e.g., R&amp;D cost treatment under IFRS vs US GAAP, Japan's Yayoi period, the Gettier problem in epistemology, the Modigliani–Miller theorem</p>
</li>
</ul>
<p>(We shuffled the answer positions on every question so the correct answer wasn't clustered in one slot.)</p>
<p><strong>Results:</strong></p>
<table>
<thead>
<tr>
<th>Tier</th>
<th>Score</th>
</tr>
</thead>
<tbody><tr>
<td>General</td>
<td>15/15</td>
</tr>
<tr>
<td>Shallow</td>
<td>30/30</td>
</tr>
<tr>
<td>Deep</td>
<td>30/30</td>
</tr>
<tr>
<td><strong>Total</strong></td>
<td><strong>75/75 = 100%</strong></td>
</tr>
</tbody></table>
<p>Its confidence was ~1.00 on nearly every question, and it answered the deep, specialized items correctly.</p>
<p><strong>An honest reading:</strong> 100% is impressive, but it also means <strong>we never found the ceiling</strong>. Our "deep" questions, while specialized, are still textbook facts. We didn't test genuinely contested knowledge, obscure long-tail trivia, or problems that require multi-step reasoning rather than recall. So the fair conclusion is "broad and deep enough," not "no limits."</p>
<hr />
<h2>Wrap-up (Part 1)</h2>
<p>These two foundational tests answer the question <strong>"is Jev smart enough?"</strong> fairly clearly:</p>
<ul>
<li><p>It <strong>understands language and meaning</strong> across 23 languages, including slang and shifts in register, accurately and with sensible gradients.</p>
</li>
<li><p>It <strong>has knowledge</strong>, both broad and deep, across many fields.</p>
</li>
<li><p>It's fast (~1s) and bills for input only.</p>
</li>
</ul>
<p>With the fundamentals looking solid, we felt safe pointing it at <strong>real MarketDX work</strong> — which is <strong>Part 2</strong>: we put Jev on a high-volume decision task that runs on every article, look at how it did, the traps we hit and fixed, and how the cost compares to the LLMs we use today (DeepSeek / OpenAI / Gemini).</p>
]]></content:encoded></item><item><title><![CDATA[MCP Optimization: ลด round-trip ของ resolver ด้วย Jev (ตอนที่ 3)]]></title><description><![CDATA[ปัญหาที่ MCP เจอทุกวัน: การปิงปอง
MarketDX เปิดให้ผู้ช่วย AI (เช่น Claude) เรียกข้อมูลตลาดผ่าน MCP — ชุด "เครื่องมือ" ที่ LLM เรียกใช้ได้เอง ค้นหุ้น ดึงงบ สกรีน ฯลฯ
ฟังดูง่าย แต่มีขั้นตอนหนึ่งที่แพงเง]]></description><link>https://marketdx.hashnode.dev/mcp-optimization-round-trip-resolver-jev-3</link><guid isPermaLink="true">https://marketdx.hashnode.dev/mcp-optimization-round-trip-resolver-jev-3</guid><category><![CDATA[jev]]></category><category><![CDATA[AI]]></category><category><![CDATA[llm]]></category><category><![CDATA[Artificial Intelligence]]></category><category><![CDATA[vector embeddings]]></category><category><![CDATA[Vector Search]]></category><dc:creator><![CDATA[Niran Pravithana]]></dc:creator><pubDate>Fri, 18 Sep 2026 10:20:29 GMT</pubDate><content:encoded><![CDATA[<h2>ปัญหาที่ MCP เจอทุกวัน: การปิงปอง</h2>
<p>MarketDX เปิดให้ผู้ช่วย AI (เช่น Claude) เรียกข้อมูลตลาดผ่าน <strong>MCP</strong> — ชุด "เครื่องมือ" ที่ LLM เรียกใช้ได้เอง ค้นหุ้น ดึงงบ สกรีน ฯลฯ</p>
<p>ฟังดูง่าย แต่มีขั้นตอนหนึ่งที่แพงเงียบ ๆ คือ <strong>การแปลงคำพูดคนให้เป็นค่าที่ระบบเข้าใจ</strong></p>
<p>ลองดูคำถามจริง:</p>
<blockquote>
<p><em>"หุ้นในกลุ่มค้าปลีกที่มีสินทรัพย์หมุนเวียนเพิ่มขึ้นก้าวกระโดด"</em></p>
</blockquote>
<p>ก่อนจะสกรีนได้ ระบบต้องแปลง 3 ชิ้นนี้เป็น "โทเคน" ที่ฐานข้อมูลรู้จัก:</p>
<ul>
<li>"สินทรัพย์หมุนเวียน" → <code>CurrentAssets</code></li>
<li>"เพิ่มขึ้นก้าวกระโดด" → <code>accelerating</code></li>
<li>"กลุ่มค้าปลีก" → <code>2550</code> (รหัส GICS)</li>
</ul>
<p>งานนี้เราทำด้วยเครื่องมือตระกูล <code>find_*</code> (find_fsconcept, find_fspattern, find_gics ...) ปัญหาคือมันทำงานแบบนี้:</p>
<ol>
<li>LLM เรียก <code>find_fsconcept("สินทรัพย์หมุนเวียน")</code> → ระบบคืน <strong>รายการผู้สมัคร (top-k)</strong> กลับมาสัก 10 ตัว</li>
<li>LLM <strong>อ่านแล้วเลือก</strong> อันที่ใช่</li>
<li>ทำซ้ำกับ <code>find_fspattern</code> → คืน top-k → เลือก</li>
<li>ทำซ้ำกับ <code>find_gics</code> → คืน top-k → เลือก</li>
<li><strong>แล้วค่อย</strong> เรียกเครื่องมือสกรีนจริงด้วยค่าที่เลือกได้</li>
</ol>
<p>นับ round-trip ดู: <strong>สี่รอบไปกลับ</strong> กว่าจะได้เริ่มงานจริง ทุกรอบมี latency ของเน็ต บวกกับที่หนักกว่านั้น — <strong>LLM ต้องเผา reasoning token อ่าน top-k แล้วตัดสินใจเลือกทุกครั้ง</strong></p>
<p>นี่คือ "การปิงปอง" ที่ MCP เจอแทบทุกคำถาม ยิ่งคำถามซับซ้อน (หลาย concept) ยิ่งปิงปองหลายรอบ ผู้ใช้ก็รอนานขึ้น</p>
<h3><code>find_*</code> ทำงานยังไงข้างใน (vector search 101)</h3>
<p>ก่อนไปต่อ ขออธิบายว่า <code>find_*</code> แปลง "สินทรัพย์หมุนเวียน" เป็น <code>CurrentAssets</code> ได้ยังไง เพราะมันคือหัวใจของเรื่องนี้</p>
<p>หัวใจคือเทคนิคชื่อ <strong>vector embedding</strong> — แปลง "ความหมาย" ของข้อความให้เป็นชุดตัวเลขยาว ๆ (เวกเตอร์หลายพันมิติ) ข้อความที่ความหมายใกล้กันจะได้เวกเตอร์ที่อยู่ใกล้กันในปริภูมิ</p>
<p>ระบบเราทำสองอย่าง:</p>
<ol>
<li><strong>เตรียมล่วงหน้า (ครั้งเดียว):</strong> ทุกแนวคิดใน catalog (เช่น "Total Revenue", "Current Assets", "Gross Margin") ถูกแปลงเป็นเวกเตอร์ด้วยโมเดล embedding (เราใช้ของ Gemini) แล้วเก็บไว้ในฐานข้อมูล</li>
<li><strong>ตอนมีคำถาม:</strong> เอาคำที่ผู้ใช้ถาม ("สินทรัพย์หมุนเวียน") มาแปลงเป็นเวกเตอร์แบบเดียวกัน แล้ว <strong>หาเพื่อนบ้านที่ใกล้ที่สุด</strong> (nearest-neighbor ด้วย cosine similarity) — เวกเตอร์ยิ่งใกล้ = ความหมายยิ่งคล้าย</li>
</ol>
<p>เรียงผลตามความใกล้ เอา k อันบนสุด = <strong>top-k</strong> (จริง ๆ มีอีกชั้นคือจับคำตรงตัว/ชื่อพ้อง — <em>lexical match</em> — มาก่อน semantic แต่หลักการรวมคือ "คืนผู้สมัครที่คล้ายที่สุดมาสัก 10 ตัว")</p>
<p><strong>จุดอ่อนอยู่ตรงนี้:</strong> "ใกล้ในเชิงเวกเตอร์" ไม่ได้แปลว่า "ใช่" เสมอ คำที่ความหมายเฉียด ๆ กัน — "ผลตอบแทนผู้ถือหุ้น" กับ "เงินปันผลต่อหุ้น", "ค่าเผื่อหนี้สงสัยจะสูญ" กับ "ตั้งสำรองหนี้สงสัยจะสูญ" — เวกเตอร์มันใกล้กันมากจนโผล่ปนกันใน top-k และบางทีตัวผิดดันอยู่อันดับสูงกว่าตัวถูกด้วยซ้ำ นั่นคือเหตุผลที่ระบบ <em>ไม่กล้า</em> ฟันธงอันเดียว</p>
<h3>ทำไมต้องคืน top-k ตั้งแต่แรก?</h3>
<p>คำถามที่ดีคือ — ทำไม <code>find_*</code> ไม่คืนคำตอบเดียวไปเลย ให้จบ?</p>
<p>เพราะ <strong>อันดับ 1 ไม่ได้ถูกเสมอ</strong> เราวัดจริงกับ <code>find_fspattern</code> (ตัวหา"รูปแบบ" ของงบ): ถ้าเชื่ออันดับ 1 ของ vector search ดื้อ ๆ จะถูกแค่ <strong>71%</strong> แต่ถ้าดู top-10 ทั้งชุด — คำตอบที่ถูก <strong>อยู่ในนั้น 100%</strong></p>
<pre><code>find_fspattern (51 รูปแบบ):
  เชื่ออันดับ 1 ดื้อ ๆ         → ถูก 71%
  คำตอบอยู่ใน top-10          → 100%
</code></pre>
<p>เห็นช่องว่าง 71% → 100% ไหม? <strong>นั่นแหละคือเหตุผลที่มี top-k</strong> — ระบบไม่มั่นใจพอจะฟันธง เลยโยนตัวเลือกกลับให้ LLM ตัดสิน และนั่นคือต้นตอของการปิงปอง</p>
<hr />
<h2>ไอเดีย: ย้าย "การเลือก" ไปไว้ฝั่งเซิร์ฟเวอร์</h2>
<p>ถ้าปัญหาคือ "ระบบไม่กล้าเลือก เลยโยนกลับให้ LLM" — แล้วถ้าเรามีตัวที่ <strong>กล้าเลือกแทน</strong> อยู่ฝั่งเซิร์ฟเวอร์ล่ะ?</p>
<p>นี่คือจุดที่ Jev เข้ามา จากตอน 1-2 เรารู้แล้วว่ามันเป็น "โมเดลตัดสินใจ" ที่เร็วและถูก — ให้ตัวเลือกกับคำถาม มันคืน <strong>คำตอบเดียว + ความมั่นใจ (confidence)</strong> ไม่ต้อง generate ข้อความยาว</p>
<p>โครงใหม่จึงเป็น:</p>
<pre><code>เดิม:  user → LLM เลือก route → find_* คืน top-k → LLM เลือก → เรียก tool จริง   (ปิงปอง)
ใหม่:  user → LLM ส่งคำดิบเข้า tool → tool ให้ Jev เลือกเอง → ทำงานต่อได้เลย     (รอบเดียว)
</code></pre>
<p>LLM ส่ง "สินทรัพย์หมุนเวียน" เข้าเครื่องมือสกรีนตรง ๆ เครื่องมือเรียก Jev แปลงเป็น <code>CurrentAssets</code> ข้างในเอง แล้วสกรีนต่อได้เลย — <strong>ตัดขั้นตอนโยน top-k กลับไปให้ LLM เลือกทิ้งทั้งหมด</strong></p>
<p>คำถามคือ Jev เลือกแม่นพอจะทำแบบนี้ไหม เราลองสองสถานการณ์</p>
<hr />
<h2>กรณี catalog เล็ก: ให้ Jev เลือกจากทั้งชุดทีเดียว</h2>
<p><code>find_fspattern</code> มีรูปแบบทั้งหมด 51 ตัว — เล็กพอจะยัดทั้งชุดเป็นตัวเลือกให้ Jev เลือกในครั้งเดียว</p>
<p><strong>อ่านผล:</strong></p>
<pre><code>find_fspattern (51 รูปแบบ, คำถามไทย/อังกฤษ):
  Jev เลือกทีเดียว           → ถูก 92.9%
  vector อันดับ 1 (แบบเดิม)   → ถูก 71.4%
</code></pre>
<p>Jev ทิ้งอันดับ-1 แบบเดิมขาด และเข้าใกล้เพดาน 100% ที่ปกติต้องพึ่ง LLM มาเลือกซ้ำ — <strong>แต่ทำในครั้งเดียว ไม่ต้องปิงปอง</strong></p>
<h3>เซอร์ไพรส์: เคสที่ "พลาด" ส่วนใหญ่เป็นความผิดของเรา</h3>
<p>ตอนแรกเรามีเคสที่ดูเหมือน Jev พลาด: คำถาม <em>"มูลค่าหุ้นเพิ่มขึ้นเป็นสองเท่า"</em> Jev ตอบผิดเป็น "สูงกว่าค่าอื่น" แทนที่จะเป็น "เติบโตทบต้น" (compound growth)</p>
<p>เกือบโทษ Jev แล้ว — แต่พอไปดู <strong>สิ่งที่เราป้อนให้มัน</strong> เราส่งแค่ "นิยามสั้น" ของแต่ละรูปแบบ ซึ่งนิยามของ compound growth เขียนเน้นแต่ "อัตราต่อปี (CAGR)" ไม่มีคำว่า "เป็นสองเท่า" เลย ทั้งที่ในฐานข้อมูลจริงมีคำอธิบายอีกฟิลด์ที่เขียนชัดว่า <em>"มูลค่าเพิ่มเป็นสองเท่า/สามเท่า"</em></p>
<p><strong>วิธีแก้:</strong> ป้อนคำอธิบายให้ครบเหมือนที่ระบบค้นหาใช้จริง — แก้ปุ๊บ Jev ตอบถูกทันที</p>
<blockquote>
<p>บทเรียนนี้ย้ำสิ่งที่เราเจอตั้งแต่ตอน 2: <strong>ก่อนโทษโมเดล ให้ดูสิ่งที่เราป้อนมันก่อน</strong> เกือบทุกเคสที่ "พลาด" กลายเป็น context ที่เราให้ไม่ครบ หรือเฉลยของเราเองที่แคบเกินไป</p>
</blockquote>
<hr />
<h2>กรณีหัวใจ: candidate เยอะเกินจะยัดหมด — vector + Jev</h2>
<p>นี่คือกรณีที่เกิดบ่อยและสำคัญที่สุด <strong>catalog ส่วนใหญ่ใหญ่เกินกว่าจะยัดทั้งชุดให้ Jev</strong> — ตัวหาแนวคิดงบการเงิน (<code>find_fsconcept</code>) มีถึง <strong>428 รายการ</strong> (บรรทัดงบ + อัตราส่วน + ตัวคูณราคา) ตัวหาหุ้นมีเป็นหมื่น ตัวหาข้อมูลเศรษฐกิจมีเป็นหลักหมื่น</p>
<p>โยนทั้ง 428 ตัวให้ Jev เลือกทีเดียวทำไม่ได้ (ทั้งแพงและเกินขีดจำกัด) แต่เราไม่จำเป็นต้องทิ้งของเดิม — <strong>เอา vector search ที่มีอยู่แล้วมาช่วยกรองก่อน</strong>:</p>
<pre><code>คำดิบ → [vector search กรองเหลือ top-15] → [Jev เลือก 1 จาก 15] → โทเคน
</code></pre>
<p>vector search ทำสิ่งที่มันเก่ง (กรองจากพันเหลือสิบ) Jev ทำสิ่งที่มันเก่ง (เลือกตัวที่ใช่จากสิบ) — <strong>และการเลือกยังอยู่ฝั่งเซิร์ฟเวอร์ ไม่ต้องปิงปองกลับหา LLM</strong></p>
<p><strong>อ่านผล:</strong></p>
<pre><code>find_fsconcept (428 รายการ, คำถามอังกฤษ):
  vector อันดับ 1 (แบบเดิม)         → ถูก 68%
  vector top-15 → Jev เลือก        → ถูก 100%
</code></pre>
<p>Jev แก้ <strong>ทุกเคส</strong> ที่ vector จัดอันดับ 1 ผิด และเป็นเคสยากจริง เช่น:</p>
<ul>
<li>"ผลตอบแทนผู้ถือหุ้น (ROE)" — vector เดาเป็น "เงินปันผลต่อหุ้น" → Jev เลือก <code>roe</code> ถูก</li>
<li>"หนี้ที่มีภาระดอกเบี้ยรวม" — vector เดาเป็น "ดอกเบี้ยค้างจ่าย" → Jev เลือก <code>total_debt</code> ถูก</li>
<li>"งานระหว่างก่อสร้าง", "เงินลงทุนที่ถือจนครบกำหนด", "กำไรขาดทุนเบ็ดเสร็จอื่นสะสม" — ศัพท์บัญชีลึกที่ vector ลอยหมด แต่ Jev เลือกถูก</li>
</ul>
<p>ที่น่าทึ่งกว่าคือมันแยกแยะ "ประเภท" ได้ถูก: <em>"กำไรขั้นต้น"</em> → บรรทัดในงบ (<code>gross_profit</code>) ส่วน <em>"อัตรากำไรขั้นต้น"</em> → อัตราส่วน (<code>gross_margin</code>) — คนละตัวกัน Jev ไม่สับสน</p>
<hr />
<h2>แล้วต้นทุนล่ะ? — vector + Jev ยังถูกกว่า</h2>
<p>หลายคนคงคิดว่าเพิ่ม Jev เข้าไปก็ต้องแพงขึ้นสิ ตรงกันข้าม</p>
<table>
<thead>
<tr>
<th>วิธี</th>
<th>Jev อ่านกี่ตัวเลือก</th>
<th>ต้นทุน / 1,000 ครั้ง</th>
</tr>
</thead>
<tbody><tr>
<td>ยัดทั้ง catalog (51 ตัว)</td>
<td>51</td>
<td>$0.35</td>
</tr>
<tr>
<td><strong>vector กรองก่อน → Jev (10-15 ตัว)</strong></td>
<td>~10</td>
<td><strong>$0.08</strong></td>
</tr>
</tbody></table>
<p>การกรองด้วย vector ก่อน <strong>ถูกลง ~4 เท่า</strong> เพราะต้นทุนหลักของ Jev คือความยาวของตัวเลือกที่ป้อนเข้าไป — อ่าน 10 ตัวย่อมถูกกว่าอ่าน 400 ตัว</p>
<p>แถมค่า embedding ของ vector แทบเป็นศูนย์ เพราะเราเก็บ vector ของคำค้นที่เคยเจอไว้ถาวรอยู่แล้ว (คำค้นซ้ำ = ไม่ต้องคำนวณใหม่) ส่วนตัว Jev เอง — คิดเงินเฉพาะ input, output ฟรี, และถูกกว่า LLM ทั่วไปหลายเท่า</p>
<p><strong>เทียบเป็น round-trip:</strong> จาก <strong>4 รอบ → 1 รอบ</strong> ผู้ใช้ได้คำตอบไวขึ้นชัดเจน และ LLM ฝั่ง client ไม่ต้องเสียสมาธิมานั่งเลือก top-k ทุกคำถาม — มันเอา token ไปคิดเรื่องที่สำคัญกว่าได้ <strong>นี่คือ UX ของ MCP ที่ดีขึ้นจริง</strong></p>
<hr />
<h2>บทเรียนที่ต้องจำ (มีจริง)</h2>
<p>การจะเอาไปใช้จริงต้องซื่อสัตย์กับข้อจำกัด — เราเจอ 4 เรื่อง</p>
<p><strong>1. context ที่ป้อนสำคัญกว่าที่คิด</strong>
เกือบทุกเคสที่ Jev "พลาด" คือเราป้อนคำอธิบายไม่ครบ หรือเฉลยของเราเองแคบเกิน แก้คำอธิบายในฐานข้อมูล = ดีขึ้นทั้งระบบ (ทั้ง vector และ Jev กินคำอธิบายชุดเดียวกัน)</p>
<p><strong>2. "ถามยืนยัน" ต้องฉลาด ไม่งั้นทำลาย UX ที่เพิ่งแก้มา</strong>
บางครั้ง Jev ก็ไม่มั่นใจจริง ๆ — คำถามกำกวมเอง หรือมีตัวเลือกสูสีสองตัว เราออกแบบให้เครื่องมือ <strong>ดู "รูปทรง" ของความมั่นใจ</strong> ไม่ใช่แค่ตัวเลขเดียว:</p>
<ul>
<li>มั่นใจชัด → ใช้เลย</li>
<li>ก้ำกึ่งแต่พอได้ → ตอบไปก่อน พร้อมแนบหมายเหตุว่าตีความยังไง (ไม่บล็อก)</li>
<li>สองตัวสูสีจริง + ต่างกันจริง → <strong>ค่อย</strong>ถามผู้ใช้ยืนยัน (เกิดน้อยมาก)</li>
</ul>
<p>หลักคือ: ถามยืนยันเฉพาะตอนที่ "คำตอบที่ถูกมีอยู่จริงแต่ Jev เลือกไม่ขาด" เท่านั้น ไม่ใช่ถามทุกครั้งที่ไม่มั่นใจ — ไม่งั้นก็กลับไปปิงปองเหมือนเดิม</p>
<p><strong>3. หลายภาษา = ให้แปลเป็นอังกฤษก่อน (และนี่คือข้อจำกัดของ vector ไม่ใช่ Jev)</strong>
เราลองศัพท์บัญชีลึกหลายภาษา เจอว่า <em>"ค่าความนิยม" (goodwill) ภาษาไทย</em> ตกไปอยู่อันดับ 45 ของ vector — หลุด top-15 ไป Jev เลยไม่เห็นให้เลือก ดูเผิน ๆ เหมือน Jev พัง</p>
<p>แต่เราพิสูจน์แล้วว่า <strong>เป็นความอ่อนของ vector (embedding) ข้ามภาษา ไม่ใช่ Jev</strong> — ถ้าถามคำเดียวกันเป็นภาษาอังกฤษ ("goodwill") มันขึ้นอันดับ 1 ทันที Jev เองก็รู้ว่า のれん (ญี่ปุ่น) = goodwill ด้วยซ้ำ</p>
<p>โชคดีที่เครื่องมือ MCP ของเรากำหนดให้ <strong>client แปลเป็นอังกฤษก่อนส่งอยู่แล้ว</strong> — ปัญหานี้จึงไม่เกิดในทางปฏิบัติ</p>
<p><strong>4. เส้นแบ่งบาง ๆ ทางบัญชี — Jev ผ่านสวย</strong>
เราจัดชุดทดสอบโหดสุด: คู่ศัพท์ที่ต่างกันนิดเดียวแต่คนละความหมาย</p>
<table>
<thead>
<tr>
<th>คู่ที่ต้องแยก</th>
<th>Jev แยกออกไหม</th>
</tr>
</thead>
<tbody><tr>
<td>หุ้นทุนซื้อคืน (treasury stock) ↔ การซื้อหุ้นคืน (buybacks)</td>
<td>✅</td>
</tr>
<tr>
<td>ตั้งสำรอง (P&amp;L) ↔ ค่าเผื่อ (งบดุล)</td>
<td>✅</td>
</tr>
<tr>
<td>สินทรัพย์ภาษีรอตัดบัญชี ↔ หนี้สินภาษีรอตัดบัญชี</td>
<td>✅</td>
</tr>
<tr>
<td>หมุนเวียน ↔ ไม่หมุนเวียน</td>
<td>✅</td>
</tr>
<tr>
<td>หนี้มีดอกเบี้ย ↔ หนี้สินรวม ↔ เงินกู้ (ไม่รวมลีส)</td>
<td>✅</td>
</tr>
</tbody></table>
<p><strong>25 คู่โหด — Jev ถูก 100% ด้วยความมั่นใจเฉลี่ย 0.998</strong> เทียบกับ vector อันดับ 1 ที่ถูกแค่ 48% นี่คือจุดที่ห่วงที่สุด (ตอบผิดแบบมั่นใจ) แต่กลับผ่านสบายในภาษาอังกฤษ</p>
<hr />
<h2>สรุป: เมื่อไหร่ควรยุบ resolver ด้วย Jev</h2>
<p>จากที่ลองมา แนวทางที่ชัดคือ:</p>
<ul>
<li><strong>catalog เล็ก (ไม่กี่สิบ):</strong> ให้ Jev เลือกจากทั้งชุดทีเดียว</li>
<li><strong>catalog ใหญ่ (ร้อย/พัน/หมื่น):</strong> ใช้ vector search กรองก่อนเหลือ ~10-15 → ให้ Jev เลือก — <strong>ยังยุบ round-trip และถูกลงพร้อมกัน</strong></li>
<li><strong>มีทางลัด cache:</strong> คำที่เคยแปลแล้ว (เช่น "current assets" → <code>CurrentAssets</code>) เก็บผลไว้ ครั้งต่อไปคืนเลย ไม่ต้องเรียก Jev ซ้ำ</li>
</ul>
<p>ทั้งหมดนี้ทำให้ MCP จาก "ปิงปองสี่รอบต่อคำถาม" เหลือ "รอบเดียว" — เร็วขึ้น ถูกลง และ LLM ฝั่ง client เบาลง</p>
<p><strong>ข้อควรระวัง:</strong> อย่าเพิ่งสลับทั้งหมดในวันเดียว วิธีที่ปลอดภัยคือรัน Jev <strong>คู่ขนาน</strong>กับของเดิมบน traffic จริงสักพัก เทียบผล ดู distribution ของความมั่นใจ แล้วค่อยเปิดทีละส่วน — และเตรียม fallback ไว้เผื่อ Jev ช้าหรือล่ม (เราวัดได้ว่าปกติ ~1 วินาที แต่มี tail ที่พุ่งได้เป็นสิบวินาที)</p>
<p>แต่ทิศทางชัด: <strong>resolver คือ "ภาษี round-trip" ที่ MCP จ่ายทุกคำถาม — Jev ช่วยจ่ายภาษีนั้นแทน</strong> และแม้ candidate จะเยอะแค่ไหน การจับคู่ vector + Jev ก็ยังยุบมันได้ ทั้งเร็วขึ้นและถูกลง</p>
]]></content:encoded></item><item><title><![CDATA[เอา Jev มาทำงานจริง — ผล ต้นทุน และบทเรียน (ตอนที่ 2)]]></title><description><![CDATA[งานที่เราเลือกลอง
MarketDX แปลงข่าวการเงินเป็นกราฟผลกระทบ หัวใจคือขั้นตอน "อ่านข่าวแล้วจัดประเภท + ประเมิน" ที่ยิง ทุกข่าว ที่ไหลเข้ามา — เป็นงาน LLM ที่ volume สูงสุดในระบบ ถ้าแทนได้คือประหยัดก้อนใหญ]]></description><link>https://marketdx.hashnode.dev/putting-jev-to-work-results-cost-and-lessons</link><guid isPermaLink="true">https://marketdx.hashnode.dev/putting-jev-to-work-results-cost-and-lessons</guid><category><![CDATA[jev]]></category><category><![CDATA[AI]]></category><category><![CDATA[llm]]></category><category><![CDATA[Artificial Intelligence]]></category><category><![CDATA[fintech]]></category><dc:creator><![CDATA[Niran Pravithana]]></dc:creator><pubDate>Fri, 18 Sep 2026 09:41:40 GMT</pubDate><content:encoded><![CDATA[<h2>งานที่เราเลือกลอง</h2>
<p>MarketDX แปลงข่าวการเงินเป็นกราฟผลกระทบ หัวใจคือขั้นตอน <strong>"อ่านข่าวแล้วจัดประเภท + ประเมิน"</strong> ที่ยิง <strong>ทุกข่าว</strong> ที่ไหลเข้ามา — เป็นงาน LLM ที่ volume สูงสุดในระบบ ถ้าแทนได้คือประหยัดก้อนใหญ่สุด เราเลยเลือกงานนี้เป็นสนามทดสอบจริง มันประกอบด้วย 4 การตัดสินใจย่อย:</p>
<ol>
<li><p><strong>ประเภทข่าว</strong> (news type) — ข่าวนี้เป็นแนวไหน (earnings / M&amp;A / กฎหมาย / มาโคร / ฯลฯ)</p>
</li>
<li><p><strong>ความสำคัญ</strong> (impact 1–5) — นักลงทุนควรสนใจแค่ไหน</p>
</li>
<li><p><strong>เชื่อมกับธีมการลงทุน</strong> (megatrend) — ข่าวนี้เกี่ยวกับเทรนด์ไหน</p>
</li>
<li><p><strong>รายละเอียดผลกระทบ</strong> — ทิศทาง (บวก/ลบ), ความแรง, ช่องทางที่กระทบ</p>
</li>
</ol>
<p>เราลองทีละส่วน แล้วอ่านผลจริงทุกครั้ง นี่คือเรื่องราวที่เกิดขึ้น</p>
<hr />
<h2>ส่วนที่ 1: ประเภทข่าว — ดีกว่าที่ตัวเลขบอก</h2>
<p>ให้ Jev เลือกประเภทจาก 16 แบบ (Choice) เทียบกับที่ระบบเดิมเคยจัด ผลแรก "ตรงกัน 74%" ดูเหมือนธรรมดา — <strong>แต่พออ่านเคสที่ไม่ตรงจริง ๆ กลับพลิก:</strong></p>
<ul>
<li><p>ส่วนใหญ่ที่ "ไม่ตรง" คือ <strong>เส้นแบ่งที่กำกวมโดยธรรมชาติ</strong> (เช่น "บทวิเคราะห์ปรับราคาเป้า" vs "ปรับประมาณการกำไร") ซึ่ง Jev ก็ตอบได้สมเหตุสมผลพอ ๆ กัน</p>
</li>
<li><p>บางเคส <strong>Jev ถูกกว่า</strong> — ข่าวเดียวกันที่ระบบเดิมจัดคนละประเภทในสองรอบ (ไม่คงเส้นคงวา) Jev จัดเหมือนกันทั้งสองครั้งและตรงเนื้อกว่า</p>
</li>
</ul>
<p><strong>กับดักเดียวที่เจอ:</strong> Jev ไม่ค่อยยอมตอบว่า "ข่าวขยะ/ไม่สำคัญ" (noise) — มันพยายามหาประเภท "จริง ๆ" ให้เสมอ <strong>วิธีแก้: ปรับคำสั่งเชิงนโยบาย</strong> บอกมันว่า "ข่าวขยะเป็นคำตอบปกติ อย่าฝืนยัดประเภทเพราะคำมันตรง" ผลคือ:</p>
<ul>
<li>ทดสอบกับข่าว<strong>ชุดใหม่ที่ไม่เคยเห็น</strong> 45 ชิ้น: จับข่าวขยะได้ <strong>20/20</strong> และ <strong>ไม่มีสักครั้งที่เผลอตีข่าวจริงเป็นขยะ (0/25)</strong></li>
</ul>
<p>บทเรียน: bias ของ Jev แก้ได้ด้วยการปรับ "นโยบาย" ในคำถาม ไม่ต้องยกตัวอย่างป้อน</p>
<hr />
<h2>ส่วนที่ 2: ความสำคัญ (impact) — เจอ bias, แก้ได้, แถมจับ bug ของระบบเดิม</h2>
<p>ถ้าให้ Jev ให้คะแนน 1–5 ตรง ๆ (Score เดียว) มันมี <strong>อคติเกาะกลาง</strong> — เกือบทุกข่าวได้ 3 และ <strong>ไม่เคยให้ 1 (ขยะ) เลย</strong> ใช้เป็น gate คัดกรองไม่ได้</p>
<p><strong>วิธีแก้ที่ได้ผล — แตกเป็นคำถามย่อยแล้วรวมเอง:</strong> แทนที่จะถาม "สำคัญเท่าไร" ทีเดียว เราถามเป็นคำถามใช่/ไม่ใช่หลายตัว (มีข้อมูลใหม่จริงไหม / เป็นเรื่องใหญ่ผิดปกติไหม / เซอร์ไพรส์ไหม / กระทบวงกว้างไหม / เป็นโฆษณา/PR ไหม) แล้ว <strong>เอาคำตอบมาประกอบเป็นคะแนนเองด้วยสูตรที่เราคุมได้</strong> ผลคือคะแนนกระจายสมจริง กลับมาให้ 1 กับข่าวขยะได้ และคัดโฆษณา/สแปมได้แม่น</p>
<p><strong>เซอร์ไพรส์:</strong> ระหว่างทาง Jev <strong>จับ bug ของระบบเดิมได้</strong> — ข่าวผลประกอบการจริงของบริษัทใหญ่ระดับผู้นำอุตสาหกรรม ถูกระบบเดิมตีเป็น "ข่าวสั้น/ไม่สำคัญ" (จากกฎความยาว) แต่ Jev ให้ความสำคัญสูงอย่างถูกต้อง — เป็นหลักฐานชัดว่า "การไม่ไล่ตามของเดิม" คือสิ่งถูกต้อง</p>
<hr />
<h2>ส่วนที่ 3: เชื่อมกับธีมการลงทุน — บทเรียนเรื่อง "บริบท" และ "การไล่จากบนลงล่าง"</h2>
<p>นี่คือส่วนยากสุด: ธีม (megatrend) มี <strong>25 หมวดใหญ่ + ~300 หมวดย่อย 3 ชั้น</strong> และข่าวส่วนใหญ่ <em>ไม่แตะ</em> ธีมไหนเลย</p>
<p><strong>ความพยายามแรกล้มเหลว:</strong> ถามกว้าง ๆ ว่า "ข่าวนี้ขยับธีมไหนไหม" — Jev แยกข่าวที่แตะกับไม่แตะแทบไม่ออก เพราะคำถามนามธรรมเกินไป</p>
<p><strong>สิ่งที่แก้ได้ (2 อย่าง):</strong></p>
<ol>
<li><p><strong>ใส่บริบท ไม่ใช่แค่ชื่อ</strong> — ชื่อธีมสั้น ๆ กำกวม เราจึงแนบคำอธิบาย + ตัวอย่างของแต่ละธีมเข้าไปในคำถามด้วย</p>
</li>
<li><p><strong>ถามเจาะทีละธีม แล้วไล่จากบนลงล่าง</strong> — เลือกหมวดใหญ่ก่อน → เจาะหมวดย่อย → เจาะย่อยลงอีก (แบบ drill-down)</p>
</li>
</ol>
<p>พอทำสองอย่างนี้ ผลพลิกเป็นบวกชัด — <strong>Jev แทบไม่เคยเชื่อมข่าวไปผิดธีมเลย</strong> (ความแม่นสูงมาก)</p>
<p><strong>คำถามเชิง "รสนิยมผลิตภัณฑ์" ที่ต้องตัดสิน:</strong> ควรเชื่อมแบบ "เข้มงวด" (เฉพาะข่าวที่ขยับทั้งธีมจริง ๆ) หรือ "ครอบคลุม" (ข่าวบริษัทใน sector นั้นก็เชื่อมได้)? เราเลือก <strong>"ครอบคลุม แต่ต้องไม่ทำให้คนอ่านแล้ว 'เอ๊ะ'"</strong> พอปรับคำถามตามนี้ Jev ทำได้ตรงเป้า — เชื่อมข่าวที่เข้ากัน (สายการบิน→ธีมการบิน, เหมืองทอง→ธีมวัตถุดิบ) และปฏิเสธที่ขัดตา โดยยังไม่เชื่อมไปผิดธีม</p>
<p><strong>เจาะลงถึงหมวดย่อยชั้นลึก:</strong> เมื่อไล่ลงไปเลือกหมวดย่อยจริง ๆ Jev เลือก <strong>ตรง 80% / อยู่ถูกกลุ่ม 90%</strong> และหลายเคส Jev เจาะได้ <strong>ละเอียด/แม่นกว่าระบบเดิม</strong> (เช่นระบบเดิมหยุดที่ "โลหะมีค่า" แต่ Jev เจาะถึง "ทอง")</p>
<p><strong>รายละเอียดผลกระทบ:</strong> ทิศทาง (บวก/ลบ) และความแรง — ทำได้ดี ส่วน "ช่องทางที่กระทบ" ตอนแรกดูเพี้ยน แต่พบว่าเป็นเพราะเรา <em>ออกแบบผิด</em> — เหตุการณ์หนึ่งกระทบหลายช่องทางพร้อมกัน (นโยบายโซลาร์ = ทั้งเรื่องราคา+ดีมานด์+กฎเกณฑ์) พอเปลี่ยนให้ตอบได้ <strong>หลายช่องทาง (multi-label)</strong> แทนที่จะบังคับเลือกอันเดียว ปัญหาก็หายไป</p>
<hr />
<h2>บทเรียนรวม 4 ข้อ</h2>
<ol>
<li><p><strong>อย่าตัดสิน AI ใหม่ด้วยการวัดว่า "เหมือนของเดิม"</strong> — ของเดิมก็ผิดได้ (เราเจอ Jev จับ bug ระบบเดิมหลายครั้ง) ต้องอ่านผลจริงแล้วตัดสิน</p>
</li>
<li><p><strong>อคติของ Jev แก้ได้ด้วย "นโยบาย" ในคำถาม</strong> — ไม่ต้องยกตัวอย่างป้อน (ซึ่งจะทำให้ผลลวง)</p>
</li>
<li><p><strong>งานที่ซับซ้อน = แตกเป็นคำถามย่อยแล้วประกอบเอง</strong> — ทั้ง impact (แตกเป็นหลาย yes/no) และ megatrend (ไล่จากบนลงล่าง) ได้ผลดีกว่าถามรวดเดียว</p>
</li>
<li><p><strong>ใส่บริบท และยอมให้ตอบได้หลายคำตอบ</strong> เมื่อความจริงเป็นแบบนั้น (ช่องทางผลกระทบ, ประเภทข่าว)</p>
</li>
</ol>
<hr />
<h2>เทียบต้นทุน (ตัวเลขประมาณ, ต่อการตัดสินใจ 1,000 ครั้ง)</h2>
<p>สมมติงานจัดประเภทข่าว 1 ครั้ง ป้อน ~1,200 token ได้คำตอบสั้น ๆ:</p>
<table>
<thead>
<tr>
<th>ทางเลือก</th>
<th>ราคา input</th>
<th>ราคา output</th>
<th><strong>~ต่อ 1,000 ข่าว</strong></th>
</tr>
</thead>
<tbody><tr>
<td>Gemini Flash (LLM กลาง)</td>
<td>~$0.30/M</td>
<td>~$2.50/M</td>
<td><strong>~$0.49</strong></td>
</tr>
<tr>
<td>DeepSeek flash</td>
<td>~$0.14/M</td>
<td>~$0.5/M</td>
<td><strong>~$0.19</strong></td>
</tr>
<tr>
<td>OpenAI nano (ตัวเล็ก)</td>
<td>~$0.10/M</td>
<td>~$0.40/M</td>
<td><strong>~$0.13</strong></td>
</tr>
<tr>
<td><strong>Jev</strong></td>
<td><strong>$0.042/M</strong></td>
<td><strong>ฟรี</strong></td>
<td><strong>~$0.05</strong></td>
</tr>
</tbody></table>
<ul>
<li><p><strong>Jev ถูกสุด</strong> — ประมาณ <strong>3–10 เท่า</strong> เมื่อเทียบกับ LLM ตัวเล็ก/กลาง ส่วนหนึ่งเพราะ output ฟรี (ยิ่งถามหลายคำถามในครั้งเดียว ยิ่งได้เปรียบ)</p>
</li>
<li><p>เทียบกับ <strong>vector embedding</strong> (อีกทางที่ราคาใกล้กัน) — คนละงานกัน: embedding บอกได้แค่ "อะไรคล้ายกัน" ตัดสินใจไม่ได้ ส่วน Jev ตัดสินใจได้เลย แพตเทิร์นที่ดีคือใช้คู่กัน (embedding คัดตัวเลือก → Jev ตัดสิน)</p>
</li>
</ul>
<blockquote>
<p>หมายเหตุ: ราคาเป็นค่าประมาณ ณ ปี 2026 และต้นทุนจริงขึ้นกับความยาว prompt ตัวเลขนี้ไว้ให้เห็น "อันดับความต่าง" ไม่ใช่บัญชีเป๊ะ</p>
</blockquote>
<p><strong>เรื่องความเร็ว:</strong> Jev ~1 วินาทีต่อครั้ง (นาน ๆ ทีมี spike หลายวินาที) — เร็วพอสำหรับงานตัดสินทีละข่าว แต่ <strong>ไม่ควรเอาไปวนลูปกับข้อมูลเป็นล้านตรง ๆ</strong> ควรคัดตัวเลือกด้วยวิธีที่ถูกกว่าก่อน</p>
<hr />
<h2>สรุป: เมื่อไหร่ควรใช้ Jev</h2>
<p><strong>ควรใช้ Jev เมื่อ</strong> งานเป็น "การตัดสินใจ" ที่ชัดเจน (จัดประเภท / ให้คะแนน / ใช่-ไม่ใช่), volume สูง, และต้องการความมั่นใจที่เชื่อถือได้เพื่อใช้เป็น gate — Jev <strong>ถูกกว่า เร็วพอ และคำตอบถูกล็อกให้อยู่ในกรอบ</strong> (สร้างคำตอบพิลึกไม่ได้)</p>
<p><strong>ยังต้องใช้ LLM เมื่อ</strong> งานต้องเขียน อธิบายเหตุผล แปลภาษา หรือคิดหลายขั้น — Jev ทำไม่ได้ และไม่ได้ตั้งใจให้ทำ</p>
<p><strong>ผลรวมจากการทดสอบ:</strong> บนงานจัดประเภท+ประเมินข่าวของ MarketDX ทั้งชุด <strong>Jev ทำได้ดีเท่าหรือดีกว่าระบบ LLM เดิมเกือบทุกจุด</strong> (จัดการข่าวขยะ/โฆษณา, ไม่เชื่อมผิดธีม, เจาะหมวดย่อยแม่น) ที่ต้นทุนถูกกว่าหลายเท่า</p>
<p><strong>ข้อควรระวังก่อนใช้จริง (พูดตามตรง):</strong> ผลทั้งหมดนี้มาจากการที่เรา (ด้วย Claude Opus) อ่านและตัดสินบนตัวอย่างหลักร้อยข่าว — ไม่ใช่ว่าคุณภาพยังไม่ชัด แต่ก่อนจะเปลี่ยนระบบจริงควร <strong>รันคู่ขนานกับของเดิมบน traffic จริงสักพัก</strong> เพื่อยืนยันที่ปริมาณเต็ม เก็บชุดตัวอย่างมาตรฐานไว้เฝ้าคุณภาพ และเผื่อเรื่องความไม่คงที่เล็กน้อยของคำตอบ + spike ความหน่วงนาน ๆ ที</p>
<p>โดยรวม: สำหรับงานตัดสินใจปริมาณมาก <strong>Jev เป็นเครื่องมือที่คุ้มค่าและน่าลงทุนทำต่อ</strong> — ไม่ใช่มาแทน LLM ทั้งหมด แต่มาแทน "ส่วนที่เป็นการตัดสินใจ" ซึ่งจริง ๆ แล้วมีอยู่เยอะกว่าที่คิด</p>
]]></content:encoded></item><item><title><![CDATA[Jev ฉลาดพอไหม? — บททดสอบความสามารถของโมเดล "ตัดสินใจ" (ตอนที่ 1)]]></title><description><![CDATA[Jev คืออะไร?
โมเดล AI ที่เราคุ้นเคย (LLM อย่าง GPT, Claude, Gemini, DeepSeek) ทำงานด้วยการ สร้างข้อความทีละคำ — คุณถาม มันเขียนคำตอบออกมาเป็นประโยค นั่นทรงพลังมากสำหรับงานเขียน สรุป แปล หรือคิดเป็นขั้]]></description><link>https://marketdx.hashnode.dev/is-jev-smart-enough-language-and-world-knowledge</link><guid isPermaLink="true">https://marketdx.hashnode.dev/is-jev-smart-enough-language-and-world-knowledge</guid><category><![CDATA[jev]]></category><category><![CDATA[llm]]></category><category><![CDATA[nlp]]></category><category><![CDATA[Artificial Intelligence]]></category><dc:creator><![CDATA[Niran Pravithana]]></dc:creator><pubDate>Fri, 18 Sep 2026 09:32:25 GMT</pubDate><content:encoded><![CDATA[<h2>Jev คืออะไร?</h2>
<p>โมเดล AI ที่เราคุ้นเคย (LLM อย่าง GPT, Claude, Gemini, DeepSeek) ทำงานด้วยการ <strong>สร้างข้อความทีละคำ</strong> — คุณถาม มันเขียนคำตอบออกมาเป็นประโยค นั่นทรงพลังมากสำหรับงานเขียน สรุป แปล หรือคิดเป็นขั้นตอน</p>
<p>แต่ในซอฟต์แวร์จริง งานจำนวนมากไม่ได้ต้องการ "ข้อความ" — มันต้องการ <strong>การตัดสินใจ</strong>:</p>
<ul>
<li>ข่าวชิ้นนี้เป็นข่าวประเภทไหน?</li>
<li>มันสำคัญระดับไหน (1–5)?</li>
<li>เนื้อหานี้ควรทำต่อ หรือทิ้ง?</li>
</ul>
<p><strong>Jev</strong> (จาก TypeSafe AI) ถูกออกแบบมาเพื่อสิ่งนี้โดยเฉพาะ — มันไม่เขียนข้อความ แต่ <strong>เลือกคำตอบจากตัวเลือกที่เรากำหนด แล้วคืนค่าเป็นคำตอบที่มีชนิดชัดเจน (typed) พร้อมระดับความมั่นใจ (confidence)</strong> ทันที</p>
<p>มันมีคำถามอยู่ 3 แบบเท่านั้น:</p>
<ul>
<li><strong>Choice</strong> — เลือก 1 จากตัวเลือกที่กำหนด (พร้อมความน่าจะเป็นของแต่ละตัว)</li>
<li><strong>Score</strong> — ให้คะแนนตามระดับที่นิยามไว้</li>
<li><strong>Noul</strong> — ใช่/ไม่ใช่ คืนเป็นความน่าจะเป็น 0–1</li>
</ul>
<p>จุดที่น่าสนใจเชิงเศรษฐศาสตร์: <strong>Jev คิดเงินเฉพาะ input ส่วน output ฟรี</strong> และตอบเร็ว (หลัก ~1 วินาที) เพราะมันไม่ต้องไล่เขียนข้อความทีละคำ</p>
<p><strong>คำถามหลักของเราคือ:</strong> โมเดลที่ "ตัดสินใจอย่างเดียว" แบบนี้ มันฉลาด/แม่นพอจะแทนงานที่วันนี้เราใช้ LLM ตัวใหญ่ทำอยู่ไหม? ตอนที่ 1 นี้เราเริ่มจากพื้นฐานที่สุด — <strong>มันเข้าใจภาษาและมีความรู้จริงหรือเปล่า</strong> ก่อนจะไปดูงานจริงในตอนที่ 2</p>
<hr />
<h2>MarketDX ทำอะไร?</h2>
<p>MarketDX เป็นแพลตฟอร์มที่ <strong>แปลงข่าวการเงินเป็นกราฟผลกระทบ</strong> — อ่านข่าวแล้วบอกว่าข่าวนั้นกระทบสินทรัพย์/ธีมการลงทุนตัวไหน ทิศทางบวกหรือลบ และส่งต่อไปยังผู้เล่นที่เกี่ยวข้องอย่างไร เบื้องหลังมีงาน "ตัดสินใจ" แบบนี้อยู่เต็มไปหมด และหลายงานยิงทุกข่าวที่ไหลเข้ามา — ซึ่งแปลว่าถ้าลดต้นทุนต่อการตัดสินใจได้ ผลรวมมหาศาล จึงเป็นเหตุผลที่เราสนใจ Jev</p>
<hr />
<h2>หลักการทดสอบของเรา</h2>
<p>ก่อนดูผล ต้องเข้าใจ 2 กติกาที่เรายึด เพราะมันเปลี่ยนวิธีอ่านผลทั้งหมด:</p>
<p><strong>1. ตัดสินคุณภาพด้วยการ "อ่านเอง" (eyeball) ไม่ใช่ดูว่า "ตรงกับของเดิม"</strong> ของเดิมในระบบเราก็คือ LLM (ซึ่งบางทีก็ผิด) การวัดว่า Jev "ตรงกับ LLM เดิมกี่ %" จึงไม่ได้บอกว่า Jev ดีหรือแย่ — บอกแค่ว่ามันเหมือนของเดิมแค่ไหน เป้าหมายจริงคือ <strong>ให้ดีขึ้น</strong> ไม่ใช่เหมือนเดิม เราจึงอ่านผลลัพธ์จริงแล้วตัดสินเอง</p>
<p><strong>2. เขียนคำถามให้โมเดลแบบไม่ "ใบ้คำตอบ"</strong> เราใส่ "นิยามงาน" ในคำถามได้ (เช่น บอกว่าให้ถือว่าความหมายเดียวกันแม้จะต่างที่ความสุภาพ) แต่เรา <strong>ไม่ใส่ตัวอย่างประโยคที่เฉลยคำตอบ</strong> เพราะนั่นทำให้ผลดูดีเกินจริง</p>
<hr />
<h2>บททดสอบ 1: ภาษา — เข้าใจ "ความหมาย" ข้ามภาษาไหม?</h2>
<p><strong>คำถามที่อยากรู้:</strong> ประโยค <em>"กินข้าวหรือยังครับ"</em> (สุภาพ) กับ <em>"เฮ้ย แดกมายัง"</em> (สแลงหยาบ) — Jev รู้ไหมว่ามันหมายความเดียวกัน? แล้วทำได้กี่ภาษา?</p>
<p><strong>วิธี:</strong> เราสร้างประโยคเองใน <strong>23 ภาษา</strong> (ไทย จีน ญี่ปุ่น อังกฤษ อาหรับ ฮินดี เกาหลี ฮกเกี้ยน ฯลฯ) แต่ละภาษามี 3 แบบ แล้วถาม Jev ว่าคู่ไหน "หมายความเดียวกัน":</p>
<ul>
<li><strong>A vs B</strong> — สุภาพ ↔ สแลง (ความหมายเดียวกัน) → ควรได้คะแนนสูง</li>
<li><strong>A vs N</strong> — คล้ายกันมากแต่เจตนาต่าง (เช่น <em>"กินข้าวมาหรือยัง"</em> [ถาม] vs <em>"กินข้าวมาแล้วเหรอ"</em> [ทวงแบบรู้อยู่แล้ว]) → คลุมเครือ</li>
<li><strong>A vs C</strong> — คนละเรื่อง (<em>"กินข้าวยัง"</em> vs <em>"หิวข้าวยัง"</em>) → ควรได้คะแนนต่ำ</li>
</ul>
<p><strong>ผล (ค่าเฉลี่ยทั้ง 23 ภาษา, คะแนน 0–1):</strong></p>
<table>
<thead>
<tr>
<th>คู่ประโยค</th>
<th>คะแนน "เหมือนกัน"</th>
<th>ตีความ</th>
</tr>
</thead>
<tbody><tr>
<td>สุภาพ ↔ สแลง (เหมือนจริง)</td>
<td><strong>0.89</strong></td>
<td>✅ รู้ว่าเหมือน</td>
</tr>
<tr>
<td>คล้ายแต่เจตนาต่าง</td>
<td><strong>0.64</strong></td>
<td>🟡 ก้ำกึ่ง — ตามที่ควรเป็น</td>
</tr>
<tr>
<td>คนละเรื่อง</td>
<td><strong>0.20</strong></td>
<td>✅ รู้ว่าต่าง</td>
</tr>
</tbody></table>
<p><strong>อ่านผล:</strong> Jev <strong>ไล่ระดับได้ถูก</strong> (เหมือนชัด &gt; ก้ำกึ่ง &gt; ต่าง) เกือบทุกภาษา และทำได้ทั้ง 23 ภาษารวมสแลง — ไม่ใช่เก่งแค่อังกฤษ ที่น่าประทับใจคือมันแยก "หิว" ออกจาก "กินแล้ว" ได้ทั้งที่ประโยคหน้าตาคล้ายกันมาก</p>
<p><strong>จุดอ่อนที่เจอ (มีจริง):</strong></p>
<ul>
<li><strong>ภาษาถิ่นข้อมูลน้อย</strong> (ฮกเกี้ยน) อ่อนสุด — แยกความหมายใกล้ ๆ ได้ไม่คมเท่าภาษาหลัก</li>
<li><strong>สำนวนกำกวม</strong> เช่น "have your tea" ในอังกฤษ (แปลว่ากินมื้อเย็นก็ได้ ดื่มชาก็ได้) — Jev เลือกความหมายตรงตัว</li>
</ul>
<p><strong>เกร็ดที่เจอระหว่างทาง:</strong> เรายิงคำถามเดิมซ้ำ 3 ครั้ง จำนวน token ที่คิดเงินเท่าเดิมทุกครั้ง → <strong>Jev ไม่มีส่วนลดแบบ cache</strong> (ต่างจาก LLM หลายเจ้า) ถ้าจะประหยัดต้องเขียนคำถามให้สั้น หรือรวมหลายคำถามในครั้งเดียว</p>
<hr />
<h2>บททดสอบ 2: ความรู้รอบโลก — ตื้นและลึก</h2>
<p><strong>คำถามที่อยากรู้:</strong> นอกจากเข้าใจภาษา มันมี "ความรู้" จริงไหม ทั้งความรู้ทั่วไปและความรู้เฉพาะทางเชิงลึก?</p>
<p><strong>วิธี:</strong> ข้อสอบปรนัย 4 ตัวเลือก <strong>75 ข้อ</strong> แบ่ง 3 ระดับ × 15 สาขา (บัญชี กฎหมาย การเงิน แพทย์ ฟิสิกส์ ประวัติศาสตร์ ปรัชญา ฯลฯ):</p>
<ul>
<li><strong>ทั่วไป</strong> — ความรู้กว้าง ๆ</li>
<li><strong>ตื้น</strong> — ระดับที่นักศึกษาสาขานั้นควรตอบได้</li>
<li><strong>ลึก</strong> — เฉพาะทางจริง เช่น การลงบัญชีค่า R&amp;D ระหว่างมาตรฐาน IFRS กับ US GAAP, ยุคยาโยยของญี่ปุ่น, Gettier problem ในปรัชญา, ทฤษฎี Modigliani–Miller ทางการเงิน</li>
</ul>
<p>(เราสลับตำแหน่งตัวเลือกทุกข้อ กันไม่ให้เฉลยไปกองอยู่ตัวเลือกเดิม)</p>
<p><strong>ผล:</strong></p>
<table>
<thead>
<tr>
<th>ระดับ</th>
<th>คะแนน</th>
</tr>
</thead>
<tbody><tr>
<td>ทั่วไป</td>
<td>15/15</td>
</tr>
<tr>
<td>ตื้น</td>
<td>30/30</td>
</tr>
<tr>
<td>ลึก</td>
<td>30/30</td>
</tr>
<tr>
<td><strong>รวม</strong></td>
<td><strong>75/75 = 100%</strong></td>
</tr>
</tbody></table>
<p>ความมั่นใจของ Jev เกือบทุกข้อ = ~1.00 และตอบถูกแม้ข้อเชิงลึกเฉพาะทาง</p>
<p><strong>อ่านผลอย่างซื่อสัตย์:</strong> 100% น่าประทับใจ แต่ก็แปลว่า <strong>เรายังหา "เพดาน" ของมันไม่เจอ</strong> — ข้อสอบเชิงลึกของเราถึงจะเฉพาะทาง แต่ก็ยังเป็นความรู้ที่มีในตำรา เรายังไม่ได้ลองความรู้ที่กำกวม/มีข้อถกเถียง หรือโจทย์ที่ต้องใช้เหตุผลหลายชั้น สรุปได้แค่ว่า "ความรู้กว้างและลึกพอ" ไม่ใช่ "ไม่มีขีดจำกัด"</p>
<hr />
<h2>สรุปตอนที่ 1</h2>
<p>สองบททดสอบพื้นฐานนี้ตอบคำถามว่า <strong>"Jev ฉลาดพอไหม"</strong> ได้ค่อนข้างชัด:</p>
<ul>
<li><strong>เข้าใจภาษา/ความหมาย</strong> ข้าม 23 ภาษา รวมสแลงและ register ต่าง ๆ ได้แม่นและไล่ระดับความคล้ายได้จริง</li>
<li><strong>มีความรู้</strong> ทั้งกว้างและลึกในหลายสาขา</li>
<li>เร็ว (~1 วินาที) และคิดเงินเฉพาะ input</li>
</ul>
<p>พอเห็นว่าพื้นฐานแน่น เราจึงกล้าเอาไปลองกับ <strong>งานจริงของ MarketDX</strong> — ซึ่งเป็นเรื่องของ <strong>ตอนที่ 2</strong>: เราเอา Jev ไปแทนงานตัดสินใจที่ยิงทุกข่าว ผลเป็นยังไง เจอกับดักอะไร แก้ยังไง และถ้าเทียบต้นทุนกับ LLM เดิม (DeepSeek / OpenAI / Gemini) มันคุ้มแค่ไหน</p>
]]></content:encoded></item></channel></rss>