2026年7月5日 2 分钟阅读

Two-Tier Memory 实战教程:给 AI 编码 Agent 装上查询式长期记忆,1000 条解决记录不占窗口

tinyash 0 条评论

你用过 Claude Code 或 Cursor 几天后,大概率遇到过这个场景:Agent 在一个新会话里重新解决上周已经搞定过的问题,或者做出一项与前几天的架构决策完全矛盾的选择。你责怪模型不够聪明。但真正的问题,出在记忆系统上。

AI 编码 Agent 的”长期记忆”默认是一堆 Markdown 文件——每次启动会话时全部加载到上下文中。10 个文件没问题。140 个文件就开始悄悄截断。Agent 以为自己在认真工作,实际上它已经忘了上下文窗口边缘之外的一切。

Two-Tier Memory 是一个纯 Python CLI 工具(MIT 许可证),用一个极简的两层架构解决了这个问题:一层永不超载的索引 + 一层按需查询的数据库。整个工具只有 4 个文件、0 个外部依赖、200 多行代码,但思路来自数据库领域 1970 年就已被验证的关系模型。

问题根源:Agent 的”装下一切”记忆模式

先看一个场景。你让 Claude Code 在一个项目中工作了两个月,积累了几十个 ADR、架构决策、排错记录和编码约定。项目里有一个 memory/ 目录,里面是 60 个 Markdown 文件。

每次启动新会话,Agent 的启动指令说:”加载 memory/ 下所有文件作为上下文。”于是 60 个文件挤进同一个上下文窗口。每个文件开头几段被完整加载,文件后半部分被截断。Agent 读到的是零散的、不完整的信息碎片。

你发现 Agent 在重复上周已经讨论过的 API 选择,而且给出的理由和前一次决策完全相反。你以为是模型变笨了。实际上,那篇 API 选择的文档被截断到了只剩标题,Agent 根本没读到关键决策依据。

Two-Tier Memory 的思路很简单:别把整本书塞进背包,只带目录出门,需要哪章去图书馆查。

两层架构:INDEX + SQLite

这个工具就两个核心概念:

Tier 1 — 索引(INDEX.md),始终加载。 每一条已解决的问题在索引中占一行:标题 + 文件内指针。索引文件很小,50 条记录大约 2KB,永远塞不满上下文窗口。它的使命是告诉 Agent 有什么东西存在,不告诉它具体细节。索引由 Tier 2 自动生成,永远不会过期。

Tier 2 — 数据库(SQLite),按需查询。 每一个硬问题的解决记录变成 SQLite 表中的一行。字段包括问题描述、根因分析、解决方案、踩坑点、成果物路径。Agent 只有在遇到疑似相关的问题时,才通过 FTS5 全文搜索查询数据库——1000 行记录在查询之前零成本。

这个分层设计的关键洞察是:Agent 不需要在上下文里装下所有知识,只需要知道 去哪里查。索引轻到可以随身携带,数据库深到足够容纳整个项目的经验积累。

实战部署:5 分钟初始化

Two-Tier Memory 不需要任何安装步骤。Python 3 标准库自带 sqlite3 模块,唯一的要求就是 Python 3.6+。

git clone https://github.com/tadelstein9/two-tier-memory
cd two-tier-memory

python3 memory.py init

init 命令做三件事:创建 memory.db(SQLite 数据库,含 FTS5 全文索引)、创建 schema.sql(建表脚本供查看)、生成初始 INDEX.md(当前为空,因为还没有记录)。

初始化完成后,项目目录结构如下:

two-tier-memory/
├── memory.py       # CLI 入口,6 个子命令
├── schema.sql      # 数据库 Schema(仅供参考)
├── INDEX.md        # Tier-1 索引(自动生成,可提交到 Git)
├── memory.db       # Tier-2 数据库(git-ignored)

memory.db 默认被 .gitignore 忽略——你的解决记录不会污染版本仓库。INDEX.md 由工具自动生成且体积极小,可以提交到仓库供团队成员共享索引。

实战记录:存下你解决过的每个硬问题

工具的日常使用只有三个操作:记录、查询、同步索引。

记录一个解决经验

当 Agent 解决了一个真正棘手的问题时,把它记下来:

python3 memory.py add \
  --area db \
  --title "SQLite can't persist a view over an ATTACH-ed database" \
  --problem "CREATE VIEW over an attached db vanished on the next connection" \
  --root-cause "the view binds to the attach alias, not the file" \
  --solution "materialize into the main db, or re-ATTACH and re-create the view on open" \
  --gotcha "no error is raised — the view simply isn't there next session" \
  --tags "sqlite,attach,view"

每个字段都有明确用途:--area 分类问题领域(如 db、deploy、security),--problem--root-cause 记录问题现象和根因,--solution 是一次性写对的方案,--gotcha 记录那些最容易被忽略的细节——往往是下次踩坑的地方。

查询已有经验

新会话开始后,遇到类似问题先查数据库:

python3 memory.py query "attach view disappears"

query 使用 SQLite FTS5 全文搜索,返回最相关的记录摘要。如果结果不够精确,可以用 get 查看单条完整记录:

python3 memory.py get 1

get 输出该记录的全部字段,包括 --gotcha 里的关键信息。

重建索引

新增或修改记录后,执行一次索引同步:

python3 memory.py index

这个命令从数据库读取所有记录,重新生成 INDEX.md——每条记录一行,包含标题和记录的 ID 号。索引文件约 40 字节/条记录,100 条记录不到 4KB,永远在上下文窗口中安全存在。

查看所有记录

python3 memory.py list

list 按时间降序列出所有记录,每条一行。可以快速浏览当前积累的所有经验知识。

关键细节:让 Agent 真正用好这个系统

工具本身很简单。让工具发挥作用的是习惯——准确地说,是写入 Agent 项目指令的两个规则:

规则一:遇到新问题先查询,不要直接解决。 Agent 的天性是”解决”而非”查找”。你必须明确告诉它:在尝试任何新方案之前,先用 query 搜索记忆数据库。这条规则是两层的核心——如果 Agent 永远不查,Tier 2 就变成了死数据。

规则二:解决新问题后,立即记录并重建索引。 每次 Agent 解决了一个值得记住的问题(不是语法错误,而是架构决策、踩坑经验、性能优化),就执行一次 add + index。让记录习惯成为工作流的固定环节。

另外两点使用注意事项:

  • 保持记录诚实。 解决问题当天就写进去。等一周后再写,关键细节已经模糊了。同样,如果某个记录被后续发现是错误的,立即删除它——一条过时的记录比空表更有害。
  • 全文搜索有上限。 FTS5 只匹配你输入的关键词,不理解和你的意图。当项目成长到需要语义理解时,可以在相同的 SQLite 表上接入 embedding 向量搜索——但不要一开始就上向量。先让关系模型跑起来。

接入 AI 编码 Agent

将 Two-Tier Memory 接入 Claude Code 或 Codex 很简单。在你的项目根目录的 Agent 指令文件中加入以下两条规则:

## Memory protocol
1. When encountering a hard problem, first run: python3 /path/to/two-tier-memory/memory.py query ""
   - If a relevant solution is found (score > 0), read it with: python3 /path/to/two-tier-memory/memory.py get 
   - Act on the stored solution instead of inventing a new one
2. After solving a novel problem, record it:
   python3 memory.py add --area  --title "" --problem "<problem>" --root-cause "<reason>" --solution "<solution>" --gotcha "<gotcha>" --tags "<tags>"
   python3 memory.py index</pre>
<p>这样配置后,Agent 每次会话启动时都会知道自己有记忆系统可用。索引文件 <code>INDEX.md</code> 如果在项目仓库中,Agent 自然能在上下文中看到它——从而知道有哪些问题已经被解决过,直接跳转到查询阶段。</p>
<h2 class="wp-block-heading">适用场景与局限</h2>
<p>Two-Tier Memory 最适合以下场景:</p>
<ul class="wp-block-list"><li><strong>长期项目积累</strong>:开发周期超过一个月的项目,架构决策和踩坑经验需要跨会话传递</li><li><strong>多 Agent 协作</strong>:多个 Agent 轮班工作时,通过共享 <code>memory.db</code> 或 Git 提交 <code>INDEX.md</code> 实现经验传递</li><li><strong>调试密集型工作</strong>:频繁遇到同类错误模式,需要系统化的经验库</li></ul>
<p>它的局限也很明确:全文搜索而非语义搜索——这意味着查询词必须和记录中的用词接近才能匹配。当记忆库超过 500 条记录后,可以考虑在同样的 SQLite 表上搭建 embedding 向量索引来提升召回率。不过对于大多数团队来说,500 条记录以内的 FTS5 全文搜索已经足够高效。</p>
<h2 class="wp-block-heading">结语</h2>
<p>Two-Tier Memory 的核心贡献不是代码量(总共 200 多行),而是它提醒了我们一件事:AI Agent 的记忆问题本质上是一个信息架构问题,不是模型能力问题。在向上下文窗口里硬塞更多 token 之前,先问问自己——你的 Agent 需要的到底是更大的背包,还是一个更好的图书馆目录?</p>
<p><strong>相关链接</strong></p>
<ul class="wp-block-list"><li><a href="https://github.com/tadelstein9/two-tier-memory" target="_blank" rel="noopener noreferrer">Two-Tier Memory GitHub(MIT)</a></li><li><a href="https://tomadelstein.substack.com/p/your-ais-memory-breaks-on-real-work" target="_blank" rel="noopener noreferrer">Companion Essay:Your AI’s Memory Breaks on Real Work</a></li><li><a href="https://www.sqlite.org/fts5.html" target="_blank" rel="noopener noreferrer">SQLite FTS5 全文搜索文档</a></li></ul>                    </div>

                                                                <div class="single-tags">
                                                            <a href="https://www.tinyash.com/blog/tag/ai/" class="tag-pill">AI</a>
                                                            <a href="https://www.tinyash.com/blog/tag/ai-%e5%b7%a5%e5%85%b7/" class="tag-pill">AI 工具</a>
                                                            <a href="https://www.tinyash.com/blog/tag/ai-%e7%bc%96%e7%a8%8b/" class="tag-pill">AI 编程</a>
                                                            <a href="https://www.tinyash.com/blog/tag/python/" class="tag-pill">python</a>
                                                            <a href="https://www.tinyash.com/blog/tag/%e5%bc%80%e5%8f%91%e5%b7%a5%e5%85%b7/" class="tag-pill">开发工具</a>
                                                            <a href="https://www.tinyash.com/blog/tag/%e5%bc%80%e6%ba%90/" class="tag-pill">开源</a>
                                                            <a href="https://www.tinyash.com/blog/tag/%e6%95%99%e7%a8%8b/" class="tag-pill">教程</a>
                                                    </div>
                    
                    <nav class="single-pagination">
                        <div class="single-pagination-item">
                            <a href="https://www.tinyash.com/blog/dart-agent-core-flutter-tutorial/" rel="prev"><span class="nav-label">上一篇</span><strong>Dart Agent Core 实战教程:在 Flutter 应用中集成 AI Agent,给移动端加上智能对话能力</strong></a>                        </div>
                        <div class="single-pagination-item">
                            <a href="https://www.tinyash.com/blog/speck-spec-driven-agentic-compiler-complete-guide-2/" rel="next"><span class="nav-label">下一篇</span><strong>Speck 完全指南:用规格驱动 AI 编码 Agent,让代码生成可复现、可验证</strong></a>                        </div>
                    </nav>

                                            
<section id="comments" class="comments-area">
    
    	<div id="respond" class="comment-respond">
		<h3 class="comment-reply-title">发表评论 <small><a rel="nofollow" id="cancel-comment-reply-link" href="/blog/two-tier-memory-tutorial/#respond" style="display:none;">取消回复</a></small></h3><form action="https://www.tinyash.com/wp-comments-post.php" method="post" id="commentform" class="comment-form comment-form-shell"><p class="comment-notes">你的邮箱地址不会被公开,带 * 的为必填项。</p><p class="comment-form-comment"><label for="comment">评论内容</label><textarea id="comment" name="comment" rows="8" placeholder="写下你的观点、经验或补充内容……" required></textarea></p><p class="comment-form-author"><label for="author">显示名称 *</label><input id="author" name="author" type="text" value="" placeholder="怎么称呼你" required></p>
<p class="comment-form-email"><label for="email">邮箱 *</label><input id="email" name="email" type="email" value="" placeholder="用于接收回复通知" required></p>
<p class="comment-form-url"><label for="url">网站</label><input id="url" name="url" type="url" value="" placeholder="可选,填写你的博客或主页"></p>
<p class="comment-form-cookies-consent"><input id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes" /> <label for="wp-comment-cookies-consent">在此浏览器中保存我的显示名称、邮箱地址和网站地址,以便下次评论时使用。</label></p>
<p class="form-submit"><input name="submit" type="submit" id="submit" class="submit" value="提交评论" /> <input type='hidden' name='comment_post_ID' value='3543' id='comment_post_ID' />
<input type='hidden' name='comment_parent' id='comment_parent' value='0' />
</p></form>	</div><!-- #respond -->
	</section>
                                    </div>

            </div>

        </article>
    </main>

    <aside class="single-floating-ad" aria-label="Article ads">
        <section class="floating-ad-card">
            <div class="floating-ad-panel-head">
                <div class="floating-ad-panel-kicker">
                    <span class="floating-ad-panel-badge">精选推荐</span>
                    <span class="floating-ad-panel-brand">RECOMMEND</span>
                </div>
            </div>

            <div class="floating-ad-list">
                                    <article class="floating-ad-item">
                        <div class="floating-ad-topline">
                            <div class="floating-ad-meta">
                                <span class="floating-ad-badge">智谱AI</span>
                                <span class="floating-ad-dot" aria-hidden="true"></span>
                            </div>
                            <a
                                class="floating-ad-button"
                                href="https://www.bigmodel.cn/glm-coding?ic=FI8SD1HDNI"
                                data-ad-link
                                data-ad-name="🙋 蹲队友拼智谱 Coding Plan"
                                data-ad-url="https://www.bigmodel.cn/glm-coding?ic=FI8SD1HDNI"
                                target="_blank" rel="noopener noreferrer sponsored"                            >
                                立即参与                            </a>
                        </div>
                        <h3 class="floating-ad-title">🙋 蹲队友拼智谱 Coding Plan</h3>
                                                    <p class="floating-ad-text">🧩 国内顶流编程大模型,20+ 主流工具全适配,性价比拉满</p>
                                                                            <p class="floating-ad-note">拼好模活动,开发者必备</p>
                                            </article>
                                    <article class="floating-ad-item">
                        <div class="floating-ad-topline">
                            <div class="floating-ad-meta">
                                <span class="floating-ad-badge">腾讯云</span>
                                <span class="floating-ad-dot" aria-hidden="true"></span>
                            </div>
                            <a
                                class="floating-ad-button"
                                href="https://cloud.tencent.com/act/cps/redirect?redirect=6150&cps_key=8319c55c294a8841b3277df2e0b29861&from=console"
                                data-ad-link
                                data-ad-name="🚀 腾讯云活动专区"
                                data-ad-url="https://cloud.tencent.com/act/cps/redirect?redirect=6150&cps_key=8319c55c294a8841b3277df2e0b29861&from=console"
                                target="_blank" rel="noopener noreferrer sponsored"                            >
                                点击查看                            </a>
                        </div>
                        <h3 class="floating-ad-title">🚀 腾讯云活动专区</h3>
                                                    <p class="floating-ad-text">💻 4核4G服务器新客 38元/年起,香港地域低至 6.5 折/月</p>
                                                                            <p class="floating-ad-note">活动价格以官网为准</p>
                                            </article>
                                    <article class="floating-ad-item">
                        <div class="floating-ad-topline">
                            <div class="floating-ad-meta">
                                <span class="floating-ad-badge">阿里云</span>
                                <span class="floating-ad-dot" aria-hidden="true"></span>
                            </div>
                            <a
                                class="floating-ad-button"
                                href="https://www.aliyun.com/benefit/ai/aistar?userCode=c5f58gmx&clubBiz=subTask..12407308..10263.."
                                data-ad-link
                                data-ad-name="🙋 AI焕新季,马上用千问"
                                data-ad-url="https://www.aliyun.com/benefit/ai/aistar?userCode=c5f58gmx&clubBiz=subTask..12407308..10263.."
                                target="_blank" rel="noopener noreferrer sponsored"                            >
                                立即前往                            </a>
                        </div>
                        <h3 class="floating-ad-title">🙋 AI焕新季,马上用千问</h3>
                                                    <p class="floating-ad-text">🧩 AI 大模型入门套餐首购低至 4.5 折</p>
                                                                            <p class="floating-ad-note">领1728元礼包</p>
                                            </article>
                                    <article class="floating-ad-item">
                        <div class="floating-ad-topline">
                            <div class="floating-ad-meta">
                                <span class="floating-ad-badge">阿里云</span>
                                <span class="floating-ad-dot" aria-hidden="true"></span>
                            </div>
                            <a
                                class="floating-ad-button"
                                href="https://www.aliyun.com/activity/ecs/clawdbot?userCode=c5f58gmx"
                                data-ad-link
                                data-ad-name="🦞 OpenClaw"
                                data-ad-url="https://www.aliyun.com/activity/ecs/clawdbot?userCode=c5f58gmx"
                                target="_blank" rel="noopener noreferrer sponsored"                            >
                                领养龙虾                            </a>
                        </div>
                        <h3 class="floating-ad-title">🦞 OpenClaw</h3>
                                                    <p class="floating-ad-text">⚡ 分钟级部署 OpenClaw,低至 68 元 1 年,专属你的 AI 管家</p>
                                                                            <p class="floating-ad-note">自动帮你干活,适合个人和团队</p>
                                            </article>
                            </div>
        </section>
    </aside>

<aside class="single-rail" aria-label="工具推荐">
    <section class="single-rail-card">
        <div class="single-rail-panel">
            <div class="single-rail-panel-head">
                <div class="single-rail-panel-kicker">
                    <span class="single-rail-panel-badge">工具推荐</span>
                    <span class="single-rail-panel-brand">TINYASH TOOL</span>
                </div>
            </div>

            <h3 class="single-rail-panel-title">效率工具,一站直达</h3>
            <p class="single-rail-panel-text">
                常用工具都在这里,打开即用                <a
                    href="https://www.tinyash.com/tool"
                    target="_blank"
                    rel="noopener noreferrer"
                    class="tool-promo-link"
                >www.tinyash.com/tool</a>
            </p>

            <div class="single-rail-panel-list">
                <span>Markdown</span>
                <span>图片处理</span>
                <span>开发调试</span>
                <span>效率工具</span>
            </div>

            <div class="single-rail-panel-actions">
                <a
                    class="tool-promo-btn tool-promo-btn--primary"
                    href="https://www.tinyash.com/tool"
                    target="_blank"
                    title="打开工具站后按 Ctrl+D 收藏"
                >
                    去逛工具站                </a>
            </div>
        </div>
    </section>
</aside>


    <footer id="colophon" class="site-footer">
        <div class="footer-panel footer-panel-minimal">
            <div class="footer-minimal-top">
                <div class="footer-brandline">
                    <span class="footer-site-name">小灰灰的笔记</span>
                    <span class="footer-site-desc">博客 | 工具 | AI</span>
                </div>

                            </div>

            <div class="footer-minimal-bottom">
                <p class="footer-copyline">Copyright © 2023-2026 TinyAsh All rights reserved</p>

                                    <div class="footer-records">
                                                                                    <a class="footer-icp footer-icp-primary" href="https://beian.mps.gov.cn/#/query/webSearch?code=44522102000345" target="_blank" rel="noreferrer">
                                    <img src="https://www.tinyash.com/wp-content/uploads/2026/03/beian.png" alt="beian" width="17">
                                    <span>粤公网安备44522102000345</span>
                                </a>
                                                    
                                                                                    <a class="footer-icp footer-icp-secondary" id="beian" href="https://beian.miit.gov.cn/" target="_blank" rel="noopener noreferrer">粤ICP备2024257007号</a>
                                                                        </div>
                            </div>
        </div>
    </footer>
</div>


		
		



<script data-jetpack-boost="ignore" id="wp-emoji-settings" type="application/json">
{"baseUrl":"https://s.w.org/images/core/emoji/17.0.2/72x72/","ext":".png","svgUrl":"https://s.w.org/images/core/emoji/17.0.2/svg/","svgExt":".svg","source":{"concatemoji":"https://www.tinyash.com/wp-includes/js/wp-emoji-release.min.js?ver=8c519c7b8f6b1a331f94817f24cd906e"}}
</script>

<script src="https://www.googletagmanager.com/gtag/js?id=GT-55BFBN8M" id="google_gtagjs-js" async></script><script id="google_gtagjs-js-after">
window.dataLayer = window.dataLayer || [];function gtag(){dataLayer.push(arguments);}
gtag("set","linker",{"domains":["www.tinyash.com"]});
gtag("js", new Date());
gtag("set", "developer_id.dZTNiMT", true);
gtag("config", "GT-55BFBN8M", {"googlesitekit_post_type":"post","googlesitekit_post_date":"20260705"});
//# sourceURL=google_gtagjs-js-after
</script><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2107381354786739&host=ca-host-pub-2644536267352236" crossorigin="anonymous"></script><script type="speculationrules">
{"prefetch":[{"source":"document","where":{"and":[{"href_matches":"/*"},{"not":{"href_matches":["/wp-*.php","/wp-admin/*","/wp-content/uploads/*","/wp-content/*","/wp-content/plugins/*","/wp-content/themes/tinyash/*","/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]}
</script><script>window.addEventListener( 'load', function() {
				document.querySelectorAll( 'link' ).forEach( function( e ) {'not all' === e.media && e.dataset.media && ( e.media = e.dataset.media, delete e.dataset.media );} );
				var e = document.getElementById( 'jetpack-boost-critical-css' );
				e && ( e.media = 'not all' );
			} );</script><script id="modern-blog-theme-main-js-extra">
var ModernBlogTheme = {"homeUrl":"https://www.tinyash.com/","themePreference":"light","copiedText":"\u94fe\u63a5\u5df2\u590d\u5236\u3002","copyFailedText":"\u590d\u5236\u5931\u8d25\uff0c\u8bf7\u624b\u52a8\u590d\u5236\u3002","openMenuText":"\u6253\u5f00\u83dc\u5355","closeMenuText":"\u5173\u95ed\u83dc\u5355","adFeedUrl":"https://www.tinyash.com/api/ads","adClickUrl":"https://www.tinyash.com/api/ads/click","backToTopText":"\u8fd4\u56de\u9876\u90e8"};
//# sourceURL=modern-blog-theme-main-js-extra
</script><script type='text/javascript' src='https://www.tinyash.com/wp-content/boost-cache/static/61cd1562ce.min.js'></script><script src="https://www.tinyash.com/wp-content/plugins/enlighter/cache/enlighterjs.min.js?ver=1PQuFilr8orbOLi" id="enlighterjs-js"></script><script id="enlighterjs-js-after">
!function(e,n){if("undefined"!=typeof EnlighterJS){var o={"selectors":{"block":"pre.EnlighterJSRAW","inline":"code.EnlighterJSRAW"},"options":{"indent":4,"ampersandCleanup":true,"linehover":true,"rawcodeDbclick":false,"textOverflow":"break","linenumbers":true,"theme":"beyond","language":"generic","retainCssClasses":false,"collapse":false,"toolbarOuter":"","toolbarTop":"{BTN_RAW}{BTN_COPY}{BTN_WINDOW}{BTN_WEBSITE}","toolbarBottom":""}};(e.EnlighterJSINIT=function(){EnlighterJS.init(o.selectors.block,o.selectors.inline,o.options)})()}else{(n&&(n.error||n.log)||function(){})("Error: EnlighterJS resources not loaded yet!")}}(window,console);
//# sourceURL=enlighterjs-js-after
</script><script type="module">
/*! This file is auto-generated */
const a=JSON.parse(document.getElementById("wp-emoji-settings").textContent),o=(window._wpemojiSettings=a,"wpEmojiSettingsSupports"),s=["flag","emoji"];function i(e){try{var t={supportTests:e,timestamp:(new Date).valueOf()};sessionStorage.setItem(o,JSON.stringify(t))}catch(e){}}function c(e,t,n){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);t=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(n,0,0);const a=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);return t.every((e,t)=>e===a[t])}function p(e,t){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);var n=e.getImageData(16,16,1,1);for(let e=0;e<n.data.length;e++)if(0!==n.data[e])return!1;return!0}function u(e,t,n,a){switch(t){case"flag":return n(e,"\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f","\ud83c\udff3\ufe0f\u200b\u26a7\ufe0f")?!1:!n(e,"\ud83c\udde8\ud83c\uddf6","\ud83c\udde8\u200b\ud83c\uddf6")&&!n(e,"\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f","\ud83c\udff4\u200b\udb40\udc67\u200b\udb40\udc62\u200b\udb40\udc65\u200b\udb40\udc6e\u200b\udb40\udc67\u200b\udb40\udc7f");case"emoji":return!a(e,"\ud83e\u1fac8")}return!1}function f(e,t,n,a){let r;const o=(r="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?new OffscreenCanvas(300,150):document.createElement("canvas")).getContext("2d",{willReadFrequently:!0}),s=(o.textBaseline="top",o.font="600 32px Arial",{});return e.forEach(e=>{s[e]=t(o,e,n,a)}),s}function r(e){var t=document.createElement("script");t.src=e,t.defer=!0,document.head.appendChild(t)}a.supports={everything:!0,everythingExceptFlag:!0},new Promise(t=>{let n=function(){try{var e=JSON.parse(sessionStorage.getItem(o));if("object"==typeof e&&"number"==typeof e.timestamp&&(new Date).valueOf()<e.timestamp+604800&&"object"==typeof e.supportTests)return e.supportTests}catch(e){}return null}();if(!n){if("undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas&&"undefined"!=typeof URL&&URL.createObjectURL&&"undefined"!=typeof Blob)try{var e="postMessage("+f.toString()+"("+[JSON.stringify(s),u.toString(),c.toString(),p.toString()].join(",")+"));",a=new Blob([e],{type:"text/javascript"});const r=new Worker(URL.createObjectURL(a),{name:"wpTestEmojiSupports"});return void(r.onmessage=e=>{i(n=e.data),r.terminate(),t(n)})}catch(e){}i(n=f(s,u,c,p))}t(n)}).then(e=>{for(const n in e)a.supports[n]=e[n],a.supports.everything=a.supports.everything&&a.supports[n],"flag"!==n&&(a.supports.everythingExceptFlag=a.supports.everythingExceptFlag&&a.supports[n]);var t;a.supports.everythingExceptFlag=a.supports.everythingExceptFlag&&!a.supports.flag,a.supports.everything||((t=a.source||{}).concatemoji?r(t.concatemoji):t.wpemoji&&t.twemoji&&(r(t.twemoji),r(t.wpemoji)))});
//# sourceURL=https://www.tinyash.com/wp-includes/js/wp-emoji-loader.min.js
</script></body>
</html>
<!--
Performance optimized by Redis Object Cache. Learn more: https://wprediscache.com

使用 Predis (v2.4.0) 从 Redis 检索了 1510 个对象 (529 KB)。
-->

<!-- Dynamic page generated in 0.842 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2026-07-05 14:17:13 -->

<!-- Compression = gzip -->