Spaces:
Running
Running
File size: 121,956 Bytes
aa2fa98 b862123 5353b52 b862123 5353b52 b862123 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 20fb169 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 5353b52 aa2fa98 6f5a2d9 20fb169 aa2fa98 7ef4e5d aa2fa98 20fb169 aa2fa98 02445d7 aa2fa98 02445d7 aa2fa98 02445d7 aa2fa98 d71e1c6 f2e9595 d71e1c6 f2e9595 d71e1c6 f2e9595 aa2fa98 02445d7 aa2fa98 f2e9595 d71e1c6 f2e9595 d71e1c6 f2e9595 d71e1c6 fe78116 b862123 754a296 fbc4f27 6f5a2d9 b862123 5353b52 b862123 6f5a2d9 b862123 d66fa71 6f5a2d9 d531da9 6f5a2d9 d531da9 6f5a2d9 d531da9 6f5a2d9 d531da9 6f5a2d9 d531da9 6f5a2d9 d531da9 6f5a2d9 b862123 d66fa71 d531da9 d66fa71 aa2fa98 d531da9 aa2fa98 b862123 aa2fa98 b862123 aa2fa98 02445d7 aa2fa98 ad93154 b862123 aa2fa98 02445d7 aa2fa98 20fb169 aa2fa98 20fb169 aa2fa98 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 | <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>InferRoute Academic & Technical Documentation Hub</title>
<!-- Outfit & Inter Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Outfit:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<!-- MathJax for rendering LaTeX formulas -->
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<!-- Mermaid JS for sequence diagrams -->
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>
mermaid.initialize({
startOnLoad: true,
theme: 'default',
themeVariables: {
background: '#FFFFFF',
primaryColor: '#6D28D9',
primaryTextColor: '#0F172A',
lineColor: '#475569',
secondaryColor: '#047857',
tertiaryColor: '#D97706'
}
});
</script>
<style>
:root {
--bg-color: #F8FAFC;
--panel-bg: rgba(255, 255, 255, 0.9);
--border-color: rgba(0, 0, 0, 0.08);
--text-primary: #0F172A;
--text-secondary: #475569;
--accent-violet: #6D28D9;
--accent-violet-glow: rgba(109, 40, 217, 0.08);
--accent-emerald: #047857;
--accent-emerald-glow: rgba(4, 120, 87, 0.08);
--accent-amber: #F59E0B;
--accent-rose: #B91C1C;
--font-outfit: 'Outfit', sans-serif;
--font-inter: 'Inter', sans-serif;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bg-color);
color: var(--text-primary);
font-family: var(--font-inter);
overflow-x: hidden;
line-height: 1.6;
}
/* ── Header ── */
header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1.5rem 2rem;
background: rgba(255, 255, 255, 0.85);
backdrop-filter: blur(12px);
border-bottom: 1px solid var(--border-color);
position: sticky;
top: 0;
z-index: 100;
}
.logo-section {
display: flex;
align-items: center;
gap: 0.75rem;
}
.logo-text {
font-family: var(--font-outfit);
font-size: 1.6rem;
font-weight: 800;
background: linear-gradient(135deg, #0F172A 30%, var(--accent-violet) 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.badge {
font-size: 0.75rem;
font-weight: 600;
padding: 0.25rem 0.75rem;
border-radius: 9999px;
background: var(--accent-violet-glow);
border: 1px solid rgba(109, 40, 217, 0.2);
color: var(--accent-violet);
letter-spacing: 0.5px;
}
.actions {
display: flex;
gap: 1rem;
}
.btn {
font-family: var(--font-inter);
font-size: 0.85rem;
font-weight: 500;
padding: 0.5rem 1rem;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 0.35rem;
}
.btn-outline {
background: transparent;
border: 1px solid var(--border-color);
color: var(--text-primary);
}
.btn-outline:hover {
background: rgba(0, 0, 0, 0.03);
border-color: rgba(0, 0, 0, 0.2);
}
.btn-primary {
background: var(--accent-violet);
border: 1px solid var(--accent-violet);
color: var(--text-primary);
box-shadow: 0 4px 12px rgba(139, 92, 246, 0.25);
}
.btn-primary:hover {
transform: translateY(-1px);
box-shadow: 0 6px 16px rgba(139, 92, 246, 0.35);
}
/* ── Container ── */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 2.5rem 1.5rem;
}
/* ── Hero ── */
.hero {
text-align: center;
margin-bottom: 3.5rem;
}
.hero h1 {
font-family: var(--font-outfit);
font-size: 2.8rem;
font-weight: 800;
margin-bottom: 1rem;
letter-spacing: -1px;
line-height: 1.2;
background: linear-gradient(to right, #0F172A, var(--accent-violet));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.hero p {
font-size: 1.1rem;
color: var(--text-secondary);
max-width: 700px;
margin: 0 auto;
}
/* ── Navigation Tabs ── */
.tabs-nav {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 0.75rem;
margin-bottom: 2.5rem;
background: rgba(0, 0, 0, 0.02);
border: 1px solid var(--border-color);
padding: 0.5rem;
border-radius: 12px;
}
.tab-btn {
font-family: var(--font-outfit);
background: transparent;
border: none;
color: var(--text-secondary);
padding: 0.75rem;
font-size: 0.95rem;
font-weight: 600;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s;
display: flex;
justify-content: center;
align-items: center;
gap: 0.5rem;
}
.tab-btn:hover {
color: var(--text-primary);
background: rgba(0, 0, 0, 0.03);
}
.tab-btn.active {
color: var(--text-primary);
background: var(--accent-violet);
box-shadow: 0 4px 12px rgba(139, 92, 246, 0.2);
}
/* ── Content Layout ── */
.tab-content {
display: none;
animation: fadeIn 0.4s ease;
}
.tab-content.active {
display: block;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
/* ── Glass Cards ── */
.glass-card {
background: var(--panel-bg);
backdrop-filter: blur(12px);
border: 1px solid var(--border-color);
border-radius: 16px;
padding: 2rem;
margin-bottom: 2rem;
box-shadow: 0 10px 30px rgba(0,0,0,0.05);
}
.glass-card h2 {
font-family: var(--font-outfit);
font-size: 1.8rem;
font-weight: 700;
margin-bottom: 1.25rem;
display: flex;
align-items: center;
gap: 0.5rem;
color: var(--text-primary);
}
.card-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1.5rem;
margin-top: 1.5rem;
}
.sub-card {
background: rgba(0, 0, 0, 0.02);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 1.5rem;
transition: all 0.3s;
}
.sub-card:hover {
border-color: rgba(109, 40, 217, 0.25);
background: rgba(109, 40, 217, 0.01);
}
.sub-card h3 {
font-family: var(--font-outfit);
font-size: 1.2rem;
font-weight: 600;
margin-bottom: 0.75rem;
color: var(--text-primary);
}
.formula-box {
background: rgba(0, 0, 0, 0.02);
border-radius: 8px;
padding: 1rem;
margin: 1rem 0;
border: 1px solid var(--border-color);
display: flex;
justify-content: center;
align-items: center;
}
/* ── Step Tracker Sequence ── */
.lifecycle-container {
display: flex;
flex-direction: column;
gap: 1rem;
margin-top: 1.5rem;
}
.lifecycle-step {
display: flex;
gap: 1.5rem;
padding: 1.25rem;
background: rgba(0, 0, 0, 0.02);
border: 1px solid var(--border-color);
border-radius: 12px;
align-items: flex-start;
position: relative;
transition: all 0.3s;
}
.lifecycle-step:hover {
transform: translateX(5px);
background: rgba(109, 40, 217, 0.02);
border-color: rgba(109, 40, 217, 0.15);
}
.step-num {
background: var(--accent-violet-glow);
border: 1px solid rgba(109, 40, 217, 0.3);
color: var(--accent-violet);
width: 32px;
height: 32px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
font-weight: 700;
font-family: var(--font-outfit);
flex-shrink: 0;
}
.step-info h4 {
font-family: var(--font-outfit);
font-size: 1.1rem;
color: var(--text-primary);
margin-bottom: 0.25rem;
}
.step-info p {
font-size: 0.9rem;
color: var(--text-secondary);
}
/* ── Tables ── */
table {
width: 100%;
border-collapse: collapse;
margin-top: 1rem;
font-size: 0.9rem;
}
th, td {
padding: 0.85rem 1rem;
text-align: left;
border-bottom: 1px solid var(--border-color);
}
th {
font-family: var(--font-outfit);
font-weight: 600;
color: var(--text-primary);
background: rgba(0, 0, 0, 0.02);
}
tr:hover td {
background: rgba(255, 255, 255, 0.01);
}
.highlight-emerald {
color: var(--accent-emerald);
font-weight: 600;
}
.highlight-violet {
color: var(--accent-violet);
font-weight: 600;
}
/* ── Live Cascade Simulator ── */
.simulator-box {
background: rgba(0, 0, 0, 0.01);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 1.5rem;
margin-top: 1.5rem;
}
.sim-controls {
display: grid;
grid-template-columns: 2fr 1fr 1fr;
gap: 1rem;
margin-bottom: 1.5rem;
align-items: center;
}
.sim-slider-container {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.sim-slider-label {
font-size: 0.85rem;
color: var(--text-secondary);
display: flex;
justify-content: space-between;
}
input[type="range"] {
-webkit-appearance: none;
width: 100%;
height: 6px;
background: rgba(0, 0, 0, 0.08);
border-radius: 3px;
outline: none;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 16px;
height: 16px;
background: var(--accent-violet);
border-radius: 50%;
cursor: pointer;
box-shadow: 0 0 8px var(--accent-violet);
transition: transform 0.2s;
}
input[type="range"]::-webkit-slider-thumb:hover {
transform: scale(1.2);
}
select {
background: rgba(0, 0, 0, 0.03);
border: 1px solid var(--border-color);
border-radius: 8px;
color: var(--text-primary);
padding: 0.6rem;
outline: none;
font-family: var(--font-inter);
cursor: pointer;
}
/* Simulator Stepper Steps */
.sim-steps-wrapper {
position: relative;
margin: 2rem 0;
display: flex;
flex-direction: column;
gap: 1.5rem;
}
.sim-step-node {
display: flex;
gap: 1.25rem;
padding: 1rem;
border-radius: 10px;
border: 1px dashed var(--border-color);
background: rgba(0,0,0,0.01);
align-items: center;
opacity: 0.5;
transition: all 0.4s;
}
.sim-step-node.active {
opacity: 1;
border-style: solid;
border-color: var(--accent-violet);
box-shadow: 0 0 15px rgba(109, 40, 217, 0.08);
background: rgba(109, 40, 217, 0.01);
}
.sim-step-node.accepted {
opacity: 1;
border-style: solid;
border-color: var(--accent-emerald);
box-shadow: 0 0 15px rgba(4, 120, 87, 0.08);
background: rgba(4, 120, 87, 0.01);
}
.sim-step-node.escalated {
opacity: 0.75;
border-style: solid;
border-color: var(--accent-rose);
background: rgba(220, 38, 38, 0.01);
}
.sim-icon {
width: 36px;
height: 36px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
background: rgba(0,0,0,0.03);
font-size: 1.1rem;
}
.sim-step-node.active .sim-icon {
background: var(--accent-violet-glow);
color: var(--accent-violet);
border: 1px solid var(--accent-violet);
animation: pulse-violet-glow 1.5s infinite;
}
.sim-step-node.accepted .sim-icon {
background: var(--accent-emerald-glow);
color: var(--accent-emerald);
border: 1px solid var(--accent-emerald);
}
.sim-step-node.escalated .sim-icon {
background: rgba(239, 68, 68, 0.1);
color: var(--accent-rose);
border: 1px solid var(--accent-rose);
}
@keyframes pulse-violet-glow {
0% { box-shadow: 0 0 0 0 rgba(139, 92, 246, 0.4); }
70% { box-shadow: 0 0 0 6px rgba(139, 92, 246, 0); }
100% { box-shadow: 0 0 0 0 rgba(139, 92, 246, 0); }
}
.node-details {
flex-grow: 1;
}
.node-name {
font-family: var(--font-outfit);
font-weight: 700;
font-size: 1rem;
color: var(--text-primary);
display: flex;
justify-content: space-between;
}
.node-output {
font-size: 0.85rem;
color: var(--text-secondary);
margin-top: 0.2rem;
font-family: monospace;
}
.node-badge {
font-size: 0.75rem;
font-weight: 600;
padding: 0.1rem 0.5rem;
border-radius: 4px;
background: rgba(0,0,0,0.03);
}
.sim-step-node.accepted .node-badge {
background: var(--accent-emerald-glow);
color: var(--accent-emerald);
}
.sim-step-node.escalated .node-badge {
background: rgba(239, 68, 68, 0.1);
color: var(--accent-rose);
}
.sim-console {
background: rgba(0, 0, 0, 0.03);
font-family: monospace;
font-size: 0.85rem;
padding: 1rem;
border-radius: 8px;
border: 1px solid var(--border-color);
color: #0369A1;
max-height: 120px;
overflow-y: auto;
margin-top: 1rem;
}
/* ── Paper summary details ── */
details.paper-summary-details {
margin-top: 1rem;
padding-top: 0.75rem;
border-top: 1px dashed var(--border-color);
}
details.paper-summary-details summary {
font-family: var(--font-outfit);
font-size: 0.85rem;
font-weight: 600;
color: var(--accent-violet);
cursor: pointer;
outline: none;
user-select: none;
}
details.paper-summary-details[open] summary {
margin-bottom: 0.75rem;
}
.paper-summary-content {
font-size: 0.85rem;
color: var(--text-secondary);
line-height: 1.6;
}
.paper-summary-content h5 {
font-family: var(--font-outfit);
color: var(--text-primary);
margin-top: 0.85rem;
margin-bottom: 0.35rem;
font-size: 0.9rem;
font-weight: 700;
}
.paper-summary-content p {
margin-bottom: 0.5rem;
}
.paper-summary-content code {
background: rgba(0,0,0,0.03);
padding: 0.1rem 0.3rem;
border-radius: 4px;
font-family: monospace;
font-size: 0.8rem;
color: var(--accent-violet);
}
.paper-summary-content pre {
background: rgba(0,0,0,0.03);
padding: 0.5rem;
border-radius: 6px;
font-family: monospace;
font-size: 0.8rem;
overflow-x: auto;
margin: 0.5rem 0;
border: 1px solid var(--border-color);
}
/* ── Playground Styles ── */
.playground-grid {
display: grid;
grid-template-columns: 1.3fr 0.7fr;
gap: 1.5rem;
margin-top: 1.5rem;
}
.playground-main-panel {
background: rgba(15, 23, 42, 0.95);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 16px;
display: flex;
flex-direction: column;
height: 600px;
overflow: hidden;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
color: #E2E8F0;
}
.playground-header {
padding: 1rem 1.5rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
display: flex;
justify-content: space-between;
align-items: center;
background: rgba(30, 41, 59, 0.5);
}
.playground-controls {
display: flex;
gap: 0.75rem;
align-items: center;
}
.playground-select {
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
color: #F8FAFC;
padding: 0.4rem 0.75rem;
border-radius: 8px;
font-size: 0.8rem;
outline: none;
cursor: pointer;
}
.playground-select option {
background: #0F172A;
color: #F8FAFC;
}
.playground-chat-history {
flex: 1;
padding: 1.5rem;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 1rem;
background: rgba(15, 23, 42, 0.5);
}
.playground-bubble {
max-width: 80%;
padding: 0.85rem 1.1rem;
border-radius: 12px;
font-size: 0.9rem;
line-height: 1.5;
}
.playground-bubble.user {
background: #6D28D9;
color: #FFFFFF;
align-self: flex-end;
border-bottom-right-radius: 2px;
}
.playground-bubble.assistant {
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.08);
color: #E2E8F0;
align-self: flex-start;
border-bottom-left-radius: 2px;
}
.playground-input-row {
padding: 1rem 1.25rem;
border-top: 1px solid rgba(255, 255, 255, 0.1);
display: flex;
gap: 0.75rem;
background: rgba(30, 41, 59, 0.3);
}
.playground-textarea {
flex: 1;
background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(255, 255, 255, 0.1);
color: #F8FAFC;
padding: 0.75rem;
border-radius: 8px;
font-size: 0.9rem;
outline: none;
resize: none;
height: 44px;
}
.playground-send-btn {
background: #6D28D9;
color: white;
border: none;
padding: 0 1.25rem;
border-radius: 8px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s;
}
.playground-send-btn:hover {
background: #7C3AED;
box-shadow: 0 0 10px rgba(124, 58, 237, 0.4);
}
.playground-sidebar {
display: flex;
flex-direction: column;
gap: 1.25rem;
}
.playground-wallet {
background: var(--panel-bg);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 1rem 1.25rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.playground-wallet-recharge {
background: var(--accent-emerald-glow);
border: 1px solid var(--accent-emerald);
color: var(--accent-emerald);
padding: 0.25rem 0.5rem;
border-radius: 4px;
font-size: 0.75rem;
cursor: pointer;
font-weight: 600;
}
.playground-metrics-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 0.75rem;
}
.playground-metric-card {
background: var(--panel-bg);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 1rem;
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.playground-metric-label {
font-size: 0.75rem;
color: var(--text-secondary);
font-weight: 500;
}
.playground-metric-val {
font-size: 1.3rem;
font-weight: 700;
color: var(--text-primary);
}
.playground-pipeline {
background: var(--panel-bg);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 1.25rem;
flex: 1;
display: flex;
flex-direction: column;
gap: 1rem;
}
.playground-pipeline-flow {
display: flex;
flex-direction: column;
gap: 0.85rem;
position: relative;
padding-left: 1.25rem;
border-left: 2px dashed var(--border-color);
margin-left: 6px;
}
.playground-pipeline-step {
font-size: 0.8rem;
opacity: 0.4;
transition: all 0.3s;
position: relative;
}
.playground-pipeline-step::before {
content: '';
width: 8px;
height: 8px;
background: var(--text-secondary);
border-radius: 50%;
position: absolute;
left: -19px;
top: 5px;
}
.playground-pipeline-step.active {
opacity: 1;
color: var(--accent-violet);
font-weight: 600;
}
.playground-pipeline-step.active::before {
background: var(--accent-violet);
box-shadow: 0 0 8px var(--accent-violet);
}
.playground-pipeline-step.success {
opacity: 1;
color: var(--accent-emerald);
}
.playground-pipeline-step.success::before {
background: var(--accent-emerald);
}
/* ── PDF / Print Styles ── */
@media print {
body {
background: #FFF;
color: #000;
}
header, .tabs-nav, .actions, .simulator-box, .btn {
display: none !important;
}
.container {
max-width: 100%;
padding: 0;
}
.tab-content {
display: block !important;
opacity: 1 !important;
page-break-after: always;
}
.glass-card {
background: none !important;
border: none !important;
box-shadow: none !important;
padding: 0;
margin-bottom: 3rem;
}
.glass-card h2, .sub-card h3, .step-info h4 {
color: #000 !important;
}
.sub-card {
background: none !important;
border: 1px solid #DDD !important;
}
th {
background: #EEE !important;
color: #000 !important;
}
td {
border-bottom: 1px solid #DDD !important;
}
}
</style>
</head>
<body>
<header>
<div class="logo-section">
<span class="logo-text">InferRoute</span>
<span class="badge">Technical Docs</span>
</div>
<div class="actions">
<a href="https://github.com/ypeng12/InferRoute" target="_blank" class="btn btn-outline">
<span>🐙</span> GitHub
</a>
<button class="btn btn-outline" onclick="window.print()">
<span>🖨️</span> Export PDF
</button>
<a href="/" class="btn btn-primary">
<span>⚡</span> Playground
</a>
</div>
</header>
<div class="container">
<!-- Hero Section -->
<div class="hero">
<h1>Academic Research & Mathematical Foundations</h1>
<p>InferRoute is built upon robust theoretical frameworks for cost-performance trade-offs and multi-tier cascading inference.</p>
</div>
<!-- Navigation Tabs -->
<div class="tabs-nav">
<button class="tab-btn active" onclick="switchTab(event, 'foundations')">
<span>🔍</span> Foundations
</button>
<button class="tab-btn" onclick="switchTab(event, 'architecture')">
<span>🏗️</span> Architecture
</button>
<button class="tab-btn" onclick="switchTab(event, 'benchmarks')">
<span>📊</span> Benchmarks
</button>
<button class="tab-btn" onclick="switchTab(event, 'self-healing')">
<span>🛡️</span> Self-Healing
</button>
<button class="tab-btn" onclick="switchTab(event, 'playground')">
<span>🎮</span> Playground Sandbox
</button>
</div>
<!-- Tab 1: Foundations -->
<div id="foundations" class="tab-content active">
<!-- FrugalGPT Card -->
<div class="glass-card">
<h2>🔄 FrugalGPT: LLM Cascades & Prompt Adaptation</h2>
<p>Derived from the paper <em>"FrugalGPT: How to Use Large Language Models While Reducing Cost and Improving Performance"</em> (Chen et al., Stanford University, 2023), InferRoute implements three key cost-saving mechanics:</p>
<div class="card-grid">
<div class="sub-card">
<h3>1. Prompt Adaptation</h3>
<p>Prunes long prompt histories or few-shot example prefixes down to at most 1 context example when querying cheap local models (Ollama/vLLM), restoring full complexity only when cascading to commercial endpoints.</p>
</div>
<div class="sub-card">
<h3>2. LLM Approximation (Redis Cache)</h3>
<p>Uses standard Redis completion caches. Matches queries in under 10ms, avoiding upstream model fees completely for exact duplicate concurrent prompts.</p>
</div>
</div>
<div class="card-grid" style="margin-top: 1.5rem;">
<div class="sub-card">
<h3>3. Sequential LLM Cascade</h3>
<p>Sequentially routes queries through a chain of backends (Ollama ➔ vLLM ➔ Gemini ➔ OpenAI). A Reliability Judge assesses output quality at each tier, escalating to the next tier if the quality score falls below \(\tau\).</p>
</div>
<div class="sub-card">
<h3>4. Streaming Cascade Buffer Heuristics</h3>
<p>Buffers SSE stream chunks server-side to detect infinite loops or gibberish outputs. Speculatively cancels degraded local streams and escalates to premium cloud nodes mid-stream to avoid client-facing disruptions.</p>
</div>
</div>
<!-- Academic Breakdown: FrugalGPT Cascading Core Logic -->
<div class="sub-card" style="margin-top: 1.5rem; background: rgba(109, 40, 217, 0.02); border-color: rgba(109, 40, 217, 0.15); display: flex; gap: 1rem; align-items: flex-start;">
<span style="font-size: 1.5rem;">📄</span>
<div>
<h4 style="font-family: var(--font-outfit); font-weight: 700; color: var(--accent-violet); margin-bottom: 0.25rem;">Theoretical Framework: Model Cascading & Optimization</h4>
<p style="font-size: 0.9rem; color: var(--text-secondary); line-height: 1.6;">
The FrugalGPT framework models cost-performance optimization as a decision sequence under cost bounds. By arranging models in ascending order of cost and capabilities (e.g., \(M_1, M_2, \dots, M_k\)), the system routes the query sequentially. For each model \(M_j\), the response is validated by a specialized quality assessor (Reliability Judge). If the response quality satisfies the threshold (\(Q(M_j, x) \ge \tau\)), the generation stops, avoiding subsequent cloud execution fees. Otherwise, the request escalates to the next model tier, guaranteeing response quality while keeping average costs minimal.
</p>
</div>
</div>
<!-- Live Cascade Simulator Box -->
<div class="simulator-box">
<h3>🎛️ Interactive Cascade Simulator</h3>
<p style="font-size: 0.85rem; color: var(--text-secondary); margin-bottom: 1rem;">Adjust the sliding acceptance threshold \(\tau\) and click Simulate to trace the sequential escalation path.</p>
<div class="sim-controls">
<div class="sim-slider-container">
<div class="sim-slider-label">
<span>Acceptance Threshold (\(\tau\)):</span>
<span id="simTauVal" style="font-weight:600; color:#C084FC;">0.60</span>
</div>
<input type="range" id="simTauSlider" min="0" max="1" step="0.05" value="0.60" oninput="updateSimTau(this.value)">
</div>
<select id="simQueryType">
<option value="math">Math Equation (5x - 15 = 20)</option>
<option value="code">Python Coding Prompt (def sort...)</option>
<option value="greeting">Simple Greeting (Hello!)</option>
</select>
<button class="btn btn-primary" onclick="runSimulation()" style="justify-content:center; padding: 0.65rem 1rem;">
Simulate Cascade
</button>
</div>
<div class="sim-steps-wrapper">
<!-- Step 1: Ollama -->
<div class="sim-step-node" id="simNode_ollama">
<div class="sim-icon">1</div>
<div class="node-details">
<div class="node-name">
<span>OLLAMA (Tier 1 - Cheap Local)</span>
<span class="node-badge" id="simBadge_ollama">Pending</span>
</div>
<div class="node-output" id="simOutput_ollama">Waiting to run...</div>
</div>
</div>
<!-- Step 2: vLLM -->
<div class="sim-step-node" id="simNode_vllm">
<div class="sim-icon">2</div>
<div class="node-details">
<div class="node-name">
<span>vLLM (Tier 2 - Mid Local)</span>
<span class="node-badge" id="simBadge_vllm">Pending</span>
</div>
<div class="node-output" id="simOutput_vllm">Waiting to run...</div>
</div>
</div>
<!-- Step 3: OpenAI -->
<div class="sim-step-node" id="simNode_openai">
<div class="sim-icon">3</div>
<div class="node-details">
<div class="node-name">
<span>OPENAI (Tier 3 - Premium Cloud)</span>
<span class="node-badge" id="simBadge_openai">Pending</span>
</div>
<div class="node-output" id="simOutput_openai">Waiting to run...</div>
</div>
</div>
</div>
<div class="sim-console" id="simConsole">
System ready. Click "Simulate Cascade" to start.
</div>
</div>
</div>
<!-- RouterBench Card -->
<div class="glass-card">
<h2>🧠 RouterBench: Mathematical Optimization</h2>
<p>Based on the paper <em>"RouterBench: A Benchmark for Multi-LLM Routing System"</em> (Li et al., Martian, 2024), InferRoute structures content-aware models using standard cost-quality constraints.</p>
<div class="sub-card" style="margin-bottom: 1.5rem;">
<h3>1. The Utility Score Formula</h3>
<p>The routing engine maximizes target utility for prompt \(x\) by selecting backend \(m\):</p>
<div class="formula-box">
\[\text{Score}(m, x) = \lambda \cdot \text{Quality}_{\text{pred}}(m, x) - \text{Cost}(m)\]
</div>
<p style="font-size: 0.85rem; color: var(--text-secondary);">
Here, \(\lambda\) is the cost-quality trade-off parameter (willingness-to-pay), \(\text{Quality}_{\text{pred}}\) is the predicted model quality score (0.0 to 1.0), and \(\text{Cost}(m)\) represents model API execution fees.
</p>
</div>
<div class="card-grid">
<div class="sub-card">
<h3>2. Routing Curve Metric (AIQ)</h3>
<p>To evaluate a routing policy globally across budgets, we calculate the **AIQ (Area under the cost-quality curve)** using the Trapezoidal Rule:</p>
<div class="formula-box" style="font-size: 0.85rem;">
\[\text{AIQ} = \int_{c_{\min}}^{c_{\max}} Q(c) \, dc \approx \sum_{i=0}^{n-1} \frac{q_i + q_{i+1}}{2} \cdot (c_{i+1} - c_i)\]
</div>
</div>
<div class="sub-card">
<h3>3. Supported Routing Policies</h3>
<p>InferRoute implements six distinct routing strategies matching the RouterBench & FrugalGPT frameworks:</p>
<div style="display: flex; flex-direction: column; gap: 0.65rem; margin-top: 0.75rem; font-size: 0.85rem; color: var(--text-secondary);">
<div><strong style="color: var(--text-primary);">🎲 Zero Router Baseline (zero):</strong> Non-content-aware routing. Randomly routes requests to Cloud vs. Local backends based on a target mixture ratio \(p \in [0, 1]\) to form the baseline cost-quality curve.</div>
<div><strong style="color: var(--text-primary);">📋 Rule-Based Router (rule):</strong> Content-aware heuristics. Evaluates prompt keywords (e.g., routing math tasks to GPT/Gemini, coding tasks to local vLLM, simple greetings to Ollama).</div>
<div><strong style="color: var(--text-primary);">🧠 KNN-Based Router (knn):</strong> Jaccard nearest-neighbor lookup on historical runs. Finds the \(K\) most similar prompts, averages their quality, and maximizes the score equation.</div>
<div><strong style="color: var(--text-primary);">🕸️ MLP-Based Router (mlp):</strong> A fast logistic regression classifier extracting features (length, code, math, JSON) to predict model success rates and select the highest-scoring backend.</div>
<div><strong style="color: var(--text-primary);">🔮 Oracle Router (oracle):</strong> Theoretical optimal offline reference that has perfect knowledge of outcomes and chooses the cheapest backend that achieves a quality score \(\ge 0.8\).</div>
<div><strong style="color: var(--text-primary);">🔄 Cascade Router (cascade):</strong> FrugalGPT-style sequential escalation. Triggers cascading hops across model tiers if the reliability judge output score falls below threshold \(\tau\).</div>
</div>
</div>
</div>
</div>
<!-- Academic Breakdown: RouterBench Optimization Framework -->
<div class="sub-card" style="margin-top: 1.5rem; background: rgba(109, 40, 217, 0.02); border-color: rgba(109, 40, 217, 0.15); display: flex; gap: 1rem; align-items: flex-start; margin-bottom: 2rem;">
<span style="font-size: 1.5rem;">📄</span>
<div>
<h4 style="font-family: var(--font-outfit); font-weight: 700; color: var(--accent-violet); margin-bottom: 0.25rem;">Theoretical Framework: Cost-Quality Optimization Frontier</h4>
<p style="font-size: 0.9rem; color: var(--text-secondary); line-height: 1.6;">
The RouterBench framework models LLM selection as a multi-objective optimization problem. By defining the parameter \(\lambda\) (cost-quality trade-off coefficient), the scoring equation evaluates the economic utility of selecting a model \(m\) for a prompt \(x\). The parameter \(\lambda\) represents a user's willingness-to-pay: setting a higher \(\lambda\) prioritizes response quality, while a lower \(\lambda\) emphasizes cost savings. The Area under the cost-quality curve (AIQ) measures the cumulative routing performance across all budget constraints, serving as a unified metric for evaluating routing efficiency.
</p>
</div>
</div>
<div class="glass-card" style="margin-top: 2rem;">
<h2>📚 Original Research Papers & Reference Hub</h2>
<p>Read and preview the full research publications associated with this routing engine directly in your browser:</p>
<div class="paper-grid" style="display: grid; grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); gap: 1.5rem; margin-top: 1.5rem;">
<!-- Paper 1 -->
<div class="sub-card" style="display: flex; flex-direction: column; padding: 1.5rem; background: rgba(0, 0, 0, 0.02); border: 1px solid var(--border-color); border-radius: 12px; color: var(--text-primary);">
<span style="font-size: 1.5rem; margin-bottom: 0.5rem;">📄</span>
<span style="font-family: var(--font-outfit); font-weight: 700; font-size: 1.1rem; color: var(--text-primary); margin-bottom: 0.25rem;">FrugalGPT Paper</span>
<span style="font-size: 0.8rem; color: var(--text-secondary); margin-bottom: 0.75rem;">How to Use Large Language Models While Reducing Cost and Improving Performance (Stanford, 2023)</span>
<a href="article/How_to_Use_Large_Language_Models.pdf" target="_blank" style="align-self: flex-start; background: rgba(139, 92, 246, 0.15); border: 1px solid rgba(109, 40, 217, 0.2); color: var(--accent-violet); font-size: 0.75rem; font-weight: 600; padding: 0.25rem 0.65rem; border-radius: 6px; text-decoration: none; display: inline-flex; align-items: center; gap: 0.25rem; margin-bottom: 0.75rem;">Read / Preview PDF</a>
<details class="paper-summary-details">
<summary>查看学术综述 (Paper Summary)</summary>
<div class="paper-summary-content">
<h5>🔍 研究背景</h5>
<p>商业大模型单次调用费用昂贵,而开源/小尺寸模型(如 Llama、GPT-3.5)极其便宜但准确率参差不齐。本论文提出通过调度低成本模型并搭配判定机制,以在保留高准确率的同时大幅削减总费用。</p>
<h5>📐 数学建模与公式</h5>
<p><strong>级联模型 (Cascade Decision):</strong> 设定模型序列 \((M_1, M_2, \dots, M_k)\) 以及质量评估器 \(J: \text{Response} \to [0, 1]\)。</p>
<p>对于请求 \(x\),系统依次生成 \(y_i = M_i(x)\),若 \(J(y_i) \ge \tau\)(接受度阈值),则立刻终止级联返回,否则 escalation 到下一级。</p>
<h5>📊 实验结论</h5>
<p>相比直接调用 GPT-4,FrugalGPT 可降低高达 90% 的总账单,并指出小模型无法有效吸收冗长上下文,提示词裁剪至关重要。</p>
<h5>⚙️ Codebase 集成落地</h5>
<p>级联选路运行在 <a href="file:///c:/Users/pengy/OneDrive/Desktop/InferRoute/inferroute/main.py">main.py</a> 的级联流中,裁剪在 <a href="file:///c:/Users/pengy/OneDrive/Desktop/InferRoute/inferroute/prompt_adapter.py">prompt_adapter.py</a>,评分判定运行在 <a href="file:///c:/Users/pengy/OneDrive/Desktop/InferRoute/inferroute/validator.py">validator.py</a>。</p>
</div>
</details>
</div>
<!-- Paper 2 -->
<div class="sub-card" style="display: flex; flex-direction: column; padding: 1.5rem; background: rgba(0, 0, 0, 0.02); border: 1px solid var(--border-color); border-radius: 12px; color: var(--text-primary);">
<span style="font-size: 1.5rem; margin-bottom: 0.5rem;">📄</span>
<span style="font-family: var(--font-outfit); font-weight: 700; font-size: 1.1rem; color: var(--text-primary); margin-bottom: 0.25rem;">RouterBench Paper</span>
<span style="font-size: 0.8rem; color: var(--text-secondary); margin-bottom: 0.75rem;">A Benchmark for Multi-LLM Routing System (Martian, 2024)</span>
<a href="article/A_Benchmark_for_Multi_LLM_Routing_System.pdf" target="_blank" style="align-self: flex-start; background: rgba(139, 92, 246, 0.15); border: 1px solid rgba(109, 40, 217, 0.2); color: var(--accent-violet); font-size: 0.75rem; font-weight: 600; padding: 0.25rem 0.65rem; border-radius: 6px; text-decoration: none; display: inline-flex; align-items: center; gap: 0.25rem; margin-bottom: 0.75rem;">Read / Preview PDF</a>
<details class="paper-summary-details">
<summary>查看学术综述 (Paper Summary)</summary>
<div class="paper-summary-content">
<h5>🔍 研究背景</h5>
<p>大模型路由逐步多样化,但缺乏标准化的评估基准和数学框架来对比不同路由器在性价比上的优劣。</p>
<h5>📐 数学建模与公式</h5>
<p><strong>效用评分公式:</strong> \(S(m, x) = \lambda \cdot Q_{\text{pred}}(m, x) - C(m)\),其中 \(\lambda\) 代表用户的支付意愿系数,\(Q\) 代表模型的质量预测,\(C\) 代表计费成本。</p>
<p><strong>AIQ 曲线下面积积分:</strong> \(\text{AIQ} = \int_{c_{\min}}^{c_{\max}} Q(c) \, dc\),衡量在各种预算曲线下的全局选路表现。</p>
<h5>📊 实验结论</h5>
<p>引入预测型 MLP 路由器相比静态概率分配(Zero Router)可提升整体 AIQ 达 15% 以上。Oracle 决策上限揭示了路由组合的潜能。</p>
<h5>⚙️ Codebase 集成落地</h5>
<p>效用评分与路由在 <a href="file:///c:/Users/pengy/OneDrive/Desktop/InferRoute/inferroute/router.py">router.py</a> 中的 KNN/MLP 选路策略中运行,帕累托分析和 AIQ 计算在 <a href="file:///c:/Users/pengy/OneDrive/Desktop/InferRoute/benchmarks/plot_results.py">plot_results.py</a>。</p>
</div>
</details>
</div>
<!-- Paper 3 -->
<div class="sub-card" style="display: flex; flex-direction: column; padding: 1.5rem; background: rgba(0, 0, 0, 0.02); border: 1px solid var(--border-color); border-radius: 12px; color: var(--text-primary);">
<span style="font-size: 1.5rem; margin-bottom: 0.5rem;">📄</span>
<span style="font-family: var(--font-outfit); font-weight: 700; font-size: 1.1rem; color: var(--text-primary); margin-bottom: 0.25rem;">Hybrid LLM Routing Paper</span>
<span style="font-size: 0.8rem; color: var(--text-secondary); margin-bottom: 0.75rem;">Hybrid LLM: Cost-Efficient and Quality-Aware Query Routing (IBM / Tsinghua, 2024)</span>
<a href="article/cost_efficiency.pdf" target="_blank" style="align-self: flex-start; background: rgba(139, 92, 246, 0.15); border: 1px solid rgba(109, 40, 217, 0.2); color: var(--accent-violet); font-size: 0.75rem; font-weight: 600; padding: 0.25rem 0.65rem; border-radius: 6px; text-decoration: none; display: inline-flex; align-items: center; gap: 0.25rem; margin-bottom: 0.75rem;">Read / Preview PDF</a>
<details class="paper-summary-details">
<summary>查看学术综述 (Paper Summary)</summary>
<div class="paper-summary-content">
<h5>🔍 研究背景</h5>
<p>解决企业在拥有高并发免费本地小模型群(Edge)与计费的云端强模型(Cloud)时,如何实现高可用混合选路,减少多级判定带来的 TTFT 耗时。</p>
<h5>📐 数学建模与公式</h5>
<p><strong>难度分类器 (Difficulty Estimator):</strong> \(D(x) = \text{Classifier}(x) \in \{0, 1\}\),直接判定请求难易度并直达目标模型,强调一击即中。</p>
<h5>📊 实验结论</h5>
<p>中等体量分类器能以 85% 以上精度区分复杂度。能够降低多达 40% 的平均网络往返延迟,节约超 60% 费用。</p>
<h5>⚙️ Codebase 集成落地</h5>
<p>在 <a href="file:///c:/Users/pengy/OneDrive/Desktop/InferRoute/inferroute/learned_router.py">learned_router.py</a> 中实现了提取 prompt 任务特质(数学、代码等)的特征估计和直达策略分流。</p>
</div>
</details>
</div>
<!-- Paper 4 -->
<div class="sub-card" style="display: flex; flex-direction: column; padding: 1.5rem; background: rgba(0, 0, 0, 0.02); border: 1px solid var(--border-color); border-radius: 12px; color: var(--text-primary);">
<span style="font-size: 1.5rem; margin-bottom: 0.5rem;">📄</span>
<span style="font-family: var(--font-outfit); font-weight: 700; font-size: 1.1rem; color: var(--text-primary); margin-bottom: 0.25rem;">RouteLLM Paper</span>
<span style="font-size: 0.8rem; color: var(--text-secondary); margin-bottom: 0.75rem;">Learning to Route LLMs with Preference Data (LMSYS / Berkeley, ICLR 2025)</span>
<a href="article/RouteLLM_Preference_Data.pdf" target="_blank" style="align-self: flex-start; background: rgba(139, 92, 246, 0.15); border: 1px solid rgba(109, 40, 217, 0.2); color: var(--accent-violet); font-size: 0.75rem; font-weight: 600; padding: 0.25rem 0.65rem; border-radius: 6px; text-decoration: none; display: inline-flex; align-items: center; gap: 0.25rem; margin-bottom: 0.75rem;">Read / Preview PDF</a>
<details class="paper-summary-details">
<summary>查看学术综述 (Paper Summary)</summary>
<div class="paper-summary-content">
<h5>🔍 研究背景</h5>
<p>针对写作、创意、日常对话等缺乏唯一标准解的任务,探讨如何利用大模型竞技场(Chatbot Arena)产生的人类真实偏好对战数据训练二分类器。</p>
<h5>📐 数学建模与公式</h5>
<p><strong>偏好对战概率 (Bradley-Terry Extension):</strong> \(P(M_{\text{strong}} \succ M_{\text{cheap}} \mid x) = \sigma(f(x))\),通过交叉熵损失优化预测。概率大于阈值 \(\theta\) 时上报强模型,否则分流至便宜模型。</p>
<h5>📊 实验结论</h5>
<p>在 Arena 上能在维持 GPT-4 95% 满意度的同时,缩减 50% API 费用,并验证了轻量级分类网络的优越性。</p>
<h5>⚙️ Codebase 集成落地</h5>
<p>概率选路决策与阈值判定借鉴了该设计(<a href="file:///c:/Users/pengy/OneDrive/Desktop/InferRoute/inferroute/router.py">router.py</a>),拟在后续工作中引入专门的偏好二分类预测器 `preference_router.py`。</p>
</div>
</details>
</div>
<!-- Paper 5 -->
<div class="sub-card" style="display: flex; flex-direction: column; padding: 1.5rem; background: rgba(0, 0, 0, 0.02); border: 1px solid var(--border-color); border-radius: 12px; color: var(--text-primary);">
<span style="font-size: 1.5rem; margin-bottom: 0.5rem;">📄</span>
<span style="font-family: var(--font-outfit); font-weight: 700; font-size: 1.1rem; color: var(--text-primary); margin-bottom: 0.25rem;">EquiRouter Paper</span>
<span style="font-size: 0.8rem; color: var(--text-secondary); margin-bottom: 0.75rem;">When Routing Collapses: On Degenerate Convergence (Lai & Ye, 2026)</span>
<a href="article/When_Routing_Collapses.pdf" target="_blank" style="align-self: flex-start; background: rgba(139, 92, 246, 0.15); border: 1px solid rgba(109, 40, 217, 0.2); color: var(--accent-violet); font-size: 0.75rem; font-weight: 600; padding: 0.25rem 0.65rem; border-radius: 6px; text-decoration: none; display: inline-flex; align-items: center; gap: 0.25rem; margin-bottom: 0.75rem;">Read / Preview PDF</a>
<details class="paper-summary-details">
<summary>查看学术综述 (Paper Summary)</summary>
<div class="paper-summary-content">
<h5>🔍 研究背景</h5>
<p>指出当存在 3 个以上候选模型池时,传统的 MSE 回归训练机制会导致在高预算(大 \(\lambda\))时决策权坍缩,强制全选最昂贵模型。</p>
<h5>📐 数学建模与公式</h5>
<p><strong>决策感知排序损失 (Decision-Aware Ranking Loss):</strong></p>
<p>\(\mathcal{L}_{\text{rank}} = -\sum_{i \ne j} \log \sigma \Big( \big(\text{Utility}(M_i, x) - \text{Utility}(M_j, x)\big) \cdot \mathbb{I}(M_i \succ M_j) \Big)\),强调学习两模型效用之差,维持边界决策概率。</p>
<h5>📊 实验结论</h5>
<p>EquiRouter 成功解决回归多分类塌陷问题,在同等质量下,高预算区间多降低 17% 开销。</p>
<h5>⚙️ Codebase 集成落地</h5>
<p>网关对效用归一化进行了放塌陷微调。未来将在 `benchmarks/train_router.py` 中直接换用此排名损失函数进行优化。</p>
</div>
</details>
</div>
<!-- Paper 6 -->
<div class="sub-card" style="display: flex; flex-direction: column; padding: 1.5rem; background: rgba(0, 0, 0, 0.02); border: 1px solid var(--border-color); border-radius: 12px; color: var(--text-primary);">
<span style="font-size: 1.5rem; margin-bottom: 0.5rem;">📄</span>
<span style="font-family: var(--font-outfit); font-weight: 700; font-size: 1.1rem; color: var(--text-primary); margin-bottom: 0.25rem;">R2-Router Paper</span>
<span style="font-size: 0.8rem; color: var(--text-secondary); margin-bottom: 0.75rem;">R2-Router: A New Paradigm for LLM Routing with Reasoning (ICML 2026)</span>
<a href="article/R2_Router_Reasoning.pdf" target="_blank" style="align-self: flex-start; background: rgba(139, 92, 246, 0.15); border: 1px solid rgba(109, 40, 217, 0.2); color: var(--accent-violet); font-size: 0.75rem; font-weight: 600; padding: 0.25rem 0.65rem; border-radius: 6px; text-decoration: none; display: inline-flex; align-items: center; gap: 0.25rem; margin-bottom: 0.75rem;">Read / Preview PDF</a>
<details class="paper-summary-details">
<summary>查看学术综述 (Paper Summary)</summary>
<div class="paper-summary-content">
<h5>🔍 研究背景</h5>
<p>大模型调用费用大多由生成字数决定。若不设防生成字数,大模型输出的冗长答复会极大地蚕食路由的成本红利。</p>
<h5>📐 数学建模与公式</h5>
<p><strong>联合寻优公式:</strong> \(\max_{m, L} \left[ \text{Quality}(m, x, L) - \lambda \cdot \text{Cost}(m, L) \right]\),其中 \(L\) 代表限制最大输出 token 字数。</p>
<h5>📊 实验结论</h5>
<p>常识问答和提取任务在缩短字数后质量维持原样,这为输出开销带来了 4-5 倍的缩减,显著加快了端到端流式接收。</p>
<h5>⚙️ Codebase 集成落地</h5>
<p>在 <a href="file:///c:/Users/pengy/OneDrive/Desktop/InferRoute/inferroute/prompt_adapter.py">prompt_adapter.py</a> 中实现了动态提示词注入与长度自适应,根据模型档次调整 payload `max_tokens` 参数。</p>
</div>
</details>
</div>
<!-- Paper 7 -->
<div class="sub-card" style="display: flex; flex-direction: column; padding: 1.5rem; background: rgba(0, 0, 0, 0.02); border: 1px solid var(--border-color); border-radius: 12px; color: var(--text-primary);">
<span style="font-size: 1.5rem; margin-bottom: 0.5rem;">📄</span>
<span style="font-family: var(--font-outfit); font-weight: 700; font-size: 1.1rem; color: var(--text-primary); margin-bottom: 0.25rem;">Router-R1 Paper</span>
<span style="font-size: 0.8rem; color: var(--text-secondary); margin-bottom: 0.75rem;">Multi-Round Routing and Aggregation via Reinforcement Learning (2025)</span>
<a href="article/Router_R1_Multi_Round.pdf" target="_blank" style="align-self: flex-start; background: rgba(139, 92, 246, 0.15); border: 1px solid rgba(109, 40, 217, 0.2); color: var(--accent-violet); font-size: 0.75rem; font-weight: 600; padding: 0.25rem 0.65rem; border-radius: 6px; text-decoration: none; display: inline-flex; align-items: center; gap: 0.25rem; margin-bottom: 0.75rem;">Read / Preview PDF</a>
<details class="paper-summary-details">
<summary>查看学术综述 (Paper Summary)</summary>
<div class="paper-summary-content">
<h5>🔍 研究背景</h5>
<p>单次单轮分类分流遇到超复杂的多步推理或代码排错任务基本失灵。复杂任务需要多轮拆解、反复求证与多次升级路由。</p>
<h5>📐 数学建模与公式</h5>
<p><strong>RL 奖励机制:</strong> \(\mathcal{R} = \mathcal{R}_{\text{accuracy}}(y) + \mathcal{R}_{\text{format}}(\text{think\_blocks}) - \beta \cdot \text{Cost}_{\text{inference}}\),用强化学习调教 local 选路 agent。Agent 生成带有 `<think>` 思维链的逻辑步骤,拆分调度子请求并汇总。</p>
<h5>📊 实验结论</h5>
<p>训练过的 8B 代理学会了在思考链中调度预算,仅耗费 GPT-4 35% 的成本就达到了等同程度的数学解答水准。</p>
<h5>⚙️ Codebase 集成落地</h5>
<p>对应了网关在 <a href="file:///c:/Users/pengy/OneDrive/Desktop/InferRoute/inferroute/main.py">main.py</a> 级联检验模块中配置的失败回退重试与条件流阻断。</p>
</div>
</details>
</div>
<!-- Paper 8 -->
<div class="sub-card" style="display: flex; flex-direction: column; padding: 1.5rem; background: rgba(0, 0, 0, 0.02); border: 1px solid var(--border-color); border-radius: 12px; color: var(--text-primary);">
<span style="font-size: 1.5rem; margin-bottom: 0.5rem;">📄</span>
<span style="font-family: var(--font-outfit); font-weight: 700; font-size: 1.1rem; color: var(--text-primary); margin-bottom: 0.25rem;">LLMRouterBench Paper</span>
<span style="font-size: 0.8rem; color: var(--text-secondary); margin-bottom: 0.75rem;">A Massive Benchmark and Unified Framework for LLM Routing (2026)</span>
<a href="article/LLMRouterBench_Massive.pdf" target="_blank" style="align-self: flex-start; background: rgba(139, 92, 246, 0.15); border: 1px solid rgba(109, 40, 217, 0.2); color: var(--accent-violet); font-size: 0.75rem; font-weight: 600; padding: 0.25rem 0.65rem; border-radius: 6px; text-decoration: none; display: inline-flex; align-items: center; gap: 0.25rem; margin-bottom: 0.75rem;">Read / Preview PDF</a>
<details class="paper-summary-details">
<summary>查看学术综述 (Paper Summary)</summary>
<div class="paper-summary-content">
<h5>🔍 研究背景</h5>
<p>解决路由领域实验设计混乱、微调偏好漂移等数据漂移(Data Drift)带来的评测不稳定性,亟需大规模科学对照评测基准。</p>
<h5>📊 实验结论</h5>
<p>构建了 400K 级多任务标准测试集,证实路由存在 Scaling Laws(缩放定律):决策模型并非越大越好,1B 以下的特征分类器往往性能/能耗性价比最高。</p>
<h5>⚙️ Codebase 集成落地</h5>
<p>网关所采用的 Reproducible Evaluation Harness 脚本提供了基础实验测试设计方法与任务配置格式(<a href="file:///c:/Users/pengy/OneDrive/Desktop/InferRoute/benchmarks/datasets/workload.json">workload.json</a>)。</p>
</div>
</details>
</div>
<!-- Paper 9 -->
<div class="sub-card" style="display: flex; flex-direction: column; padding: 1.5rem; background: rgba(0, 0, 0, 0.02); border: 1px solid var(--border-color); border-radius: 12px; color: var(--text-primary);">
<span style="font-size: 1.5rem; margin-bottom: 0.5rem;">📄</span>
<span style="font-family: var(--font-outfit); font-weight: 700; font-size: 1.1rem; color: var(--text-primary); margin-bottom: 0.25rem;">Routing Survey Paper</span>
<span style="font-size: 0.8rem; color: var(--text-secondary); margin-bottom: 0.75rem;">A Survey on Routing Strategies for Resource Optimisation (2025)</span>
<a href="article/Survey_Routing_Resource_Optimisation.pdf" target="_blank" style="align-self: flex-start; background: rgba(139, 92, 246, 0.15); border: 1px solid rgba(109, 40, 217, 0.2); color: var(--accent-violet); font-size: 0.75rem; font-weight: 600; padding: 0.25rem 0.65rem; border-radius: 6px; text-decoration: none; display: inline-flex; align-items: center; gap: 0.25rem; margin-bottom: 0.75rem;">Read / Preview PDF</a>
<details class="paper-summary-details">
<summary>查看学术综述 (Paper Summary)</summary>
<div class="paper-summary-content">
<h5>🔍 研究背景</h5>
<p>为大模型服务架构及硬件开销分摊在资源优化垂直领域的科学分类(Taxonomy)建立体系。</p>
<h5>📊 总结机制</h5>
<p>从路由特征空间(Embedding/Text/Agent)、选路时间节点(Pre-generation/In-generation/Post-generation)与基础设施成本(本地 GPU 折旧 vs 云 API 计费)对比了各种架构的吞吐量、响应延时等折中机制。</p>
<h5>⚙️ Codebase 集成落地</h5>
<p>确定了 InferRoute 数据平面与控制平面分离、网关多指标 Prometheus 监控的设计方针。</p>
</div>
</details>
</div>
</div>
</div>
<!-- Academic Bibliography & References -->
<div class="glass-card" style="margin-top: 2rem;">
<h2>📚 Academic Bibliography & References</h2>
<p>Formal scientific citations for the core research papers referenced during the design and optimization of the InferRoute gateway:</p>
<div style="display: flex; flex-direction: column; gap: 1.5rem; margin-top: 1.5rem;">
<div class="sub-card" style="background: rgba(0,0,0,0.01);">
<h4 style="font-family: var(--font-outfit); font-weight: 700; color: var(--text-primary); margin-bottom: 0.5rem;">1. FrugalGPT (Stanford University)</h4>
<p style="font-size: 0.9rem; color: var(--text-secondary); margin-bottom: 0.75rem; font-style: italic;">
Chen, L., Zaharia, M., & Zou, J. (2023). FrugalGPT: How to use large language models while reducing cost and improving performance. <em>arXiv preprint arXiv:2305.05196</em>.
</p>
<details style="cursor: pointer; font-size: 0.85rem;">
<summary style="color: var(--accent-violet); font-weight: 600; outline: none; margin-bottom: 0.5rem;">Show BibTeX Citation</summary>
<pre style="background: rgba(0,0,0,0.03); padding: 0.75rem; border-radius: 6px; border: 1px solid var(--border-color); overflow-x: auto; font-family: monospace; color: var(--text-secondary);">@article{chen2023frugalgpt,
title={FrugalGPT: How to use large language models while reducing cost and improving performance},
author={Chen, Lingjiao and Zaharia, Matei and Zou, James},
journal={arXiv preprint arXiv:2305.05196},
year={2023}
}</pre>
</details>
</div>
<div class="sub-card" style="background: rgba(0,0,0,0.01);">
<h4 style="font-family: var(--font-outfit); font-weight: 700; color: var(--text-primary); margin-bottom: 0.5rem;">2. RouterBench (Martian)</h4>
<p style="font-size: 0.9rem; color: var(--text-secondary); margin-bottom: 0.75rem; font-style: italic;">
Li, T., Martian Team, et al. (2024). RouterBench: A Benchmark for Multi-LLM Routing System. <em>arXiv preprint arXiv:2403.11164</em>.
</p>
<details style="cursor: pointer; font-size: 0.85rem;">
<summary style="color: var(--accent-violet); font-weight: 600; outline: none; margin-bottom: 0.5rem;">Show BibTeX Citation</summary>
<pre style="background: rgba(0,0,0,0.03); padding: 0.75rem; border-radius: 6px; border: 1px solid var(--border-color); overflow-x: auto; font-family: monospace; color: var(--text-secondary);">@article{li2024routerbench,
title={RouterBench: A Benchmark for Multi-LLM Routing System},
author={Li, Teh-Hsien and others},
journal={arXiv preprint arXiv:2403.11164},
year={2024}
}</pre>
</details>
</div>
<div class="sub-card" style="background: rgba(0,0,0,0.01);">
<h4 style="font-family: var(--font-outfit); font-weight: 700; color: var(--text-primary); margin-bottom: 0.5rem;">3. Hybrid LLM Routing (IBM / Tsinghua)</h4>
<p style="font-size: 0.9rem; color: var(--text-secondary); margin-bottom: 0.75rem; font-style: italic;">
Ding, J., et al. (2024). Hybrid LLM: Cost-Efficient and Quality-Aware Query Routing. <em>arXiv preprint arXiv:2404.14944</em>.
</p>
<details style="cursor: pointer; font-size: 0.85rem;">
<summary style="color: var(--accent-violet); font-weight: 600; outline: none; margin-bottom: 0.5rem;">Show BibTeX Citation</summary>
<pre style="background: rgba(0,0,0,0.03); padding: 0.75rem; border-radius: 6px; border: 1px solid var(--border-color); overflow-x: auto; font-family: monospace; color: var(--text-secondary);">@article{ding2024hybrid,
title={Hybrid LLM: Cost-Efficient and Quality-Aware Query Routing},
author={Ding, Jiayi and others},
journal={arXiv preprint arXiv:2404.14944},
year={2024}
}</pre>
</details>
</div>
<div class="sub-card" style="background: rgba(0,0,0,0.01);">
<h4 style="font-family: var(--font-outfit); font-weight: 700; color: var(--text-primary); margin-bottom: 0.5rem;">4. RouteLLM (LMSYS / UC Berkeley)</h4>
<p style="font-size: 0.9rem; color: var(--text-secondary); margin-bottom: 0.75rem; font-style: italic;">
Ong, I., Almahairi, A., Wu, V., Chiang, W. L., Wu, T., Gonzalez, J. E., Kadous, M. W., & Stoica, I. (2025). RouteLLM: Learning to Route LLMs with Preference Data. <em>Proceedings of the Thirteenth International Conference on Learning Representations (ICLR)</em>.
</p>
<details style="cursor: pointer; font-size: 0.85rem;">
<summary style="color: var(--accent-violet); font-weight: 600; outline: none; margin-bottom: 0.5rem;">Show BibTeX Citation</summary>
<pre style="background: rgba(0,0,0,0.03); padding: 0.75rem; border-radius: 6px; border: 1px solid var(--border-color); overflow-x: auto; font-family: monospace; color: var(--text-secondary);">@inproceedings{ong2025routellm,
title={RouteLLM: Learning to Route LLMs with Preference Data},
author={Ong, Isaac and Almahairi, Amjad and Wu, Vincent and Chiang, Wei-Lin and Wu, Tianhao and Gonzalez, Joseph E. and Kadous, M. Waleed and Stoica, Ion},
booktitle={The Thirteenth International Conference on Learning Representations},
year={2025}
}</pre>
</details>
</div>
<div class="sub-card" style="background: rgba(0,0,0,0.01);">
<h4 style="font-family: var(--font-outfit); font-weight: 700; color: var(--text-primary); margin-bottom: 0.5rem;">5. EquiRouter (Routing Collapse Mitigation)</h4>
<p style="font-size: 0.9rem; color: var(--text-secondary); margin-bottom: 0.75rem; font-style: italic;">
Lai, G., & Ye, H. J. (2026). When Routing Collapses: On the Degenerate Convergence of LLM Routers. <em>arXiv preprint arXiv:2602.03478</em>.
</p>
<details style="cursor: pointer; font-size: 0.85rem;">
<summary style="color: var(--accent-violet); font-weight: 600; outline: none; margin-bottom: 0.5rem;">Show BibTeX Citation</summary>
<pre style="background: rgba(0,0,0,0.03); padding: 0.75rem; border-radius: 6px; border: 1px solid var(--border-color); overflow-x: auto; font-family: monospace; color: var(--text-secondary);">@article{lai2026when,
title={When Routing Collapses: On the Degenerate Convergence of LLM Routers},
author={Lai, Guannan and Ye, Han-Jia},
journal={arXiv preprint arXiv:2602.03478},
year={2026}
}</pre>
</details>
</div>
<div class="sub-card" style="background: rgba(0,0,0,0.01);">
<h4 style="font-family: var(--font-outfit); font-weight: 700; color: var(--text-primary); margin-bottom: 0.5rem;">6. R2-Router (Output-Length-Constrained Routing)</h4>
<p style="font-size: 0.9rem; color: var(--text-secondary); margin-bottom: 0.75rem; font-style: italic;">
Anonymous (2026). R2-Router: A New Paradigm for LLM Routing with Reasoning. <em>arXiv preprint arXiv:2602.02823</em>.
</p>
<details style="cursor: pointer; font-size: 0.85rem;">
<summary style="color: var(--accent-violet); font-weight: 600; outline: none; margin-bottom: 0.5rem;">Show BibTeX Citation</summary>
<pre style="background: rgba(0,0,0,0.03); padding: 0.75rem; border-radius: 6px; border: 1px solid var(--border-color); overflow-x: auto; font-family: monospace; color: var(--text-secondary);">@article{r2router2026,
title={R2-Router: A New Paradigm for LLM Routing with Reasoning},
journal={arXiv preprint arXiv:2602.02823},
year={2026}
}</pre>
</details>
</div>
<div class="sub-card" style="background: rgba(0,0,0,0.01);">
<h4 style="font-family: var(--font-outfit); font-weight: 700; color: var(--text-primary); margin-bottom: 0.5rem;">7. Router-R1 (Reinforcement Learned Multi-Round Router)</h4>
<p style="font-size: 0.9rem; color: var(--text-secondary); margin-bottom: 0.75rem; font-style: italic;">
Anonymous (2025). Router-R1: Teaching LLMs Multi-Round Routing and Aggregation via Reinforcement Learning. <em>arXiv preprint arXiv:2506.09033</em>.
</p>
<details style="cursor: pointer; font-size: 0.85rem;">
<summary style="color: var(--accent-violet); font-weight: 600; outline: none; margin-bottom: 0.5rem;">Show BibTeX Citation</summary>
<pre style="background: rgba(0,0,0,0.03); padding: 0.75rem; border-radius: 6px; border: 1px solid var(--border-color); overflow-x: auto; font-family: monospace; color: var(--text-secondary);">@article{routerr12025,
title={Router-R1: Teaching LLMs Multi-Round Routing and Aggregation via Reinforcement Learning},
journal={arXiv preprint arXiv:2506.09033},
year={2025}
}</pre>
</details>
</div>
<div class="sub-card" style="background: rgba(0,0,0,0.01);">
<h4 style="font-family: var(--font-outfit); font-weight: 700; color: var(--text-primary); margin-bottom: 0.5rem;">8. LLMRouterBench (Large-Scale Benchmarking Framework)</h4>
<p style="font-size: 0.9rem; color: var(--text-secondary); margin-bottom: 0.75rem; font-style: italic;">
Anonymous (2026). LLMRouterBench: A Massive Benchmark and Unified Framework for LLM Routing. <em>arXiv preprint arXiv:2601.07206</em>.
</p>
<details style="cursor: pointer; font-size: 0.85rem;">
<summary style="color: var(--accent-violet); font-weight: 600; outline: none; margin-bottom: 0.5rem;">Show BibTeX Citation</summary>
<pre style="background: rgba(0,0,0,0.03); padding: 0.75rem; border-radius: 6px; border: 1px solid var(--border-color); overflow-x: auto; font-family: monospace; color: var(--text-secondary);">@article{llmrouterbench2026,
title={LLMRouterBench: A Massive Benchmark and Unified Framework for LLM Routing},
journal={arXiv preprint arXiv:2601.07206},
year={2026}
}</pre>
</details>
</div>
<div class="sub-card" style="background: rgba(0,0,0,0.01);">
<h4 style="font-family: var(--font-outfit); font-weight: 700; color: var(--text-primary); margin-bottom: 0.5rem;">9. Resource-Optimized LLM Routing Survey</h4>
<p style="font-size: 0.9rem; color: var(--text-secondary); margin-bottom: 0.75rem; font-style: italic;">
Anonymous (2025). Doing More with Less: A Survey on Routing Strategies for Resource Optimisation in Large Language Model-Based Systems. <em>arXiv preprint arXiv:2502.00409</em>.
</p>
<details style="cursor: pointer; font-size: 0.85rem;">
<summary style="color: var(--accent-violet); font-weight: 600; outline: none; margin-bottom: 0.5rem;">Show BibTeX Citation</summary>
<pre style="background: rgba(0,0,0,0.03); padding: 0.75rem; border-radius: 6px; border: 1px solid var(--border-color); overflow-x: auto; font-family: monospace; color: var(--text-secondary);">@article{resource_routing_survey_2025,
title={Doing More with Less: A Survey on Routing Strategies for Resource Optimisation in Large Language Model-Based Systems},
journal={arXiv preprint arXiv:2502.00409},
year={2025}
}</pre>
</details>
</div>
</div>
</div>
</div>
<!-- Tab 2: Architecture -->
<div id="architecture" class="tab-content">
<div class="glass-card">
<h2>🏗 InferRoute Gateway Request Lifecycle</h2>
<p>The sequence details how the gateway interceptor resolves client requests, manages cache, allocates concurrency slots, and executes cascades:</p>
<div class="mermaid-box" style="background: rgba(0,0,0,0.35); padding: 1.5rem; border-radius: 12px; border: 1px solid var(--border-color); display: flex; justify-content: center; overflow-x: auto; margin-top: 1rem; margin-bottom: 2.5rem; box-shadow: inset 0 2px 8px rgba(0,0,0,0.4);">
<div class="mermaid" style="width: 100%; min-width: 600px;">
sequenceDiagram
autonumber
actor Client as Client App / SDK
participant GW as InferRoute Gateway
participant Auth as Auth & Credit Gate
participant Cache as Cache Layer (Redis)
participant Limiter as Vegas Limiter
participant Router as Routing Engine
participant Model as LLM Upstream
participant Audit as DB Audit & Billing
Client->>GW: POST /v1/chat/completions (Stream)
GW->>Auth: verify_api_key & check_balance
alt Balance <= $0.00
Auth-->>Client: 402 Payment Required
else Balance OK
Auth-->>GW: Tenant ID Resolved
GW->>Cache: try_acquire_dedup_lock
alt Cache Hit
Cache-->>Client: Stream Cached chunks directly
else Cache Miss
GW->>Cache: match_longest_prefix
Cache-->>GW: Return Cache-Affinity Weight
GW->>Limiter: acquire_slot
alt Concurrency Exceeded
Limiter-->>Client: 429 Too Many Requests
else Slot Acquired
GW->>Router: choose_backend (Scoring weights)
Router-->>GW: Selected Backend (e.g. Ollama)
GW->>Model: Invoke Model Stream
Model-->>GW: Yield Stream Chunks
GW->>Client: Forward Stream Chunks
alt Loop/Repetitive Garbage Detected
GW->>Model: Cancel speculative stream
GW->>Router: Trigger Fallback Cascade
Router->>Model: Invoke Cloud Backend (OpenAI)
Model-->>Client: Stream Cloud response
end
GW->>Limiter: release_slot
GW->>Audit: db_log_request & debit wallet
end
end
end
</div>
</div>
<div class="lifecycle-container">
<div class="lifecycle-step">
<div class="step-num">1</div>
<div class="step-info">
<h4>Authentication & Credit check</h4>
<p>Resolves client headers to tenant ID and asserts balance balance \(> \$0.00\). Applies a resilient fail-open policy if the database is unreachable.</p>
</div>
</div>
<div class="lifecycle-step">
<div class="step-num">2</div>
<div class="step-info">
<h4>Exact & Prefix Cache Match</h4>
<p>Performs a Redis exact completion lookup. If missing, checks the Radix Trie prefix index to score warm KV-cache affinity on self-hosted model backends.</p>
</div>
</div>
<div class="lifecycle-step">
<div class="step-num">3</div>
<div class="step-info">
<h4>Vegas Concurrency Control</h4>
<p>Queries concurrency limits to dynamically protect local GPU memory allocations, rejecting or cascading requests to cloud buffers if limits are breached.</p>
</div>
</div>
<div class="lifecycle-step">
<div class="step-num">4</div>
<div class="step-info">
<h4>Model Selection & Cascade Stream</h4>
<p>Routes prompts to the chosen backend. For cascades, it buffers output stream tokens, runs heuristics, and transparently initiates speculative escalations upon validation failures.</p>
</div>
</div>
<div class="lifecycle-step">
<div class="step-num">5</div>
<div class="step-info">
<h4>Audit Ledger logging</h4>
<p>Logs latency telemetry and final aggregated token costs asynchronously to PostgreSQL database ledgers, decrementing tenant credit limits.</p>
</div>
</div>
</div>
</div>
<!-- Playground Control Center Card -->
<div class="glass-card" style="margin-top: 2rem;">
<h2>🎨 Observability Control Center & Interactive Playground</h2>
<p>InferRoute features an interactive client playground dashboard (served at the root <code>/</code> path) allowing developers to monitor and simulate gateway functions in real-time:</p>
<div class="card-grid" style="margin-top: 1.5rem;">
<div class="sub-card">
<h3>1. Live Telemetry Cost Dashboard</h3>
<p>Displays financial metrics including cumulative API dollars saved, tokens processed, Redis cache hit rates, average Time-to-First-Token (TTFT), and system uptime in real-time.</p>
</div>
<div class="sub-card">
<h3>2. Interceptor Pipeline Visualizer</h3>
<p>Renders a live vertical step visualizer tracking individual requests. Watch prompts flow through Cache lookup ➔ Concurrency limit verification ➔ Primary model execution ➔ speculative loops cancellation ➔ Cascade trigger.</p>
</div>
<div class="sub-card">
<h3>3. Wallet & Credit Controller</h3>
<p>Simulates tenant wallet balances and limits. Allows manual top-up adjustments (e.g., refilling $10.00 trial credits) to inspect rate-limiting triggers and HTTP 402 payment requirements.</p>
</div>
<div class="sub-card">
<h3>4. Chaos Engineering Panel</h3>
<p>Allows manual injection of failures (latency spikes, HTTP 500 crashes, network dropouts) into specific backend nodes to observe gateway self-healing, automatic failovers, and circuit-breaker status changes in real-time.</p>
</div>
</div>
</div>
</div>
<!-- Tab 3: Benchmarks -->
<div id="benchmarks" class="tab-content">
<div class="glass-card">
<h2>📊 RouterBench Policy Sweep Outcomes</h2>
<p>Below are evaluation statistics sweeping mixture ratios (\(p\)), trade-off factors (\(\lambda\)), and cascade thresholds (\(\tau\)) over workload dataset prompts:</p>
<table>
<thead>
<tr>
<th>Routing Strategy</th>
<th>Cost per Request ($ USD)</th>
<th>Avg Quality Score (0 - 1.0)</th>
<th>Avg Latency (ms)</th>
<th>SLO Compliance</th>
<th>Fallback Hops</th>
</tr>
</thead>
<tbody>
<tr>
<td class="highlight-violet">Oracle Router Optimal</td>
<td>$0.000022</td>
<td>0.78</td>
<td>258ms</td>
<td class="highlight-emerald">100.0%</td>
<td>0.0%</td>
</tr>
<tr>
<td>KNN Router (\(\lambda = 1.00\))</td>
<td>$0.000019</td>
<td>0.75</td>
<td>266ms</td>
<td class="highlight-emerald">100.0%</td>
<td>0.0%</td>
</tr>
<tr>
<td>MLP Router (\(\lambda = 0.50\))</td>
<td>$0.000023</td>
<td>0.75</td>
<td>258ms</td>
<td class="highlight-emerald">100.0%</td>
<td>0.0%</td>
</tr>
<tr>
<td>Cascade Router (\(\tau = 0.60\))</td>
<td>$0.000017</td>
<td>0.62</td>
<td>239ms</td>
<td class="highlight-emerald">100.0%</td>
<td>66.7%</td>
</tr>
<tr>
<td>Always OpenAI Cloud</td>
<td>$0.000044</td>
<td>0.75</td>
<td>250ms</td>
<td class="highlight-emerald">100.0%</td>
<td>0.0%</td>
</tr>
<tr>
<td>Always Ollama Local</td>
<td>$0.000000</td>
<td>0.31</td>
<td>190ms</td>
<td class="highlight-emerald">100.0%</td>
<td>8.3%</td>
</tr>
</tbody>
</table>
</div>
<div class="glass-card">
<h2>📈 Trade-off Visualization Curves</h2>
<p>These curves show the actual measured performance frontier across swept cost levels:</p>
<div class="card-grid" style="margin-top: 1.5rem;">
<div class="sub-card" style="text-align: center;">
<h3 style="margin-bottom: 0.75rem; text-align: left;">Cost-Quality Pareto Frontier</h3>
<img src="cost_quality_frontier.png" alt="Cost-Quality Frontier" style="max-width: 100%; border-radius: 8px; border: 1px solid var(--border-color); box-shadow: 0 4px 15px rgba(0,0,0,0.3); transition: all 0.3s;" onmouseover="this.style.transform='scale(1.02)';" onmouseout="this.style.transform='scale(1)';" />
<p style="font-size: 0.8rem; color: var(--text-secondary); margin-top: 0.75rem; text-align: left;">Pareto sweeps comparing KNN, MLP, FrugalGPT Cascades, and the Zero Router baseline. Note the efficient frontier pushed to the top-left by the learned routers.</p>
</div>
<div class="sub-card" style="text-align: center;">
<h3 style="margin-bottom: 0.75rem; text-align: left;">Latency Comparison</h3>
<img src="latency_comparison.png" alt="Latency Comparison" style="max-width: 100%; border-radius: 8px; border: 1px solid var(--border-color); box-shadow: 0 4px 15px rgba(0,0,0,0.3); transition: all 0.3s;" onmouseover="this.style.transform='scale(1.02)';" onmouseout="this.style.transform='scale(1)';" />
<p style="font-size: 0.8rem; color: var(--text-secondary); margin-top: 0.75rem; text-align: left;">Comparison of processing latency and time-to-first-token (TTFT) metrics across different routing scenarios.</p>
</div>
</div>
</div>
<div class="glass-card">
<h2>📈 Executive Experiment Summary</h2>
<div class="card-grid">
<div class="sub-card">
<h3>98% API Cost Saved</h3>
<p>Through exact stream deduplication via Redis Pub/Sub, multiple concurrent burst requests calling duplicate system prompts are coalesced into a single upstream model invocation.</p>
</div>
<div class="sub-card">
<h3>80% TTFT Reduction</h3>
<p>Prefix-affinity routing identifies Warm KV-caches on GPU nodes using a Radix Trie, routing prompts to nodes with active context caches to eliminate prefill latency.</p>
</div>
</div>
</div>
<!-- Reproducible Evaluation Sweep Harness -->
<div class="glass-card" style="margin-top: 2rem;">
<h2>📊 Reproducible Evaluation Sweep Harness</h2>
<p>InferRoute provides a built-in evaluation framework to verify the cost-quality trade-offs of all routing algorithms under realistic workload datasets. The system sweeps ratios and willingness-to-pay parameters to export Pareto curves:</p>
<div style="display: flex; flex-direction: column; gap: 1rem; margin-top: 1rem;">
<div class="sub-card" style="background: rgba(0, 0, 0, 0.01);">
<h3>1. Run the Evaluation Sweep Orchestrator</h3>
<p style="margin-bottom: 0.75rem; font-size: 0.9rem; color: var(--text-secondary);">This script iterates across dataset prompts, simulating requests against mock or real endpoints and logging cost, latency, quality, and routing outputs:</p>
<pre style="background: rgba(0,0,0,0.03); padding: 0.75rem; border-radius: 6px; border: 1px solid var(--border-color); font-family: monospace; color: var(--text-primary); font-size: 0.85rem;">python benchmarks/run_router_eval.py</pre>
</div>
<div class="sub-card" style="background: rgba(0, 0, 0, 0.01);">
<h3>2. Compile Metrics & Generate Pareto Curves</h3>
<p style="margin-bottom: 0.75rem; font-size: 0.9rem; color: var(--text-secondary);">This script reads the raw evaluation outcomes, fits the cost-quality points using the Trapezoidal Rule to calculate Area Under the Curve (AIQ), and exports standard PNG curves:</p>
<pre style="background: rgba(0,0,0,0.03); padding: 0.75rem; border-radius: 6px; border: 1px solid var(--border-color); font-family: monospace; color: var(--text-primary); font-size: 0.85rem;">python benchmarks/plot_results.py</pre>
</div>
<div class="sub-card" style="background: rgba(109, 40, 217, 0.02); border-color: rgba(109, 40, 217, 0.15);">
<h3 style="color: var(--accent-violet);">⚙️ Sweeping Parameters Summary</h3>
<p style="font-size: 0.85rem; color: var(--text-secondary);">The evaluation sweeps the target cloud mixture ratio \(p \in [0, 1]\) for the Zero Router baseline, and sweeping trade-off thresholds \(\lambda \in [0, 1]\) or \(\tau \in [0, 1]\) for KNN, MLP, and Cascade routing algorithms to systematically construct the Pareto frontier.</p>
</div>
</div>
</div>
</div>
<!-- Tab 4: Self-Healing -->
<div id="self-healing" class="tab-content">
<div class="glass-card">
<h2>🛡️ Vegas Adaptive Limiting & Circuit Breakers</h2>
<p>InferRoute maintains system resilience through autonomous closed-loop feedback controllers.</p>
<div class="card-grid">
<div class="sub-card">
<h3>1. Vegas Congestion Limiter</h3>
<p>Inspired by TCP Vegas congestion control, the gateway dynamically scales concurrent request slots based on measured latency queue sizes. It auto-throttles requests during model spikes to prevent local GPU OOMs.</p>
</div>
<div class="sub-card">
<h3>2. Self-Healing Circuit Breaker</h3>
<p>Monitors consecutive timeouts and error codes. Transitions from <strong>CLOSED</strong> to <strong>OPEN</strong> upon 5 consecutive failures, bypassing degraded local nodes to fallback cloud targets instantly, recovering automatically via <strong>HALF-OPEN</strong> testing.</p>
</div>
</div>
</div>
</div>
<!-- Tab 5: Playground -->
<div id="playground" class="tab-content">
<div class="glass-card">
<h2>🎮 Interactive Gateway Sandbox (Client-Side Simulator)</h2>
<p>Play with all 9 academic routing policies directly in your browser. This sandbox simulates prefix cache check, Vegas limiter slots, RouteLLM Bradley-Terry勝率 matching, R2-Router word restraints, and Router-R1 agentic draft correction.</p>
<div class="playground-grid">
<!-- Left: Interactive Chat -->
<div class="playground-main-panel">
<div class="playground-header">
<span style="font-weight:700; font-family:var(--font-outfit);">Sandbox Panel</span>
<div class="playground-controls">
<select id="pgPolicySelect" class="playground-select" onchange="onPgPolicyChange(this.value)">
<option value="frugalgpt">🔄 Stanford FrugalGPT Cascade</option>
<option value="routerbench">🎯 Martian RouterBench Utility</option>
<option value="hybrid_llm">⚡ IBM Hybrid LLM Difficulty</option>
<option value="routellm">🧠 LMSYS RouteLLM Preference</option>
<option value="equirouter">⚖️ EquiRouter Decision-Aware MLP</option>
<option value="r2_router">📏 R2-Router Length Constrained</option>
<option value="router_r1">🤖 Router-R1 Multi-Round Agentic</option>
<option value="routing_survey">📋 Unified Routing Survey</option>
<option value="zero">🎲 Zero Router Baseline</option>
</select>
</div>
</div>
<div class="playground-chat-history" id="pgChatHistory">
<div class="playground-bubble assistant">
System initialized. Select any of the 9 academic routing policies from the dropdown above and send a message. The gateway pipeline visualizer and metrics will update in real-time.
</div>
</div>
<div class="playground-input-row">
<textarea id="pgPromptInput" class="playground-textarea" placeholder="Type a message to route... (e.g. 'Solve for x: 5x - 15 = 20' or 'def is_prime(n):')"></textarea>
<button class="playground-send-btn" onclick="sendPgMessage()">Send</button>
</div>
</div>
<!-- Right: Dashboard & Visualizer -->
<div class="playground-sidebar">
<div class="playground-wallet">
<span style="font-size:0.85rem; color:var(--text-secondary); font-weight:500;">Trial Wallet Balance:</span>
<div style="display:flex; align-items:center; gap:0.5rem;">
<span id="pgWalletBalance" style="color:var(--accent-emerald); font-weight:700; font-size:1.1rem;">$5.00</span>
<button class="playground-wallet-recharge" onclick="rechargePgWallet()">+ $10</button>
</div>
</div>
<div class="playground-metrics-grid">
<div class="playground-metric-card">
<span class="playground-metric-label">Estimated Savings</span>
<span class="playground-metric-val" id="pgSavingsVal">$0.00</span>
</div>
<div class="playground-metric-card">
<span class="playground-metric-label">Tokens Saved</span>
<span class="playground-metric-val" id="pgTokensVal">0</span>
</div>
<div class="playground-metric-card">
<span class="playground-metric-label">Last TTFT</span>
<span class="playground-metric-val" id="pgTtftVal">0 ms</span>
</div>
<div class="playground-metric-card">
<span class="playground-metric-label">Cache Hit Rate</span>
<span class="playground-metric-val" id="pgCacheHitVal">0%</span>
</div>
</div>
<div class="playground-pipeline">
<h3 style="font-size:0.95rem; font-family:var(--font-outfit); display:flex; justify-content:space-between; align-items:center; margin-bottom:0.25rem;">
<span>🚀 Gateway Pipeline Visualizer</span>
<span id="pgPipelineStatus" style="font-size:0.75rem; font-weight:600; color:var(--text-secondary);">IDLE</span>
</h3>
<div class="playground-pipeline-flow">
<div class="playground-pipeline-step" id="pgStep_cache">
<div class="step-name">1. Exact & Prefix Cache Check</div>
<div class="step-desc" id="pgStepDesc_cache">Checking Redis caches (Radix Trie check)</div>
</div>
<div class="playground-pipeline-step" id="pgStep_limiter">
<div class="step-name">2. Vegas Concurrency Limiter</div>
<div class="step-desc" id="pgStepDesc_limiter">Validating slot queue depth</div>
</div>
<div class="playground-pipeline-step" id="pgStep_routing">
<div class="step-name">3. Routing Decision Engine</div>
<div class="step-desc" id="pgStepDesc_routing">Evaluating policy formula</div>
</div>
<div class="playground-pipeline-step" id="pgStep_exec">
<div class="step-name">4. Verification & Output Judge</div>
<div class="step-desc" id="pgStepDesc_exec">Running syntactic & loop validation</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
function switchTab(event, tabId) {
// Hide all tabs
const tabContents = document.getElementsByClassName("tab-content");
for (let content of tabContents) {
content.classList.remove("active");
}
// Remove active style from buttons
const tabButtons = document.getElementsByClassName("tab-btn");
for (let btn of tabButtons) {
btn.classList.remove("active");
}
// Show target tab
document.getElementById(tabId).classList.add("active");
event.currentTarget.classList.add("active");
}
function updateSimTau(val) {
document.getElementById("simTauVal").innerText = parseFloat(val).toFixed(2);
}
// ── Interactive Playground Simulation Engine ──
const COSTS = { ollama: 0.0001, vllm: 0.0002, gemini: 0.0015, openai: 0.0030 };
let pgWallet = 5.00;
let pgSavings = 0.00;
let pgTokensSaved = 0;
let pgCacheHits = 0;
let pgTotalReqs = 0;
let pgSentPrompts = new Set();
let pgIsProcessing = false;
function rechargePgWallet() {
pgWallet += 10.00;
document.getElementById("pgWalletBalance").innerText = "$" + pgWallet.toFixed(2);
appendSystemMessage("Wallet recharged with $10.00. New balance: $" + pgWallet.toFixed(2));
}
function onPgPolicyChange(policy) {
appendSystemMessage(`Selected Routing Policy: ${policy.toUpperCase()}`);
}
function appendSystemMessage(text) {
const chatHistory = document.getElementById("pgChatHistory");
const bubble = document.createElement("div");
bubble.className = "playground-bubble assistant";
bubble.style.borderStyle = "dashed";
bubble.style.borderColor = "rgba(139, 92, 246, 0.3)";
bubble.innerText = `⚙️ [SYSTEM LOG] ${text}`;
chatHistory.appendChild(bubble);
chatHistory.scrollTop = chatHistory.scrollHeight;
}
function appendChatBubble(role, text) {
const chatHistory = document.getElementById("pgChatHistory");
const bubble = document.createElement("div");
bubble.className = `playground-bubble ${role}`;
bubble.innerText = text;
chatHistory.appendChild(bubble);
chatHistory.scrollTop = chatHistory.scrollHeight;
return bubble;
}
function resetPipelineSteps() {
const steps = ["cache", "limiter", "routing", "exec"];
steps.forEach(s => {
const el = document.getElementById(`pgStep_${s}`);
el.className = "playground-pipeline-step";
});
document.getElementById("pgStepDesc_cache").innerText = "Checking Redis caches (Radix Trie check)";
document.getElementById("pgStepDesc_limiter").innerText = "Validating slot queue depth";
document.getElementById("pgStepDesc_routing").innerText = "Evaluating policy formula";
document.getElementById("pgStepDesc_exec").innerText = "Running syntactic & loop validation";
}
function setPipelineStepState(step, state, descText) {
const el = document.getElementById(`pgStep_${step}`);
el.className = `playground-pipeline-step ${state}`;
if (descText) {
document.getElementById(`pgStepDesc_${step}`).innerText = descText;
}
}
function sendPgMessage() {
if (pgIsProcessing) return;
const promptInput = document.getElementById("pgPromptInput");
const promptText = promptInput.value.trim();
if (!promptText) return;
pgIsProcessing = true;
promptInput.value = "";
pgTotalReqs++;
// Append user bubble
appendChatBubble("user", promptText);
resetPipelineSteps();
document.getElementById("pgPipelineStatus").innerText = "PROCESSING";
document.getElementById("pgPipelineStatus").style.color = "var(--accent-violet)";
// Step 1: Cache check after 400ms
setTimeout(() => {
setPipelineStepState("cache", "active");
const isCacheHit = pgSentPrompts.has(promptText.toLowerCase());
pgSentPrompts.add(promptText.toLowerCase());
setTimeout(() => {
if (isCacheHit) {
setPipelineStepState("cache", "success", "Cache HIT (Exact match in Redis in 1ms)");
pgCacheHits++;
document.getElementById("pgCacheHitVal").innerText = Math.round((pgCacheHits / pgTotalReqs) * 100) + "%";
document.getElementById("pgTtftVal").innerText = "1 ms";
// Stream response immediately
const cachedResponse = `[CACHE HIT] The answer to your query: "${promptText}" is already cached in Redis memory.`;
const bubble = appendChatBubble("assistant", "");
streamTextIntoBubble(bubble, cachedResponse, () => {
finalizeRequest(0.00, 100, 1.0);
});
} else {
setPipelineStepState("cache", "success", "Cache MISS (Checking suffix tries... no match)");
// Step 2: Limiter check
setTimeout(() => {
setPipelineStepState("limiter", "active");
setTimeout(() => {
setPipelineStepState("limiter", "success", "Slot Acquired (Adaptive slots = 12/32)");
// Step 3: Routing
setTimeout(() => {
setPipelineStepState("routing", "active");
const policy = document.getElementById("pgPolicySelect").value;
const decision = makeRoutingDecision(promptText, policy);
setTimeout(() => {
setPipelineStepState("routing", "success", decision.reason);
// Step 4: Execution
setTimeout(() => {
setPipelineStepState("exec", "active");
executeModelQuery(promptText, decision);
}, 600);
}, 800);
}, 500);
}, 500);
}, 400);
}
}, 500);
}, 300);
}
function makeRoutingDecision(prompt, policy) {
const promptLower = prompt.toLowerCase();
const words = promptLower.split(" ");
const hasCode = promptLower.includes("def ") || promptLower.includes("function") || promptLower.includes("{") || promptLower.includes("code");
const hasMath = promptLower.includes("solve") || promptLower.includes("calculate") || promptLower.includes("math") || promptLower.includes("=") || promptLower.includes("+");
const hasJson = promptLower.includes("json") || promptLower.includes("schema") || promptLower.includes("extract");
let backend = "vllm";
let reason = "";
let r2Active = false;
let r1Active = false;
let cascadeActive = false;
if (policy === "frugalgpt" || policy === "cascade") {
cascadeActive = true;
backend = hasCode || hasMath ? "openai" : "vllm";
reason = `FrugalGPT sequential cascade resolved. Primary target: ${backend}`;
} else if (policy === "hybrid_llm") {
backend = (hasCode || hasMath || hasJson) ? "openai" : "vllm";
reason = `Hybrid LLM difficulty split: '${backend}' (Hard Task = ${hasCode || hasMath || hasJson})`;
} else if (policy === "routellm") {
const prob = hasMath ? 0.88 : (hasCode ? 0.76 : 0.32);
backend = prob >= 0.5 ? "openai" : "vllm";
reason = `RouteLLM Win rate = ${prob.toFixed(2)}. Selected: ${backend}`;
} else if (policy === "equirouter") {
backend = hasCode ? "vllm" : (hasMath ? "openai" : "gemini");
reason = `EquiRouter Decision-Aware MLP recommended: ${backend}`;
} else if (policy === "r2_router") {
r2Active = true;
backend = (hasCode || hasMath) ? "openai" : "gemini";
reason = `R2-Router selected '${backend}' with output brevity constraints`;
} else if (policy === "router_r1") {
r1Active = true;
backend = "vllm";
reason = `Router-R1 agentic drafting mode triggered on '${backend}'`;
} else if (policy === "routing_survey") {
backend = hasCode ? "vllm" : "openai";
reason = `Routing Survey pre-generation prediction: ${backend}`;
} else if (policy === "zero") {
backend = Math.random() < 0.5 ? "openai" : "ollama";
reason = `Zero Router mixture baseline selected: ${backend}`;
} else {
// routerbench
backend = hasCode ? "vllm" : (hasMath ? "openai" : "ollama");
reason = `RouterBench utility scoring recommended: ${backend}`;
}
return { backend, reason, r2Active, r1Active, cascadeActive };
}
function executeModelQuery(prompt, decision) {
const promptLower = prompt.toLowerCase();
const hasMath = promptLower.includes("solve") || promptLower.includes("calculate") || promptLower.includes("math") || promptLower.includes("=");
const hasCode = promptLower.includes("def ") || promptLower.includes("function") || promptLower.includes("{");
let ttft = 450;
let cost = COSTS[decision.backend] || 0.0002;
let completionText = "";
let tokens = 120;
if (decision.backend === "openai" || decision.backend === "gemini") {
ttft = decision.backend === "openai" ? 650 : 380;
tokens = 150;
cost = decision.backend === "openai" ? 0.0030 : 0.0015;
if (hasMath) {
completionText = "To solve 5x - 15 = 20, we isolate x step-by-step:\n1. Add 15 to both sides: 5x = 35\n2. Divide both sides by 5: x = 7.\nThe final value of x is 7.";
} else if (hasCode) {
completionText = "def is_prime(n):\n if n <= 1:\n return False\n for i in range(2, int(n**0.5) + 1):\n if n % i == 0:\n return False\n return True";
} else {
completionText = "Large language models can be routed dynamically to save API costs. I am running on a premium cloud model to provide maximum quality response.";
}
} else {
// Local vllm/ollama
ttft = decision.backend === "vllm" ? 180 : 90;
tokens = 85;
cost = decision.backend === "vllm" ? 0.0002 : 0.0001;
if (hasCode) {
completionText = "def is_prime(n):\n # Local model fast check\n return n > 1 and all(n % i for i in range(2, int(n**0.5) + 1))";
} else {
completionText = "Hello! I am a lightweight local model running on-device. Since this is an easy task, I was selected to save cost and reduce latency.";
}
}
// Adjust parameters if R2-Router is active
if (decision.r2Active) {
cost = cost * 0.4; // saves 60% completion tokens
tokens = Math.round(tokens * 0.4);
completionText = "Result: x = 7 (brevity constraint active).";
}
document.getElementById("pgTtftVal").innerText = ttft + " ms";
// If Router-R1 multi-round is active
if (decision.r1Active) {
// Simulates draft generation failure, then escalation correction!
setPipelineStepState("exec", "warning", "Draft failing validation score (0.42 < 0.8). Escalating to Cloud...");
setTimeout(() => {
const bubble = appendChatBubble("assistant", "");
let thinkingText = "<think>\nRound 1: Draft response by vllm failed code validator check.\nRound 2: Escalated correction payload to OpenAI GPT-4o-mini.\n</think>\n";
let correctionText = "def is_prime(n):\n if n <= 1:\n return False\n for i in range(2, int(n**0.5) + 1):\n if n % i == 0:\n return False\n return True";
streamTextIntoBubble(bubble, thinkingText + correctionText, () => {
setPipelineStepState("exec", "success", "Escalation corrected & validated (Pass)");
finalizeRequest(COSTS["vllm"] + COSTS["openai"], tokens + 50, ttft + 800);
});
}, 600);
} else {
// Normal streaming
const bubble = appendChatBubble("assistant", "");
streamTextIntoBubble(bubble, completionText, () => {
setPipelineStepState("exec", "success", "Response generated and validated (Pass)");
finalizeRequest(cost, tokens, ttft);
});
}
}
function streamTextIntoBubble(bubble, fullText, callback) {
let idx = 0;
const words = fullText.split(" ");
function streamNext() {
if (idx < words.length) {
bubble.innerText += (idx === 0 ? "" : " ") + words[idx];
idx++;
const chatHistory = document.getElementById("pgChatHistory");
chatHistory.scrollTop = chatHistory.scrollHeight;
setTimeout(streamNext, 40);
} else {
if (callback) callback();
}
}
streamNext();
}
function finalizeRequest(cost, tokens, ttft) {
// Deduct wallet
pgWallet = Math.max(0.00, pgWallet - cost);
document.getElementById("pgWalletBalance").innerText = "$" + pgWallet.toFixed(2);
// Compute savings vs OpenAI base ($0.0030)
const baseCost = 0.0030;
const saved = Math.max(0.0, baseCost - cost);
pgSavings += saved;
document.getElementById("pgSavingsVal").innerText = "$" + pgSavings.toFixed(4);
// Increment tokens saved if routed to local model or cache
if (cost < 0.0015) {
pgTokensSaved += tokens;
document.getElementById("pgTokensVal").innerText = pgTokensSaved;
}
document.getElementById("pgCacheHitVal").innerText = Math.round((pgCacheHits / pgTotalReqs) * 100) + "%";
// Idle pipeline status
document.getElementById("pgPipelineStatus").innerText = "COMPLETED";
document.getElementById("pgPipelineStatus").style.color = "var(--accent-emerald)";
pgIsProcessing = false;
}
// Live Stepper Simulation Code
const simulatedOutputs = {
math: [
{ backend: 'ollama', output: '5', score: 0.0 },
{ backend: 'vllm', output: '6', score: 0.0 },
{ backend: 'openai', output: '7', score: 1.0 }
],
code: [
{ backend: 'ollama', output: 'def quicksort(arr): return arr', score: 0.3 },
{ backend: 'vllm', output: 'def quicksort(arr):\n if len(arr) <= 1: return arr\n pivot = arr[0]...', score: 0.8 },
{ backend: 'openai', output: 'def quicksort(arr):\n if len(arr) <= 1: return arr\n pivot = arr[len(arr)//2]\n ...', score: 1.0 }
],
greeting: [
{ backend: 'ollama', output: 'Hello there!', score: 0.9 },
{ backend: 'vllm', output: 'Hello! How can I help you today?', score: 1.0 },
{ backend: 'openai', output: 'Greetings! I am here to assist you.', score: 1.0 }
]
};
let simInterval = null;
function runSimulation() {
if (simInterval) clearInterval(simInterval);
const tau = parseFloat(document.getElementById("simTauSlider").value);
const queryType = document.getElementById("simQueryType").value;
const steps = simulatedOutputs[queryType];
const consoleBox = document.getElementById("simConsole");
consoleBox.innerHTML = "Starting cascade routing simulation...<br>";
// Reset nodes
const backends = ['ollama', 'vllm', 'openai'];
backends.forEach(b => {
const node = document.getElementById(`simNode_${b}`);
const badge = document.getElementById(`simBadge_${b}`);
const outputDiv = document.getElementById(`simOutput_${b}`);
node.className = "sim-step-node";
badge.innerText = "Pending";
badge.className = "node-badge";
outputDiv.innerText = "Waiting to run...";
});
let stepIdx = 0;
function executeStep() {
if (stepIdx >= steps.length) {
consoleBox.innerHTML += "Cascade completed. All models evaluated.<br>";
return;
}
const step = steps[stepIdx];
const node = document.getElementById(`simNode_${step.backend}`);
const badge = document.getElementById(`simBadge_${step.backend}`);
const outputDiv = document.getElementById(`simOutput_${step.backend}`);
// Set node active
node.className = "sim-step-node active";
badge.innerText = "Running...";
consoleBox.innerHTML += `Querying backend: ${step.backend.toUpperCase()}...<br>`;
setTimeout(() => {
outputDiv.innerText = step.output;
const score = step.score;
const accepted = score >= tau;
consoleBox.innerHTML += `-> ${step.backend.toUpperCase()} output score: ${score.toFixed(2)} (Threshold: ${tau.toFixed(2)})<br>`;
if (accepted || stepIdx === steps.length - 1) {
node.className = "sim-step-node accepted";
badge.innerText = accepted ? "Accepted" : "Terminal Accept";
consoleBox.innerHTML += `✔ [ACCEPTED] Cascade stopped at tier: ${step.backend.toUpperCase()}<br>`;
} else {
node.className = "sim-step-node escalated";
badge.innerText = "Escalated";
consoleBox.innerHTML += `❌ [ESCALATED] Score ${score.toFixed(2)} < Threshold ${tau.toFixed(2)}. Escalating...<br>`;
stepIdx++;
executeStep();
}
}, 1000);
}
executeStep();
}
</script>
</body>
</html>
|