1<!DOCTYPE html> 2<html lang="en"> 3 4<head> 5 <meta charset="utf-8"> 6 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 7 <meta name="google-site-verification" content="xBT4GhYoi5qRD5tr338pgPM5OWHHIDR6mNg1a3euekI" /> 8 <meta name="viewport" content="width=device-width, initial-scale=1"> 9 <meta name="theme-color" content="#0f1a26"> 10 11 <!-- 12 Removed: meta name="keywords". Google has ignored it since 2009 and Bing 13 treats it as a spam signal; it was emitting an empty content="" on every 14 page that had no page.keywords, which was almost all of them. 15 --> 16 17 <!-- 18 Crawl directives. 19 20 max-image-preview:large is what lets Google show a full-width image 21 thumbnail in Search and, more importantly, is a prerequisite for Google 22 Discover -- the traffic source that actually matters for a daily brief. 23 max-snippet:-1 removes the snippet length cap. 24 25 Paginated index pages (/page2/ upward) and the client-side search page 26 are listing pages with no content of their own, so they are noindex but 27 still followed, letting crawl equity flow through to the posts they link. 28 The paginator check has to happen here rather than in front matter, 29 because jekyll-paginate clones index.html's front matter onto every 30 paginated page -- there is no way to mark only page 2+ from there. 31 32 NOTE: do not write Liquid tags inside these comments. Liquid runs before 33 the HTML is parsed, so anything in braces here still executes. 34 --><meta name="robots" content="noindex, follow"> 35 36 37 <!-- 38 Title. This used to append site.SEOTitle -- 63 characters of 39 "AI Consultant | Enterprise Agentic AI | Tokenization payment" -- to all 40 ~2,900 page titles. Google routinely rewrites titles that end in a 41 keyword-stuffed brand string, and it pushed every post title past the 42 ~60-character SERP limit. site.title_suffix is now just the brand. 43 --> 44 <title>Search · AISeng Tech</title> 45 46 <!-- 47 Resource hints for the two third parties on the critical path. The 48 AdSense and GA hosts are discovered late (they are async scripts at the 49 end of head), so the TCP + TLS handshake lands in the middle of render. 50 --> 51 <link rel="preconnect" href="https://pagead2.googlesyndication.com" crossorigin> 52 <link rel="preconnect" href="https://www.googletagmanager.com"> 53 <link rel="dns-prefetch" href="https://googleads.g.doubleclick.net"> 54 <link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin> 55 56 <!-- 57 jekyll-seo-tag. It was listed in _config.yml plugins but never invoked, 58 so the plugin did nothing: the site had no og: or twitter: tags at all 59 and shared links previewed bare. 60 61 title=false keeps the hand-written <title> above, so ~2,600 existing 62 page titles are left exactly as they were. Everything else comes from 63 the plugin: description, canonical, og:*, twitter:* and JSON-LD. 64 65 The hand-rolled tags it replaces were removed rather than kept, to 66 avoid emitting each one twice: 67 - meta name="description" was page.title followed by the keywords 68 list, i.e. a keyword list rather than a description. 69 - link rel="canonical" was built from site.url by hand. 70 71 NOTE: do not write Liquid tags in these comments. Liquid runs before 72 the HTML is parsed, so anything in braces here still executes. 73 --> 74 <!-- Begin Jekyll SEO tag v2.8.0 --> 75<meta name="generator" content="Jekyll v3.10.0" /> 76<meta property="og:title" content="Search" /> 77<meta name="author" content="Sheng Gao" /> 78<meta property="og:locale" content="en_US" /> 79<meta name="description" content="Daily briefs and analysis on enterprise agentic AI, fintech and payments, tokenization, and AI governance, plus consulting and development services." /> 80<meta property="og:description" content="Daily briefs and analysis on enterprise agentic AI, fintech and payments, tokenization, and AI governance, plus consulting and development services." /> 81<link rel="canonical" href="https://aisengtech.com/search/" /> 82<meta property="og:url" content="https://aisengtech.com/search/" /> 83<meta property="og:site_name" content="AI-driven Business Transformation Consulting & Development" /> 84<meta property="og:image" content="https://aisengtech.com/image/og-default.jpg" /> 85<meta property="og:type" content="website" /> 86<meta name="twitter:card" content="summary_large_image" /> 87<meta property="twitter:image" content="https://aisengtech.com/image/og-default.jpg" /> 88<meta property="twitter:title" content="Search" />
89<script type="application/ld+json"> 90{"@context":"https://schema.org","@type":"WebPage","author":{"@type":"Person","name":"Sheng Gao"},"description":"Daily briefs and analysis on enterprise agentic AI, fintech and payments, tokenization, and AI governance, plus consulting and development services.","headline":"Search","image":"https://aisengtech.com/image/og-default.jpg","publisher":{"@type":"Organization","logo":{"@type":"ImageObject","url":"https://aisengtech.com/image/logo.png"},"name":"Sheng Gao"},"url":"https://aisengtech.com/search/"}</script>
90 91<!-- End Jekyll SEO tag --> 92 93 94 95 <!-- Web App Manifest --> 96 <!-- <link rel="manifest" href="/pwa/manifest.json"> --> 97 98 <!-- 99 Icon set, all drawn from geometry by _tools/make_logo.py. 100 101 favicon.ico held a single 256x256 image, which left every browser to 102 downscale it to 16px itself -- and browser ICO downscaling is poor. It 103 now embeds 16, 32 and 48 drawn individually at their own optical size: 104 below 32px the nodes of the mark are dropped and the strokes thickened, 105 because at tab size the detailed version goes translucent and the 106 counter inside the A fills in. 107 108 The PNG links come first in preference for browsers that read them; the 109 .ico stays for Windows shortcuts and older clients. rel="shortcut icon" 110 was dropped -- it has never been part of any specification and "icon" 111 alone is what browsers actually match on. 112 113 apple-touch-icon is deliberately opaque with square corners. iOS applies 114 its own rounded mask, so baking corners in produces a double-rounded 115 icon with dark slivers showing at the edges. It previously pointed at a 116 461 KB photograph, then briefly at a 44 KB crop of one; it is now the 117 brand mark at 6.9 KB. 118 119 NOTE: do not write Liquid tags inside these comments. Liquid runs before 120 the HTML is parsed, so anything in braces here still executes. 121 --> 122 <link rel="icon" type="image/png" sizes="32x32" href="/image/favicon-32x32.png"> 123 <link rel="icon" type="image/png" sizes="16x16" href="/image/favicon-16x16.png"> 124 <link rel="icon" href="/image/favicon.ico" sizes="any"> 125 <link rel="apple-touch-icon" sizes="180x180" href="/image/apple-touch-icon.png"> 126 127 <!-- Canonical URL is emitted by the seo tag above, from site.url + page.url --> 128 129 <!-- Bootstrap Core CSS --> 130 <link rel="stylesheet" href="/css/bootstrap.min.css"> 131 132 <!-- Custom CSS --> 133 <link rel="stylesheet" href="/css/hux-blog.min.css"> 134 135 <!-- Additions layered on the theme; see css/enhancements.css --> 136 <link rel="stylesheet" href="/css/enhancements.css"> 137 138 <!-- Pygments Github CSS --> 139 <link rel="stylesheet" href="/css/syntax.css"> 140 141 <!-- Custom Fonts --> 142 <!-- <link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet" type="text/css"> --> 143 <!-- Hux change font-awesome CDN to qiniu --> 144 <link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" type="text/css"> 145 146 147 <!-- Hux Delete, sad but pending in China 148 <link href='http://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic' rel='stylesheet' type='text/css'> 149 <link href='http://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/ 150 css'> 151 --> 152 153 154 <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> 155 <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> 156 <!--[if lt IE 9]> 157
157<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
157 158
158<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
158 159 <![endif]--> 160 161 <!-- 162 Google Analytics 4 and AdSense. 163 164 Both are now gated on jekyll.environment. GitHub Pages builds with 165 JEKYLL_ENV=production; a local `jekyll serve` does not. Before this 166 gate, every local preview at 127.0.0.1:4000 sent page_view hits to the 167 live GA property, so the numbers used to judge traffic and ad 168 performance included the author's own development sessions. 169 170 The IDs are read from _config.yml rather than hard-coded here, so there 171 is one place to change them and the gate cannot be bypassed by 172 forgetting one of the two copies. 173 174 NOTE: do not write Liquid tags inside these comments. Liquid runs before 175 the HTML is parsed, so anything in braces here still executes. 176 --> 177 178 179<!-- Google tag (gtag.js) -->
vendor: 64 bytes, lines 179-180
179 180<script async src="https://www.googletagmanager.com/gtag/js?id=
180G-KTDMZH87NL
vendor: 12 bytes, line 180
180"></script>
181<script> 182
vendor: 133 bytes, lines 182-185
182window.dataLayer = window.dataLayer || []; 183 function gtag(){dataLayer.push(arguments);} 184 gtag('js', new Date()); 185 gtag('config', '
185G-KTDMZH87NL
vendor: 4 bytes, line 185
185');
186</script>
186 187 188 189
190<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-8709587192438304" 191 crossorigin="anonymous"></script>
191 192 193 194 195<!-- 196 Ad slots do not belong here in <head>. What used to sit at this spot was a 197 commented-out slot element plus a bare push call, and the push could only 198 ever throw: it ran before any slot existed in the document. 199 200 In-article slots now live in _layouts/post.html, where each <ins> is 201 immediately followed by its own push. See the comment there. 202--> 203
204<script async custom-element="amp-auto-ads" 205 src="https://cdn.ampproject.org/v0/amp-auto-ads-0.1.js"> 206</script>
206 207 208</head> 209 210 211<!-- hack iOS CSS :active style --> 212<body ontouchstart=""> 213<amp-auto-ads type="adsense" 214 data-ad-client="ca-pub-8709587192438304"> 215</amp-auto-ads> 216 217
218<script type="module"> 219 import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs"; 220 221 mermaid.initialize({ 222 startOnLoad: false, 223 securityLevel: "loose", 224 theme: "default" 225 }); 226 227 document.addEventListener("DOMContentLoaded", async () => { 228 document.querySelectorAll("pre code.language-mermaid").forEach((code) => { 229 const pre = code.parentElement; 230 const div = document.createElement("div"); 231 232 div.className = "mermaid"; 233 div.textContent = code.textContent; 234 235 pre.replaceWith(div); 236 }); 237 238 await mermaid.run({ 239 querySelector: ".mermaid" 240 }); 241 }); 242</script>
242 243 244 <!-- Navigation --> 245<nav class="navbar navbar-default navbar-custom navbar-fixed-top"> 246 <div class="container-fluid"> 247 <!-- Brand and toggle get grouped for better mobile display --> 248 <div class="navbar-header page-scroll"> 249 <button type="button" class="navbar-toggle"> 250 <span class="sr-only">Toggle navigation</span> 251 <span class="icon-bar"></span> 252 <span class="icon-bar"></span> 253 <span class="icon-bar"></span> 254 </button> 255 <a class="navbar-brand" href="/">AISeng Tech</a> 256 257 </div> 258 259 <!-- Collect the nav links, forms, and other content for toggling --> 260 <div id="huxblog_navbar"> 261 <div class="navbar-collapse"> 262 <ul class="nav navbar-nav navbar-right"> 263 <li> 264 <a href="/">Home</a> 265 </li> 266 267 <li> 268 <a href="/series/">Series</a> 269 </li> 270 271 <li> 272 <a href="/tags/">Tags</a> 273 </li> 274 275 <li> 276 <a href="/about/">About</a> 277 </li> 278 279 <li> 280 <a href="/products&services/">Services</a> 281 </li> 282 283 <li class="active"> 284 <a href="/search/">Search</a> 285 </li> 286 287 <li> 288 <a href="/resume/">CV</a> 289 </li> 290 291 </ul> 292 </div> 293 </div> 294 <!-- /.navbar-collapse --> 295 </div> 296 <!-- /.container --> 297</nav>
298<script> 299 // Drop Bootstarp low-performance Navbar 300 // Use customize navbar with high-quality material design animation 301 // in high-perf jank-free CSS3 implementation 302 var $body = document.body; 303 var $toggle = document.querySelector('.navbar-toggle'); 304 var $navbar = document.querySelector('#huxblog_navbar'); 305 var $collapse = document.querySelector('.navbar-collapse'); 306 307 var __HuxNav__ = { 308 close: function(){ 309 $navbar.className = " "; 310 // wait until animation end. 311 setTimeout(function(){ 312 // prevent frequently toggle 313 if($navbar.className.indexOf('in') < 0) { 314 $collapse.style.height = "0px" 315 } 316 },400) 317 }, 318 open: function(){ 319 $collapse.style.height = "auto" 320 $navbar.className += " in"; 321 } 322 } 323 324 // Bind Event 325 $toggle.addEventListener('click', function(e){ 326 if ($navbar.className.indexOf('in') > 0) { 327 __HuxNav__.close() 328 }else{ 329 __HuxNav__.open() 330 } 331 }) 332 333 /** 334 * Since Fastclick is used to delegate 'touchstart' globally 335 * to hack 300ms delay in iOS by performing a fake 'click', 336 * Using 'e.stopPropagation' to stop 'touchstart' event from 337 * $toggle/$collapse will break global delegation. 338 * 339 * Instead, we use a 'e.target' filter to prevent handler 340 * added to document close HuxNav. 341 * 342 * Also, we use 'click' instead of 'touchstart' as compromise 343 */ 344 document.addEventListener('click', function(e){ 345 if(e.target == $toggle) return; 346 if(e.target.className == 'icon-bar') return; 347 __HuxNav__.close(); 348 }) 349</script>
349 350 351 352 <div style="max-width: 800px; margin: 40px auto; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;"> 353 <h1>Search the Site</h1> 354 <input type="text" id="search-input" placeholder="Type to search..." style="width: 100%; padding: 12px; font-size: 1rem; border: 1px solid #ddd; border-radius: 6px; margin-bottom: 30px;" autocomplete="off" /> 355 356 <div id="search-results"> 357 <p id="result-count" style="font-weight: bold; margin-bottom: 10px;"></p> 358 <ul id="results-list" style="list-style: none; padding: 0; margin: 0;"></ul> 359 </div> 360</div> 361 362<!-- Load Lunr.js from CDN -->
363<script src="https://cdn.jsdelivr.net/npm/[email protected]/lunr.min.js"></script>
363 364
365<script> 366document.addEventListener('DOMContentLoaded', function() { 367 const searchInput = document.getElementById('search-input'); 368 const resultList = document.getElementById('results-list'); 369 const resultCount = document.getElementById('result-count'); 370 371 // Load search index â safe for subdirectory sites 372 fetch('/search-data.json') 373 .then(response => { 374 if (!response.ok) throw new Error('Network response was not ok'); 375 return response.json(); 376 }) 377 .then(data => { 378 // Build Lunr index 379 const idx = lunr(function () { 380 this.ref('id'); 381 this.field('title', { boost: 20 }); 382 this.field('content', { boost: 5 }); 383 this.field('url'); 384 385 data.index.forEach(doc => { 386 this.add(doc); 387 }); 388 }); 389 390 // Map ID back to original document 391 const documents = {}; 392 data.index.forEach(doc => { 393 documents[doc.id] = doc; 394 }); 395 396 // Handle search 397 searchInput.addEventListener('keyup', function() { 398 const query = this.value.trim(); 399 resultList.innerHTML = ''; 400 resultCount.textContent = ''; 401 402 if (!query) return; 403 404 const results = idx.search(query); 405 resultCount.textContent = `${results.length} result(s) found`; 406 407 if (results.length === 0) { 408 resultList.innerHTML = '<li style="padding: 12px; color: #666;">No results found. Try another keyword.</li>'; 409 return; 410 } 411 412 results.forEach(result => { 413 const doc = documents[result.ref]; 414 const li = document.createElement('li'); 415 li.style.padding = '12px 0'; 416 li.style.borderBottom = '1px solid #eee'; 417 418 const a = document.createElement('a'); 419 a.href = doc.url; 420 a.innerHTML = `<strong>${doc.title}</strong>`; 421 a.style.textDecoration = 'none'; 422 a.style.color = '#0366d6'; 423 a.style.display = 'block'; 424 a.style.marginBottom = '4px'; 425 426 const excerpt = document.createElement('p'); 427 excerpt.textContent = doc.content.substring(0, 150) + '...'; 428 excerpt.style.color = '#555'; 429 excerpt.style.fontSize = '0.9rem'; 430 excerpt.style.margin = '0'; 431 432 li.appendChild(a); 433 li.appendChild(excerpt); 434 resultList.appendChild(li); 435 }); 436 }); 437 }) 438 .catch(err => { 439 console.error('Failed to load search index:', err); 440 resultList.innerHTML = '<li style="color: red;">â ï¸ Search index failed to load. Check console for details.</li>'; 441 }); 442}); 443</script>
443 444 445 <!-- Footer --> 446<footer> 447 <div class="container"> 448 <div class="row"> 449 <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1"> 450 451 <ul class="list-inline text-center footer-links"> 452 453 <li><a href="/resume/">Resume</a></li> 454 455 <li><a href="/privacy/">Privacy</a></li> 456 457 <li><a href="/series/">All series</a></li> 458 </ul> 459 460 <ul class="list-inline text-center"> 461 <!-- add jianshu add target = "_blank" to <a> by BY --> 462 463 464 465 <!-- add linkedin by Hux, add target = "_blank" to <a> by Hux --> 466 467 468 469 470 471 472 <li> 473 <a target="_blank" href="https://www.linkedin.com/in/dlsheng"> 474 <span class="fa-stack fa-lg"> 475 <i class="fa fa-circle fa-stack-2x"></i> 476 <i class="fa fa-linkedin fa-stack-1x fa-inverse"></i> 477 </span> 478 </a> 479 </li> 480 481 482 <li> 483 <a target="_blank" href="https://github.com/aigaosheng"> 484 <span class="fa-stack fa-lg"> 485 <i class="fa fa-circle fa-stack-2x"></i> 486 <i class="fa fa-github fa-stack-1x fa-inverse"></i> 487 </span> 488 </a> 489 </li> 490 491 </ul> 492 <p class="copyright text-muted"> 493 Copyright © AISeng Tech 2026 494 <br> 495 Theme on <a href="https://github.com/aigaosheng/aigaosheng.github.io.git">GitHub</a> | 496 <iframe 497 style="margin-left: 2px; margin-bottom:-5px;" 498 frameborder="0" scrolling="0" width="100px" height="20px" 499 src="https://ghbtns.com/github-btn.html?user=aigaosheng&repo=aigaosheng.github.io&type=star&count=true" > 500 </iframe> 501 </p> 502 </div> 503 </div> 504 </div> 505</footer> 506 507<!-- jQuery -->
508<script src="/js/jquery.min.js "></script>
508 509 510<!-- Bootstrap Core JavaScript -->
511<script src="/js/bootstrap.min.js "></script>
511 512 513<!-- Custom Theme JavaScript -->
514<script src="/js/hux-blog.min.js "></script>
514 515 516<!-- Service Worker --> 517<!-- 518
519<script type="text/javascript"> 520 if(navigator.serviceWorker){ 521 // For security reasons, a service worker can only control the pages that are in the same directory level or below it. That's why we put sw.js at ROOT level. 522 navigator.serviceWorker 523 .register('/sw.js') 524 .then((registration) => {console.log('Service Worker Registered. ', registration)}) 525 .catch((error) => {console.log('ServiceWorker registration failed: ', error)}) 526 } 527</script>
527 528 529--> 530 531<!-- async load function -->
532<script> 533 function async(u, c) { 534 var d = document, t = 'script', 535 o = d.createElement(t), 536 s = d.getElementsByTagName(t)[0]; 537 o.src = u; 538 if (c) { o.addEventListener('load', function (e) { c(null, e); }, false); } 539 s.parentNode.insertBefore(o, s); 540 } 541</script>
541 542 543<!-- 544 Because of the native support for backtick-style fenced code blocks 545 right within the Markdown is landed in Github Pages, 546 From V1.6, There is no need for Highlight.js, 547 so Huxblog drops it officially. 548 549 - https://github.com/blog/2100-github-pages-now-faster-and-simpler-with-jekyll-3-0 550 - https://help.github.com/articles/creating-and-highlighting-code-blocks/ 551 - https://github.com/jneen/rouge/wiki/list-of-supported-languages-and-lexers 552--> 553<!-- 554
554<script> 555 async("http://cdn.bootcss.com/highlight.js/8.6/highlight.min.js", function(){ 556 hljs.initHighlightingOnLoad(); 557 }) 558 </script>
558 559 <link href="http://cdn.bootcss.com/highlight.js/8.6/styles/github.min.css" rel="stylesheet"> 560--> 561 562 563<!-- jquery.tagcloud.js -->
564<script> 565 // only load tagcloud.js in tag.html 566 if($('#tag_cloud').length !== 0){ 567 async('/js/jquery.tagcloud.js',function(){ 568 $.fn.tagcloud.defaults = { 569 //size: {start: 1, end: 1, unit: 'em'}, 570 color: {start: '#bbbbee', end: '#0085a1'}, 571 }; 572 $('#tag_cloud a').tagcloud(); 573 }) 574 } 575</script>
575 576 577<!--fastClick.js -->
578<script> 579 async("//cdnjs.cloudflare.com/ajax/libs/fastclick/1.0.6/fastclick.min.js", function(){ 580 var $nav = document.querySelector("nav"); 581 if($nav) FastClick.attach($nav); 582 }) 583</script>
583 584 585 586<!-- Google Analytics --> 587 588 589 590<!-- Baidu Tongji --> 591 592 593 594 595<!-- Side Catalog --> 596 597 598 599 600 601 602<!-- 603 Removed: a 461 KB <img src="/image/rawa-sun-falling3.jpg" width="0" height="0"> 604 inherited from the upstream Hux theme to seed WeChat share thumbnails. 605 It downloaded half a megabyte on every pageview and rendered nothing. 606 Use an og:image meta tag instead (see _includes/head.html). 607--> 608<!-- 609 The commented-out AdSense loader and slot push that used to sit here were 610 removed rather than left in place. Commented markup still ships to every 611 reader, and this copy also contradicted the live one: it duplicated the 612 loader from _includes/head.html and pushed a slot that does not exist at 613 this point in the document. 614 615 The loader now lives once, in _includes/head.html, behind a production 616 check. Ad slots live in _layouts/post.html via _includes/ad-unit.html, 617 each with its own push directly after its own element. 618--> 619 620</body> 621 622</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.