This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
LLMAPI:保持它 活生生的和活着的 ,春金与Caching
Thursday, 06 November 2025
一. 导言导言 导言 导言 导言
在我的LLMApi项目中, 我想能够支持对数据 LOTS 的询问@;}然而,LMs有非常有限的数据 他们可以一次性输出...";" 和是'
此外,还有上下文的问题 ,}一个伟大的特点 但直到现在为止 只要应用程序能持续到某个环境 所以这增加了对滑动缓存的充分支持 如果您离开正在运行的模拟器.}
弹出 & 缓存系统
释放@1.8.0 -#高级性能 @&_资源管理
本文件介绍两个强大的系统,它们使 mostlylucid.mockllmapi 高效的,和生产 自动跳键 和 反应缓存.
快速启动@: @ 见见 踢打和追击 @. @http 显示所有特性的 HTTP 示例@ . @
目录目录
自动跳键
什么是自动 -_ chunking_?}
Auto-chunking 是一个智能系统, 当大请求超过您的 LLM\ @ '}符号限制% MS K2 时, 可以自动将大型请求折成最佳块@ title 默认启用的 It@ ' @%s 并透明地工作... ..."—,你没有''"不需要改变您的API调用吗?
问题解决
请求具有复杂形状的“ 100” 项目可能会产生超过您的 LLM @ MS K1}%s 输出代号限制的响应@ ( 典型地 {2048-4096} ), matters @ MPK4} 导致回复中断或失败=.}
解决方案
系统@: @%
- 估计数估计数 基于形状复杂性的当值使用
- 计算 符合限制范围内的最佳块块大小
- 执行 自动请求多个LLM
- 维护者 使用上下文横跨块的一致一致性
- 组合 形成单一无缝反应的结果
弹头配置
添加到 appsettings.json:
{
"MockLlmApi": {
"BaseUrl": "http://localhost:11434/v1/",
"ModelName": "llama3",
// Auto-Chunking Settings
"MaxOutputTokens": 2048, // LLM output limit (default: 2048)
"EnableAutoChunking": true, // Enable automatic chunking (default: true)
"MaxItems": 1000, // Maximum items per response (default: 1000)
// Input Token Settings
"MaxInputTokens": 2048 // LLM input limit (default: 2048)
}
}
配置选项解析
| @ | _ 设置@ | _ 默认 @ | } 描述 @ MPK3 |
|---|---|---|---|
MaxOutputTokens @ |
@ 2048 @ @ I | # 您的LLM 最大符號可以產生共同值@ MS K4 @ _ 512 @ *(# 小型號 @ MPK7 @ #2048 @ <(Llama> @MS K10# MS k11 @ (大型號} @) @\ MSC14# | |
EnableAutoChunking |
真实的 @ | 全局启用#/ 禁用自动填充@ | |
MaxItems 超过此限制的请求以警告为上限@ |
@ | ||
MaxInputTokens |
{2048} | 最大快速大小{. 用于在必要时截断上下文历史@ |
如何踢步工作
概览流程
flowchart TD
A[API Request: ?count=100] --> B{Extract Count}
B --> C{Check MaxItems}
C -->|Exceeds| D[Cap at MaxItems]
C -->|Within| E{Check autoChunk param}
D --> E
E -->|false| F[Execute Single Request]
E -->|true/default| G{Estimate Tokens}
G --> H{Will Exceed<br/>MaxOutputTokens?}
H -->|No| F
H -->|Yes| I[Calculate Chunk Strategy]
I --> J[Execute Chunk 1]
J --> K[Build Context for Chunk 2]
K --> L[Execute Chunk 2]
L --> M{More Chunks?}
M -->|Yes| N[Build Context for Next]
M -->|No| O[Combine All Results]
N --> L
O --> P[Return Unified Response]
F --> P
style I fill:#e1f5ff
style O fill:#d4edda
style P fill:#d4edda
1. Tok 光量估计
系统分析您的形状 JSON 来估计每个项目的代号@: @%
// Simple shape → ~50 tokens/item
{"id": 1, "name": ""}
// Complex nested shape → ~200 tokens/item
{
"user": {
"id": 1,
"profile": {
"name": "",
"address": {"street": "", "city": ""},
"contacts": [{"type": "", "value": ""}]
}
}
}
估计系数
- 嵌套深度 (+0.5*x 超过 @2)=%
- 数组计数 (+0.3x 每个阵列@)
- 财产计数 (+0.05x 超过 @5)的每个属性
flowchart LR
A[Shape JSON] --> B[Parse Structure]
B --> C[Count Properties]
B --> D[Measure Nesting Depth]
B --> E[Count Arrays]
C --> F[Base Token Count:<br/>Length / 4]
D --> G[Complexity Multiplier]
E --> G
C --> G
G --> H[Estimated Tokens/Item:<br/>Base × Multiplier]
2. 块大小计算
Available Output Tokens = MaxOutputTokens × 75% (25% reserved for prompt overhead)
Items Per Chunk = Available Output Tokens / Estimated Tokens Per Item
Total Chunks = Ceiling(Requested Items / Items Per Chunk)
实例::
- 请求@: @ @ @ 100}项目
- 形状复杂度@: @ @\ 150 @ matters @ MS K2 @ item
- 最大输出Tokens@ : @ @ MS K1 @
- 可用@: @ @ 1536_ 标语 @ I(2048 @ @ *×} @ MPK4#
- 每个块的項目@: @ @ 10 @ *(1536} @ I/ @ @ @ 150)#
- 结果": {10} @10"每个项目块
3. 块执行
每个块M:
- 接收带有更新计数的修改后的形状
- 获取上一个块的上下文以保持一致
- 执行独立的 LLAM 请求
- 返回 JSON,这是' 解析和累积
4. 保存上下文
随后的块获得上下文, 如 @ : @
IMPORTANT CONTEXT - Multi-part Response (Part 2/10):
This is a continuation of a larger request. Previous parts have generated:
Part 1: 10 items (first: id=1, name="Alice", last: id=10, name="Jane")
Ensure consistency with the above data (IDs, names, relationships, style).
Continue numbering, IDs, and patterns logically from where the previous part left off.
这将确保 ID do't 重新启动\ , names 保持一致@,, 而数据感觉有一致性 @.}
弹出用法示例
示例 @1:_Basic Auto@-_Chunking
# Request 100 users
GET /api/mock/users?count=100
Content-Type: application/json
{
"shape": {
"id": 1,
"name": "string",
"email": "[email protected]"
}
}
发生什么了?
- 系统估计@~100 @signals @/}项目
- 计算 {4} @ 25} 每个项的块数
- 自动执行 {4}%LLM 请求
- 返回 {100} 用户的合并数组
日志@ : @%
[INFO] Request needs chunking: 100 items × 100 tokens/item = 10000 tokens > 1536 available
[INFO] AUTO-CHUNKING ENABLED: Breaking request into 4 chunks (25 items/chunk)
[INFO] AUTO-CHUNKING: Executing chunk 1/4 (items 1-25 of 100)
[INFO] AUTO-CHUNKING: Executing chunk 2/4 (items 26-50 of 100)
[INFO] AUTO-CHUNKING: Executing chunk 3/4 (items 51-75 of 100)
[INFO] AUTO-CHUNKING: Executing chunk 4/4 (items 76-100 of 100)
[INFO] AUTO-CHUNKING COMPLETE: Combined 4 chunks into 100 items
2: Opt- 逐个请求
# Disable chunking for this specific request
GET /api/mock/users?count=100&autoChunk=false
使用时@ : @
- LLM 测试限制
- 您想要看到短时行为
- 调试即时工程
例3:最大项目限制
# Request 2000 items (exceeds MaxItems=1000)
GET /api/mock/products?count=2000
结果#:
[WARN] AUTO-LIMIT: Request for 2000 items exceeds MaxItems limit (1000). Capping to 1000 items
返回 1000}项目自动填充\ MPK1
复式内嵌形状
POST /api/mock/orders?count=50
Content-Type: application/json
{
"shape": {
"orderId": 1,
"customer": {
"id": 1,
"name": "string",
"address": {
"street": "string",
"city": "string",
"country": "string"
}
},
"items": [
{"productId": 1, "name": "string", "quantity": 1, "price": 9.99}
],
"shipping": {"method": "string", "trackingNumber": "string"},
"payment": {"method": "string", "status": "string"}
}
}
发生什么了?
- 系统检测高复杂度 @ ( @ dep besting@ MS K1} 数组=)
- 估测@~300 @ massigns @ /}項目
- 计算 {10} @ 5} 每个项的块数
- 维持各个块的身份证连续性和客户关系
弹序测算
所有块状操作都记录为可观察性@ : @%
调试日志@ : @%
- 计数提取@: @%
Found explicit count in query parameter 'count': 100 - 不需要填块@: @%
No chunking needed for this request
Info Logs:
- 执行决定@: @%
Request needs chunking: 100 items × 150 tokens = 15000 tokens > 1536 available - 战略*:
Chunking strategy: 100 items → 4 chunks × 25 items/chunk - 执行=:
AUTO-CHUNKING: Executing chunk 2/4 (items 26-50 of 100) - 完成@:
AUTO-CHUNKING COMPLETE: Combined 4 chunks into 100 items
警告日志@ : @%
- 限制超过@: @%
AUTO-LIMIT: Request for 2000 items exceeds MaxItems (1000). Capping to 1000
反应缓存
回应是什么 Caching?
回应前-generate多个LLM对同一请求的响应*,将其存储在记忆中,并提供给它们一个{-}byMS K3one,以提供多样性而无需重复LLOM调用.
如何不同
与传统 caching {(} 不同的是, 每时每刻 < ), } 这个系统:\ {
- 产生生成 N变式 按要求
- 每种变式 一次 @(_sliding window #)}#MSKO_滑动窗口@MSK1#
- 在背景中再填充 枯竭时
- 提供 多样性 保持业绩的同时保持绩效
缓存配置
{
"MockLlmApi": {
// Cache Settings
"MaxCachePerKey": 5, // Variants per unique request (default: 5)
"CacheSlidingExpirationMinutes": 15, // Idle time before expiration (default: 15)
"CacheAbsoluteExpirationMinutes": 60, // Max lifetime (default: 60, null = none)
"CacheRefreshThresholdPercent": 50, // Trigger refill at % empty (default: 50)
"MaxItems": 1000, // Max total cached items (default: 1000)
"CachePriority": 1, // Memory priority: 0=Low, 1=Normal, 2=High, 3=Never (default: 1)
// Advanced Cache Options
"EnableCacheStatistics": false, // Track cache hits/misses (default: false)
"EnableCacheCompression": false // Compress cached responses (default: false)
}
}
缓存行为行为
stateDiagram-v2
[*] --> ColdCache: First Request
ColdCache --> Generating: Generate N variants
Generating --> WarmCache: Store variants
WarmCache --> ServingFromCache: Subsequent requests
ServingFromCache --> WarmCache: Variants remaining
ServingFromCache --> RefillTriggered: Last variant served
RefillTriggered --> BackgroundRefill: Async refill
BackgroundRefill --> WarmCache: Refill complete
ServingFromCache --> Expired: 15min idle
Expired --> [*]
note right of ColdCache
Cache miss
5x LLM calls
Slow first response
end note
note right of ServingFromCache
Cache hit
Instant response
No LLM call
end note
note right of BackgroundRefill
Transparent refill
User does not wait
Fresh variants ready
end note
初步请求@( @Cold cache_)
GET /api/mock/users?shape={"id":1,"name":""}
X-Cache-Count: 5
发生什么了?
- 系统立即生成 & 5 @ 变异响应
- 第一种变式
- 在缓存中剩余存储库 @ 4 @%
- 回应时间: 普通的(+Generates 所有变体 )
之后请求@(Warm Cache)
# Request 2
GET /api/mock/users?shape={"id":1,"name":""}
X-Cache-Count: 5
发生什么了?
- 服务于缓存的第二变种
- 缓存中现在剩下了 @ 3 @ 变量
- 回应时间: 即时 (NoLLM呼叫)
# Request 5 (last variant)
GET /api/mock/users?shape={"id":1,"name":""}
X-Cache-Count: 5
发生什么了?
- 取代缓存的第五变种
- 缓存现已为空
- 触发背景填充 新的变体
- 回应时间: 即时
# Request 6 (refill in progress)
GET /api/mock/users?shape={"id":1,"name":""}
X-Cache-Count: 5
发生什么了?
- 填充完成@, 服务来自补充的缓存
- 回应时间: 即时
缓存键唯一性
缓存密钥基于 @ :\
- HTTP 方法 @ (GET,POST},等等@.)
- 带查询字符串的完整路径
- 形状 JSON
不同的请求保留单独的缓存@: @%
GET /api/mock/users?count=10 # Cache Key A
GET /api/mock/users?count=20 # Cache Key B (different count)
GET /api/mock/products?count=10 # Cache Key C (different endpoint)
缓存使用率示例
示例 @1: 能够用查询参数缓存
GET /api/mock/users?count=10
X-Cache-Count: 3
生成“3”变体 “,”按顺序为它们服务“MS K2”
示例 @2: 启用以形状属性缓存
POST /api/mock/users
Content-Type: application/json
{
"shape": {
"$cache": 5,
"id": 1,
"name": "string"
}
}
生成“5”变体@.
3: 禁用缓存
# Don't cache this request
GET /api/mock/random-data?count=10
否 无 X-Cache-Count 或 $cache 表示没有缓冲@ — @ refreshLLM 每次响应\ .
4:
GET /api/mock/users?count=100
X-Cache-Count: 3
**行为举止 : ***
- 弹打是 残疾残疾人 当使用缓存@ ( @ 避免缓存污染时 @ MS K1\ {
- 如果需要填入, 缓存被绕过
- 使用缓存用于小@-_中度响应 @,大块
内装储存
上下文过期
维护各请求之间一致性的 API 环境( @15-_ 分钟滑动到期.
如何运作
gantt
title Context Sliding Window Expiration (15 minutes)
dateFormat mm:ss
axisFormat %M:%S
section Context Lifecycle
Request 1 creates context :milestone, m1, 00:00, 0m
Active (15min window) :active, 00:00, 10m
Request 2 extends window :milestone, m2, 10:00, 0m
Active (window reset) :active2, 10:00, 15m
Request 3 after 20min idle :milestone, m3, 30:00, 0m
Expired - starts fresh :crit, 25:00, 5m
# Request 1
GET /api/mock/users/123?context=user-session-1
# Creates context "user-session-1" with 15-minute expiration
# Request 2 (10 minutes later)
GET /api/mock/orders?context=user-session-1
# Context still exists, expiration resets to 15 minutes
# Request 3 (20 minutes after Request 2, no activity for 20 minutes)
GET /api/mock/profile?context=user-session-1
# Context expired, starts fresh
上下文配置
上下文使用相同的过期设置@: @%
{
"MockLlmApi": {
"MaxInputTokens": 2048 // Contexts are truncated to fit within this limit
}
}
内部储存使用 IMemoryCache 与#:
- 滑动过期@: @% @15 @ minutes @ (# hardcoded@) @ 分钟 @
- Case -不敏感的名字 @: " user@-session @"。
- 自动清理@: @% 自动删除过期环境
- 无内存泄漏@: @% 驱逐回电清理追踪字典
最佳做法
何时使用弹进
使用块值时@ : @
- 正在请求具有复杂形状的 & >\ @ @ MS K1}项目
- 使用嵌套的@ /等级数据
- 要求数百件物品
Donó't 禁用块块, 除非 @
- 测试LLLM象征性限制
- 调试即时工程
- 您想要看到短时行为
何时使用缓存
使用缓存时间@ : @
- 请求模式是重复的@( @e% .}(g) .,}下载数据 ,}参考列表)}
- 不同的模拟用户每次使用“)”
- @( @instant 响应@)#
当“:”到% 1 时, Donñ' @ t缓存@ action
- 每个响应都必须是独一无二的 @ ( @ e @ MPK1} g.,} 随机测试数据生成@ MS K3
- 数据应该为会话@- @ 指定
- 请求量低, @ (cache 管理费不值得@)
最佳配置
小LLMS (EMS K1g.,小喇叭
{
"MaxOutputTokens": 512,
"MaxInputTokens": 1024,
"MaxCachePerKey": 3,
"EnableAutoChunking": true
}
中度LL女士 @(e.g}.,Llama _3):
{
"MaxOutputTokens": 2048,
"MaxInputTokens": 2048,
"MaxCachePerKey": 5,
"EnableAutoChunking": true
}
大型LL女士 @(e.g}.,Llama @MS K3#70B□):
{
"MaxOutputTokens": 4096,
"MaxInputTokens": 4096,
"MaxCachePerKey": 5,
"EnableAutoChunking": true
}
排除故障
弹出问题
问题M: @ "_ 请求 < MS K1} 仅返回\ 50"{ >
解答@: @ 检查弹片执行的日志@ . @ 如果不打块... ,}增加 MaxOutputTokens:
{
"MaxOutputTokens": 4096 // Increase limit
}
问题M: @"_chunks 的IDs与每个块的 (QIDs 重新啟動@1Q}
解答@: @ 这是罕见的LLM行为问题 \ @._ try:}
- 使用不同的模式
- 增加
Temperature创造更多创造力 - 在形状中添加明确的 ID 区域@: @%
{"id": "start at 1 and increment"}
问题M: @"#to Too 产生许多块 生成了@(}(性能冲击) )"
解答@: @
- 简化您的形状 @ ( remove 不必要的嵌套@ MS K1
- 增加
MaxOutputTokens - 减少要求的数
- 使用
?autoChunk=false如果您需要完整数据集, 则不需要完整的数据集@ ' @ }
缓结问题
问题M: @"_same answer 每次回应都一样,
解答@: @ 缓存为空@ , @ 背景填充可能是慢@ MPK1 check @ MS K2}
- LLM服务反应迅速
- 增加
MaxCachePerKey用于更多变式 - 检查“ "” 的日志( Backform re填充抓取失败) @"@%
问题M: " @QCache 没有被使用@" @%
解答@: @ 确保您@ '}用其中之一指定缓存@ I:} @
- 查询参数 @:
?cache=5 - 标题@: @%
X-Cache-Count: 5 - 形状属性@: @%
"$cache": 5
问题M: "-Memory使用量在不断增长
解答@: @
- 减少
MaxCachePerKey-=YTET -伊甸园字幕组=- 翻译: - 减少
CacheSlidingExpirationMinutes速战速决 - 启用
EnableCacheCompression: true用于内存的(trade CPU+) - 减少
MaxItems@(_hard 缓存大小上限@)
背景问题
问题M: @"_Context 在请求之间丢失@"}
解答@: @ 上下文已过期@(15 @ minutes of noactivity @ ).} 如果您需要更长的时间 @ MPK2%
- 更经常地提出请求,以保持背景的活力
- 考虑使用持久性内存存储 ( 未来释放的功能请求@)
问题M: #M"#Context变得太大了#"#
解答@: @ 环境在超过 MaxInputTokens# . 检查#: *
- 日志显示 @ "+Context 摘要@ MS K1 message
- 增加
MaxInputTokens必要时 - 使用较短的上下文名称提高效率
实绩计数
弹头性动作
| “ | 假想”“ | ”没有打全拳的“MS K2”与打全球的“ | 改善” | |
|---|---|---|---|---|
| @ | @ @ 100 @ 简单项目 @ I | @ 转机@ MS K3} 完成 *(4 @ 块 @ MPK5 @ @ | # 工作 vs. 失灵 | |
| @ | }{50} 复杂项目 | } 完成 *(10块 )}MS K6} 工作 vs. 失灵 | ||
| @ | 10 項目 | @#2.3s | }{2.3s□ | 无间接费用 |
缓存性能
| “ | 假想”“ | ”没有缓存,也没有 | 与"缓冲"一起 (和"Warmm) | |
|---|---|---|---|---|
| @ | _简单请求@ | } @ 2.1%s @ | # *0.002%s # | # 动作快一点 |
| -=YTET -伊甸园字幕组=- 翻译: 动作快一点 | ||||
| @ | }第一個請求 | MS K2 @s | @ *10.5 #s MPK5# 變式@)#_ | # -=YTET -伊甸园字幕组=- 翻译: |
内存使用
| 配置 @ | 估计内存@ | ||
|---|---|---|---|
| 甲基溴基准量 | |||
| @100}键盘 :# | #MB # | # | |
| @1000}键盘 :# | #MB # | # | |
| @ | 内装贮存@(100 活动=) | #+10 MB□ | # |
版本历史
- {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}我... - 自动解锁和强化缓存的初始释放
- {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}我... - 基本缓存系统
- {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}我... 引入了内装储存
详情请见 重新释放吗? 不,不!.