<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/scripts/pretty-feed-v3.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:h="http://www.w3.org/TR/html4/"><channel><title>Ouonnki Space</title><description>Sharing snippets of technology and life.</description><link>https://ouonnki.site</link><item><title>多模态AI的真正落地：从看图说话到理解世界</title><link>https://ouonnki.site/blog/ai/multimodal-ai-reality</link><guid isPermaLink="true">https://ouonnki.site/blog/ai/multimodal-ai-reality</guid><description>多模态AI已经从&quot;看图说话&quot;进化到理解UI、分析视频、辅助开发。这篇聊聊它的真实能力、应用场景和当前局限。</description><pubDate>Fri, 13 Feb 2026 22:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;不只是&quot;看图说话&quot;&lt;/h2&gt;
&lt;p&gt;2024年的多模态AI，大部分时候还停留在&quot;描述一下这张图片&quot;的水平。你给它一张猫的照片，它告诉你&quot;这是一只橘猫&quot;——准确但无聊。&lt;/p&gt;
&lt;p&gt;2026年的多模态AI，已经是完全不同的物种了。&lt;/p&gt;
&lt;p&gt;它能看一张UI截图，直接告诉你哪个按钮对齐有问题。它能看一段代码的报错截图，直接给出修复方案。它能看一个视频片段，总结出关键信息并标注时间戳。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;从识别到理解，这是质的飞跃。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;视觉理解：现在能做什么？&lt;/h2&gt;
&lt;h3&gt;UI理解与自动化&lt;/h3&gt;
&lt;p&gt;这是我觉得最实用的场景。给AI一张网页截图，它能：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;识别出所有可交互元素（按钮、输入框、链接）&lt;/li&gt;
&lt;li&gt;理解页面的布局结构和层级关系&lt;/li&gt;
&lt;li&gt;发现设计上的不一致（间距、字体、颜色）&lt;/li&gt;
&lt;li&gt;生成对应的HTML/CSS代码&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/posts/multimodal-vision.jpg&quot; alt=&quot;视觉理解应用&quot;&gt;&lt;/p&gt;
&lt;p&gt;我最近在用的一个工作流：截图 → Claude分析 → 生成修复代码 → 自动提交。整个过程不到30秒，以前可能要对着设计稿对半天。&lt;/p&gt;
&lt;p&gt;更厉害的是&lt;strong&gt;浏览器自动化&lt;/strong&gt;。像OpenClaw这样的工具，AI可以直接&quot;看&quot;浏览器画面，理解当前页面状态，然后执行点击、输入等操作。不需要写CSS选择器，不需要XPath——AI看到什么就操作什么，跟人类一样。&lt;/p&gt;
&lt;h3&gt;文档和图表理解&lt;/h3&gt;
&lt;p&gt;以前OCR只能识别文字。现在的多模态AI能理解文档的&lt;strong&gt;语义结构&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;给它一份PDF报告，它不只是提取文字，还能理解：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;表格数据之间的关系&lt;/li&gt;
&lt;li&gt;图表传达的趋势&lt;/li&gt;
&lt;li&gt;注释和正文的对应关系&lt;/li&gt;
&lt;li&gt;整体的论证逻辑&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这对于研究人员、分析师、律师来说是巨大的效率提升。&lt;/p&gt;
&lt;h3&gt;代码理解的视觉维度&lt;/h3&gt;
&lt;p&gt;这个场景可能被低估了。当你把一个报错截图、一个终端输出、或者一个架构图发给AI的时候，它能结合视觉和文本信息给出更准确的判断。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/posts/multimodal-code.jpg&quot; alt=&quot;代码与多模态&quot;&gt;&lt;/p&gt;
&lt;p&gt;比如你截了一张浏览器控制台的图，里面有红色的error、黄色的warning、还有stack trace。AI不仅能读出文字内容，还能通过颜色和位置理解哪些是相关的错误、哪个是root cause。&lt;/p&gt;
&lt;h2&gt;视频分析：下一个前沿&lt;/h2&gt;
&lt;p&gt;图片理解已经比较成熟了，视频分析则是2026年正在快速发展的方向。&lt;/p&gt;
&lt;h3&gt;当前能做的&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;视频摘要&lt;/strong&gt;——给一段10分钟的视频，AI能生成带时间戳的摘要&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;关键帧提取&lt;/strong&gt;——自动识别视频中信息密度最高的画面&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内容审核&lt;/strong&gt;——检测不当内容，远比传统算法准确&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;教程分析&lt;/strong&gt;——看一段编程教程视频，提取出代码和操作步骤&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/posts/video-analysis.jpg&quot; alt=&quot;视频分析AI&quot;&gt;&lt;/p&gt;
&lt;h3&gt;Google Gemini的优势&lt;/h3&gt;
&lt;p&gt;在视频理解这个赛道上，Gemini目前是领先的。它原生支持长视频输入，不需要先切帧再逐帧分析。你可以直接丢一个小时的视频给它，然后问任何关于视频内容的问题。&lt;/p&gt;
&lt;p&gt;GPT-5和Claude也在追赶，但在处理长视频方面，Gemini的架构优势还是明显的。&lt;/p&gt;
&lt;h2&gt;各家模型多模态能力对比&lt;/h2&gt;
&lt;p&gt;说说我的实际使用体验：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Claude Opus 4&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;图片理解：⭐⭐⭐⭐⭐ 最细致，能注意到微小细节&lt;/li&gt;
&lt;li&gt;UI分析：⭐⭐⭐⭐⭐ 最好的UI理解能力，非常适合前端开发&lt;/li&gt;
&lt;li&gt;视频：⭐⭐⭐ 支持但不是强项&lt;/li&gt;
&lt;li&gt;特点：对图片的推理能力最强，不只是描述而是真正的理解&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;GPT-5&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;图片理解：⭐⭐⭐⭐⭐ 全面且准确&lt;/li&gt;
&lt;li&gt;UI分析：⭐⭐⭐⭐ 很好但偶尔会忽略细节&lt;/li&gt;
&lt;li&gt;视频：⭐⭐⭐⭐ 支持较长视频&lt;/li&gt;
&lt;li&gt;特点：最均衡，各方面都不差&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Gemini 2.5 Pro&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;图片理解：⭐⭐⭐⭐ 准确但有时不够深入&lt;/li&gt;
&lt;li&gt;UI分析：⭐⭐⭐⭐ 不错&lt;/li&gt;
&lt;li&gt;视频：⭐⭐⭐⭐⭐ 这个赛道的王者&lt;/li&gt;
&lt;li&gt;特点：长视频和多图理解是杀手级场景&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;开源模型（Llama 4 / Qwen-VL）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;图片理解：⭐⭐⭐⭐ 追上来了&lt;/li&gt;
&lt;li&gt;UI分析：⭐⭐⭐ 还有差距&lt;/li&gt;
&lt;li&gt;视频：⭐⭐ 刚起步&lt;/li&gt;
&lt;li&gt;特点：进步很快，本地部署是优势&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;在开发中的实际应用&lt;/h2&gt;
&lt;p&gt;说些接地气的用法：&lt;/p&gt;
&lt;h3&gt;1. 设计稿转代码&lt;/h3&gt;
&lt;p&gt;截图一个Figma设计稿，AI能直接生成对应的React/Vue组件。不是完美的，但能完成80%的工作。剩下的手动调调就好。&lt;/p&gt;
&lt;h3&gt;2. Bug可视化诊断&lt;/h3&gt;
&lt;p&gt;截图报错界面发给AI，比复制粘贴文字效果更好。因为截图保留了上下文——你能看到是哪个页面、什么状态下出的错。&lt;/p&gt;
&lt;h3&gt;3. 竞品分析&lt;/h3&gt;
&lt;p&gt;截图竞品的界面，让AI分析设计模式、信息架构、用户体验的优劣。比自己对着看效率高多了。&lt;/p&gt;
&lt;h3&gt;4. 文档自动化&lt;/h3&gt;
&lt;p&gt;拍照手写的架构图或白板讨论，AI能转成结构化的文档和流程图。会议记录从此不再痛苦。&lt;/p&gt;
&lt;h2&gt;当前的局限&lt;/h2&gt;
&lt;p&gt;多模态AI还不完美。几个明显的问题：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;幻觉依然存在。&lt;/strong&gt; AI有时会&quot;看到&quot;图片里没有的东西，或者误读文字。对于关键信息（数字、代码），一定要二次确认。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;空间推理还弱。&lt;/strong&gt; &quot;这个按钮在那个表格的左下方&quot;——这种空间关系的理解还不够可靠。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;视频理解有延迟。&lt;/strong&gt; 长视频分析需要时间和大量计算资源，实时视频理解还不现实。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;成本不低。&lt;/strong&gt; 图片和视频的token消耗远高于纯文本。频繁使用多模态功能，API费用会明显增加。&lt;/p&gt;
&lt;h2&gt;未来会怎样？&lt;/h2&gt;
&lt;p&gt;多模态不是一个功能，而是AI发展的&lt;strong&gt;必然方向&lt;/strong&gt;。人类就是通过多种感官来理解世界的，AI也需要。&lt;/p&gt;
&lt;p&gt;接下来可以期待的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;实时视频理解&lt;/strong&gt;——AI能像人一样&quot;看直播&quot;并实时反应&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;音频+视觉联合理解&lt;/strong&gt;——看视频的同时理解对话内容和语气&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;3D空间理解&lt;/strong&gt;——从2D图片推断3D空间关系&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;具身智能&lt;/strong&gt;——AI通过摄像头&quot;看&quot;真实世界并操控机器人&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;多模态AI正在从一个&quot;加分项&quot;变成&quot;基本能力&quot;。再过两年，不支持多模态的AI模型，大概就像不支持中文的搜索引擎一样——理论上能用，实际上没人想用。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;学会用眼睛看世界的AI，才是真正有用的AI。&lt;/strong&gt;&lt;/p&gt;</content:encoded><h:img src="/_astro/multimodal-ai-reality.DO21I_gq.jpg"/><enclosure url="/_astro/multimodal-ai-reality.DO21I_gq.jpg"/></item><item><title>开源大模型的逆袭：DeepSeek、Llama 4与本地部署实战</title><link>https://ouonnki.site/blog/ai/opensource-llm-rise</link><guid isPermaLink="true">https://ouonnki.site/blog/ai/opensource-llm-rise</guid><description>开源大模型已经追平甚至超越闭源模型，本文聊聊DeepSeek、Llama 4等代表选手，以及如何用Ollama在本地跑起来。</description><pubDate>Fri, 13 Feb 2026 21:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;格局变了&lt;/h2&gt;
&lt;p&gt;2024年初，开源模型和GPT-4之间还有明显差距。到了2026年？&lt;strong&gt;这个差距基本消失了&lt;/strong&gt;，在很多场景下开源甚至更强。&lt;/p&gt;
&lt;p&gt;这不是我的主观判断。看看各大benchmark的排行榜，DeepSeek-R1、Llama 4、Qwen 3这些开源模型，已经稳定出现在前十甚至前五的位置。更关键的是，实际使用体验上，它们已经完全够用了。&lt;/p&gt;
&lt;h2&gt;三大代表选手&lt;/h2&gt;
&lt;h3&gt;DeepSeek：中国队的惊喜&lt;/h3&gt;
&lt;p&gt;DeepSeek可能是2025年最大的黑马。一个相对低调的中国团队，用更少的计算资源训练出了能跟顶级模型掰手腕的产品。&lt;/p&gt;
&lt;p&gt;DeepSeek-R1的推理能力尤其让人印象深刻。在数学和编程任务上，它的表现经常能超过GPT-4o。而且它的MoE（Mixture of Experts）架构意味着推理成本更低——同样的性能，更少的GPU。&lt;/p&gt;
&lt;p&gt;我自己用DeepSeek最多的场景是代码review和技术文档写作。说实话，对于中文内容，它的理解和表达甚至比很多闭源模型更自然。&lt;/p&gt;
&lt;h3&gt;Llama 4：Meta的开源野心&lt;/h3&gt;
&lt;p&gt;Meta的Llama系列一直是开源LLM的标杆。Llama 4延续了这个传统，但这次的跃升幅度特别大。&lt;/p&gt;
&lt;p&gt;最值得关注的几点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;多模态原生支持&lt;/strong&gt;——不是后加的，是从训练开始就融入了视觉能力&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;超长上下文&lt;/strong&gt;——支持128K甚至更长的上下文窗口&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多语言能力&lt;/strong&gt;——中文表现比前几代好太多了&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scout和Maverick两个版本&lt;/strong&gt;——Scout轻量适合部署，Maverick重量级追求极致性能&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Qwen 3：阿里的稳定输出&lt;/h3&gt;
&lt;p&gt;Qwen（通义千问）系列一直是中文场景的强力选手。Qwen 3在保持中文优势的同时，英文和代码能力也上了一个台阶。&lt;/p&gt;
&lt;p&gt;它的优势在于版本丰富——从1.5B到72B，总有一个适合你的场景和硬件。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/posts/opensource-compare.jpg&quot; alt=&quot;开源模型对比&quot;&gt;&lt;/p&gt;
&lt;h2&gt;本地部署：没你想的那么难&lt;/h2&gt;
&lt;p&gt;很多人觉得跑本地模型需要几万块的显卡。2026年的现实是：&lt;strong&gt;一台普通的Mac就够了&lt;/strong&gt;。&lt;/p&gt;
&lt;h3&gt;Ollama：一行命令搞定&lt;/h3&gt;
&lt;p&gt;如果你还没试过Ollama，强烈建议现在就试。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 安装
curl -fsSL https://ollama.ai/install.sh | sh

# 跑一个模型，就这么简单
ollama run deepseek-r1:14b

# 或者Llama 4
ollama run llama4-scout:17b

# 想要更小的？
ollama run qwen3:7b
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;就这样。没有复杂的环境配置，没有CUDA版本冲突，没有依赖地狱。Ollama把所有脏活都包了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/posts/ollama-terminal.jpg&quot; alt=&quot;终端运行Ollama&quot;&gt;&lt;/p&gt;
&lt;h3&gt;硬件需求实话实说&lt;/h3&gt;
&lt;p&gt;别被&quot;大模型&quot;这个词吓到。现在的量化技术已经非常成熟：&lt;/p&gt;
&lt;p&gt;| 模型大小 | 量化后 | 最低内存 | 推荐设备 |
|---------|--------|---------|---------|
| 7B | Q4_K_M | 6GB | M1 MacBook Air |
| 14B | Q4_K_M | 10GB | M2 Pro Mac |
| 32B | Q4_K_M | 20GB | M3 Max Mac / RTX 4090 |
| 72B | Q4_K_M | 42GB | M4 Ultra Mac / 2×RTX 4090 |&lt;/p&gt;
&lt;p&gt;7B的模型在M1 MacBook Air上就能跑，速度还不错——大概每秒20-30 token。日常对话、简单编程完全够用。&lt;/p&gt;
&lt;p&gt;想要更好的体验？14B是性价比最高的甜点。它在大多数任务上的表现已经接近GPT-3.5时代的水平，但完全运行在你自己的机器上。&lt;/p&gt;
&lt;h3&gt;不只是命令行&lt;/h3&gt;
&lt;p&gt;Ollama跑起来之后，你可以用各种前端连接它：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Open WebUI&lt;/strong&gt;——最流行的本地AI聊天界面，支持多模型切换&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Continue&lt;/strong&gt;——VSCode插件，本地模型做代码补全&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LobeChat&lt;/strong&gt;——漂亮的聊天界面，支持插件系统&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;为什么要跑本地模型？&lt;/h2&gt;
&lt;h3&gt;隐私&lt;/h3&gt;
&lt;p&gt;这是最直接的理由。你的代码、文档、对话记录，一个字节都不会离开你的机器。&lt;/p&gt;
&lt;p&gt;对于处理公司内部代码、客户数据、个人隐私信息的场景，这不是nice-to-have，是&lt;strong&gt;必须的&lt;/strong&gt;。&lt;/p&gt;
&lt;h3&gt;成本&lt;/h3&gt;
&lt;p&gt;API调用的费用是会累积的。如果你是重度用户，每月几十到几百美元很正常。本地模型的成本就是电费——如果你已经有合适的硬件，基本等于免费。&lt;/p&gt;
&lt;h3&gt;可控性&lt;/h3&gt;
&lt;p&gt;不担心API突然涨价、服务下线、模型被修改。你的模型就在你的硬盘上，随时可用，永远不变。&lt;/p&gt;
&lt;h3&gt;速度&lt;/h3&gt;
&lt;p&gt;没有网络延迟。对于需要频繁调用的场景——比如代码补全、实时翻译——本地模型的响应速度通常更快。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/posts/local-deploy-server.jpg&quot; alt=&quot;本地部署服务器&quot;&gt;&lt;/p&gt;
&lt;h2&gt;什么时候该用闭源？&lt;/h2&gt;
&lt;p&gt;说了这么多开源的好，但我不是&quot;开源原教旨主义者&quot;。有些场景闭源模型确实还是更好的选择：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;最前沿的推理能力&lt;/strong&gt;——Claude Opus 4、GPT-5在最复杂的推理任务上还是有优势&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;超大上下文理解&lt;/strong&gt;——处理整本书级别的内容，闭源模型的长文本能力更稳定&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多模态能力&lt;/strong&gt;——视觉理解方面，Gemini和GPT-5还是领先的&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不想折腾&lt;/strong&gt;——如果你只是偶尔用用，API确实更方便&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我的做法是&lt;strong&gt;混合使用&lt;/strong&gt;：日常编程、文档写作用本地的DeepSeek或Qwen；复杂推理、重要决策用Claude或GPT-5；创意和brainstorm两边都试试，看谁的输出更好。&lt;/p&gt;
&lt;h2&gt;开源的未来&lt;/h2&gt;
&lt;p&gt;开源大模型的发展速度比大多数人预期的要快。每隔几个月就有新的突破——更好的架构、更高效的训练方法、更小的模型做到更强的效果。&lt;/p&gt;
&lt;p&gt;2026年底，我相信7B级别的开源模型就能达到现在GPT-4o的水平。到那时候，每个人的手机上都能跑一个真正强大的AI助手。&lt;/p&gt;
&lt;p&gt;**这才是AI民主化的真正含义。**不是每个人都能调用API，而是每个人都能拥有自己的模型——不受审查、不受限制、不受服务商控制。&lt;/p&gt;
&lt;p&gt;开源正在赢。&lt;/p&gt;</content:encoded><h:img src="/_astro/opensource-llm-rise.CjirVX4b.jpg"/><enclosure url="/_astro/opensource-llm-rise.CjirVX4b.jpg"/></item><item><title>Prompt Engineering已死？2026年与AI高效协作的新范式</title><link>https://ouonnki.site/blog/ai/prompt-engineering-dead</link><guid isPermaLink="true">https://ouonnki.site/blog/ai/prompt-engineering-dead</guid><description>从精心雕琢prompt到设计system prompt、编排工具链、构建agent workflow，人机协作方式正在经历根本性的范式转移。</description><pubDate>Fri, 13 Feb 2026 20:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;一个时代的终结&lt;/h2&gt;
&lt;p&gt;还记得2023年那会儿吗？Twitter上到处是&quot;10个ChatGPT prompt让你效率翻倍&quot;，Medium上的prompt engineering教程能绕地球三圈。每个人都在研究怎么跟AI&quot;说话&quot;——用什么语气、加什么前缀、要不要说&quot;你是一个专家&quot;。&lt;/p&gt;
&lt;p&gt;2026年了，这些技巧还有用吗？&lt;/p&gt;
&lt;p&gt;说实话，&lt;strong&gt;大部分已经没意义了&lt;/strong&gt;。不是因为prompt不重要，而是因为AI变聪明了，协作方式也彻底变了。你不再需要用各种trick去&quot;骗&quot;模型给出好答案，而是要学会一种全新的协作范式。&lt;/p&gt;
&lt;h2&gt;从&quot;写prompt&quot;到&quot;设计系统&quot;&lt;/h2&gt;
&lt;p&gt;以前我们把80%的精力花在单条prompt上，反复调试措辞。现在？重点完全转移了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/posts/system-prompt-design.jpg&quot; alt=&quot;系统提示词设计&quot;&gt;&lt;/p&gt;
&lt;h3&gt;System Prompt才是核心战场&lt;/h3&gt;
&lt;p&gt;2026年的AI协作，真正的功夫在system prompt的设计上。这不是简单的&quot;你是一个有帮助的助手&quot;，而是一份精心设计的&lt;strong&gt;行为规范文档&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;拿我自己的例子来说。我给Claude写的system prompt里包含：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;角色定义&lt;/strong&gt;：不只是&quot;你是谁&quot;，而是详细的决策框架——遇到什么情况该怎么做&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工具使用规范&lt;/strong&gt;：什么时候用搜索，什么时候读文件，什么时候直接回答&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;输出格式约束&lt;/strong&gt;：不同场景下的格式要求，比如技术讨论用markdown，闲聊就口语化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安全边界&lt;/strong&gt;：哪些事情绝对不做，哪些需要确认&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一个好的system prompt，相当于给AI写了一份&quot;员工手册&quot;。你不需要每次对话都重复要求，模型会持续遵循这些规范。&lt;/p&gt;
&lt;h3&gt;上下文工程 &gt; Prompt工程&lt;/h3&gt;
&lt;p&gt;Andrej Karpathy说得好：&quot;Prompt engineering is dead, context engineering is real.&quot; 现在的关键不是怎么措辞，而是&lt;strong&gt;给模型提供什么上下文&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;实际操作中，这意味着：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;项目的AGENTS.md文件，让AI理解项目结构和规范&lt;/li&gt;
&lt;li&gt;自动注入的相关代码片段，而不是让AI猜&lt;/li&gt;
&lt;li&gt;对话历史的智能裁剪，保留重要上下文，丢弃噪音&lt;/li&gt;
&lt;li&gt;实时的工具调用结果，让AI基于事实而非猜测回答&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Agent Workflow：真正的生产力革命&lt;/h2&gt;
&lt;p&gt;单轮对话的时代已经过去了。2026年最大的变化是&lt;strong&gt;Agent&lt;/strong&gt;的成熟。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/posts/agent-workflow.jpg&quot; alt=&quot;Agent工作流&quot;&gt;&lt;/p&gt;
&lt;h3&gt;不是聊天，是编排&lt;/h3&gt;
&lt;p&gt;我现在每天的工作流是这样的：写一段需求描述，AI自动拆解成子任务，调用不同的工具去执行——读代码、搜索文档、写测试、提PR。整个过程我可能只需要介入两三次做决策。&lt;/p&gt;
&lt;p&gt;这跟2023年&quot;请帮我写一个函数&quot;的模式完全不同。&lt;/p&gt;
&lt;p&gt;举个真实例子。上周我需要给博客加三篇新文章，包括找图片、写内容、上传图床、推送部署。我只写了一段任务描述，AI agent就自动完成了整个流程——下载图片、上传CDN、生成文章、git push。全程不需要我盯着。&lt;/p&gt;
&lt;h3&gt;工具链是新的prompt&lt;/h3&gt;
&lt;p&gt;现在&quot;调教&quot;AI的方式不是改措辞，而是&lt;strong&gt;给它更好的工具&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;一个能读写文件的AI，比你写再完美的prompt都有用。一个能搜索网络的AI，不会再&quot;幻觉&quot;过时信息。一个能执行代码的AI，不需要你肉眼检查逻辑。&lt;/p&gt;
&lt;p&gt;工具的选择和编排，才是2026年&quot;prompt engineering&quot;的真正含义。&lt;/p&gt;
&lt;h2&gt;人的角色变了&lt;/h2&gt;
&lt;p&gt;这不意味着人变得不重要。恰恰相反，&lt;strong&gt;人的角色升级了&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/posts/human-ai-collab.jpg&quot; alt=&quot;人机协作&quot;&gt;&lt;/p&gt;
&lt;h3&gt;从执行者到审核者&lt;/h3&gt;
&lt;p&gt;以前：你告诉AI每一步该做什么。
现在：你定义目标和约束，AI规划执行路径，你审核关键决策点。&lt;/p&gt;
&lt;p&gt;这更像是管理一个能力很强但经验不足的新人。你不需要手把手教他写代码，但需要review他的PR、把关架构决策、在关键分叉点给出方向。&lt;/p&gt;
&lt;h3&gt;从写prompt到写规范&lt;/h3&gt;
&lt;p&gt;最有价值的技能不再是&quot;怎么跟AI说话&quot;，而是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;需求定义能力&lt;/strong&gt;——你能不能把模糊的想法变成清晰的规范？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;系统设计能力&lt;/strong&gt;——你能不能设计出合理的工具链和工作流？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;质量判断能力&lt;/strong&gt;——你能不能快速判断AI输出的质量？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;边界感知能力&lt;/strong&gt;——你知不知道什么该交给AI，什么该自己做？&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;那些还在&quot;学prompt&quot;的人&lt;/h2&gt;
&lt;p&gt;我不是说prompt完全不重要。在某些场景下——比如创意写作、复杂推理——措辞的细微差别确实会影响结果。&lt;/p&gt;
&lt;p&gt;但如果你还在花大量时间研究&quot;最佳prompt模板&quot;，你可能在优化一个越来越不重要的环节。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;真正的杠杆在更高的层面：&lt;/strong&gt; 设计好的system prompt、选择合适的工具、构建高效的workflow、定义清晰的评估标准。&lt;/p&gt;
&lt;h2&gt;写在最后&lt;/h2&gt;
&lt;p&gt;Prompt engineering没有&quot;死&quot;，它进化了。从一个专门的技能，变成了更广泛的&quot;AI协作设计&quot;能力的一小部分。&lt;/p&gt;
&lt;p&gt;就像&quot;会打字&quot;曾经是一个专业技能，现在只是基本素养一样。会写prompt很快也会变成默认技能，真正稀缺的是——&lt;strong&gt;知道让AI做什么，以及怎么验证AI做得对不对&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这才是2026年与AI高效协作的核心。&lt;/p&gt;
&lt;p&gt;不是说得更好，而是&lt;strong&gt;设计得更好&lt;/strong&gt;。&lt;/p&gt;</content:encoded><h:img src="/_astro/llm-landscape.DKQgOlij.jpg"/><enclosure url="/_astro/llm-landscape.DKQgOlij.jpg"/></item><item><title>AI编程的下一步：Codex、Claude Code与前端开发的未来</title><link>https://ouonnki.site/blog/ai/ai-coding-future</link><guid isPermaLink="true">https://ouonnki.site/blog/ai/ai-coding-future</guid><description>深度分析2026年AI编程工具现状，探讨Copilot、Cursor、Claude Code和Codex CLI对前端开发的影响与未来</description><pubDate>Thu, 12 Feb 2026 22:00:00 GMT</pubDate><content:encoded>&lt;p&gt;一个事实：我现在写代码的方式和一年前完全不同了。&lt;/p&gt;
&lt;p&gt;不是说AI替代了我写代码，而是&lt;strong&gt;写代码的流程变了&lt;/strong&gt;。以前是&quot;想→写→调→测&quot;，现在是&quot;想→描述→审→调&quot;。AI处理了大量机械性的编码工作，我更多时间花在思考架构和审查代码上。&lt;/p&gt;
&lt;p&gt;这篇文章聊聊2026年AI编程工具的现状，以及作为前端开发者，我们该怎么适应。&lt;/p&gt;
&lt;h2&gt;AI编程工具现状&lt;/h2&gt;
&lt;p&gt;目前主流的AI编程工具可以分三个层次：&lt;/p&gt;
&lt;h3&gt;编辑器内嵌：Copilot与Cursor&lt;/h3&gt;
&lt;p&gt;GitHub Copilot已经迭代到了一个相当成熟的阶段。代码补全的准确率比早期提升了一个量级，特别是在你项目上下文足够丰富的情况下，它给出的建议经常是直接能用的。&lt;/p&gt;
&lt;p&gt;Cursor则走了一条更激进的路——它不只是补全，而是试图理解你的整个项目。Cursor的Composer模式可以同时修改多个文件，做跨文件的重构。对于前端项目来说，修改一个组件同时更新相关的样式、测试和文档，这种体验是传统IDE无法想象的。&lt;/p&gt;
&lt;p&gt;两者的选择其实很简单：如果你重度依赖VS Code生态，Copilot无缝集成；如果你愿意尝试新编辑器，Cursor的体验上限更高。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/posts/ai-coding-screen.jpg&quot; alt=&quot;AI辅助编程&quot; title=&quot;代码编辑器&quot;&gt;&lt;/p&gt;
&lt;h3&gt;终端工具：Claude Code与Codex CLI&lt;/h3&gt;
&lt;p&gt;这是2025-2026年最让我兴奋的新品类。&lt;/p&gt;
&lt;p&gt;Claude Code可以直接在终端里理解你的项目结构，执行复杂的开发任务。&quot;帮我把这个React组件重构成TypeScript，加上单元测试&quot;——它会自己读文件、改代码、跑测试、修bug，全程你只需要review最终结果。&lt;/p&gt;
&lt;p&gt;OpenAI的Codex CLI走了类似的路线。它的优势在于和GitHub生态的深度集成——创建PR、写commit message、处理code review comment，流程非常顺畅。&lt;/p&gt;
&lt;p&gt;这类工具改变了一个根本性的东西：&lt;strong&gt;开发者从&quot;写代码的人&quot;变成了&quot;审代码的人&quot;&lt;/strong&gt;。&lt;/p&gt;
&lt;h3&gt;Agent级别：自主开发&lt;/h3&gt;
&lt;p&gt;再往上一层，就是完全自主的AI开发Agent。给它一个需求描述，它自己完成从设计到实现到测试的全流程。&lt;/p&gt;
&lt;p&gt;目前这个层次还不够成熟，生产环境下我不敢完全放手。但在原型开发、小工具开发这些场景下，已经可以用了。&lt;/p&gt;
&lt;h2&gt;效率提升实例&lt;/h2&gt;
&lt;p&gt;说几个具体的例子：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;组件开发&lt;/strong&gt;：一个中等复杂度的React组件，以前需要2-3小时。现在用Claude Code描述需求，10分钟出初版，再花30分钟review和调整。效率提升3-4倍。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;API对接&lt;/strong&gt;：对接第三方API最烦的是读文档和处理边界情况。现在把API文档丢给AI，它能直接生成类型定义、请求封装和错误处理代码。这种机械活儿AI做得比人好。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bug修复&lt;/strong&gt;：把报错信息和相关代码贴给Claude Code，它大概率能直接定位问题并给出修复方案。复杂bug可能需要几轮对话，但比自己翻Stack Overflow快多了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;代码迁移&lt;/strong&gt;：最近把一个项目从Webpack迁移到Vite，Claude Code处理了80%的配置改动和兼容性修复。省了至少两天时间。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/posts/ai-coding-workspace.jpg&quot; alt=&quot;开发效率提升&quot; title=&quot;开发效率&quot;&gt;&lt;/p&gt;
&lt;h2&gt;对前端开发流程的改变&lt;/h2&gt;
&lt;p&gt;前端的工作流正在被重塑：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CSS几乎不用手写了&lt;/strong&gt;。描述你想要的样式，AI生成Tailwind类名或CSS代码，准确率很高。响应式、动画这些以前费时间的东西，现在几句话就搞定。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;测试覆盖率暴涨&lt;/strong&gt;。以前谁愿意写测试？现在AI一键生成，覆盖率轻松上80%。写测试的成本从&quot;高到不想写&quot;变成了&quot;低到没理由不写&quot;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;文档不再是负担&lt;/strong&gt;。组件文档、API文档、README，都可以让AI根据代码自动生成。质量还不错，至少比没有文档强太多。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Code Review效率提升&lt;/strong&gt;。AI先过一遍，标出潜在问题，人再重点审核。Review的质量反而提高了，因为你可以把注意力集中在架构和业务逻辑上。&lt;/p&gt;
&lt;h2&gt;AI编程的局限性&lt;/h2&gt;
&lt;p&gt;但也要清醒地认识到局限：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;架构决策还是人的活&lt;/strong&gt;。AI可以实现任何架构，但选择哪种架构、为什么选这种架构，需要对业务和团队的深度理解。这是AI目前做不了的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;复杂状态管理容易出错&lt;/strong&gt;。涉及多个组件之间复杂交互的状态管理，AI经常给出看起来对、但实际有隐藏bug的方案。这类问题必须仔细review。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;性能优化需要人类直觉&lt;/strong&gt;。AI能写出功能正确的代码，但不一定是性能最优的。关键路径的优化还是需要有经验的工程师来判断。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;上下文限制&lt;/strong&gt;。即使是100万token的上下文，面对大型monorepo也不够用。AI看不到全貌，给的建议可能和项目整体架构冲突。&lt;/p&gt;
&lt;h2&gt;前端工程师如何适应&lt;/h2&gt;
&lt;p&gt;我的建议：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;拥抱AI工具，但不要依赖&lt;/strong&gt;。用AI加速日常开发，但确保你理解AI生成的每一行代码。不理解的代码不要提交。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;往上走&lt;/strong&gt;。把时间花在架构设计、性能优化、用户体验这些AI还不擅长的地方。纯编码能力的价值在下降，系统设计能力的价值在上升。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;学会&quot;描述&quot;&lt;/strong&gt;。和AI协作的核心技能是精确描述你想要什么。Prompt engineering不只是写ChatGPT的提示词，更是清晰表达技术需求的能力。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;保持学习&lt;/strong&gt;。AI工具迭代很快，每隔几个月就有新的工具和工作流。保持好奇心，不断尝试新工具。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/posts/ai-coding-macbook.jpg&quot; alt=&quot;前端开发的未来&quot; title=&quot;前端开发&quot;&gt;&lt;/p&gt;
&lt;h2&gt;未来展望&lt;/h2&gt;
&lt;p&gt;2026年只是AI编程的早期阶段。我预测接下来会发生的事：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AI Native的开发框架会出现&lt;/strong&gt;。不是在现有框架上加AI功能，而是从底层就为AI协作设计的新框架。代码结构、文件组织、API设计都会被重新思考。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;初级开发者的定义会改变&lt;/strong&gt;。&quot;初级&quot;不再意味着&quot;只会写简单代码&quot;，而是&quot;能有效指导AI完成开发任务&quot;。门槛变了，但并没有消失。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;前端和后端的界限会更模糊&lt;/strong&gt;。AI让全栈开发变得更容易，一个前端工程师借助AI可以轻松处理大部分后端任务。专业分工的边界在重新划定。&lt;/p&gt;
&lt;p&gt;说到底，AI编程工具是&lt;strong&gt;放大器&lt;/strong&gt;，不是替代品。它放大了优秀工程师的能力，也放大了不合格工程师的问题。核心竞争力从来不是&quot;会写代码&quot;，而是&quot;知道该写什么代码&quot;。&lt;/p&gt;
&lt;p&gt;这一点，在AI时代只会更加明显。&lt;/p&gt;</content:encoded><h:img src="/_astro/ai-coding.D2n4aAyB.jpg"/><enclosure url="/_astro/ai-coding.D2n4aAyB.jpg"/></item><item><title>AI Agent落地实战：我如何用OpenClaw搭建7×24小时个人AI助手</title><link>https://ouonnki.site/blog/ai/ai-agent-openclaw</link><guid isPermaLink="true">https://ouonnki.site/blog/ai/ai-agent-openclaw</guid><description>分享使用OpenClaw搭建个人AI Agent的完整经验，包括Telegram接入、多模型配置、记忆系统和日常使用场景</description><pubDate>Thu, 12 Feb 2026 21:00:00 GMT</pubDate><content:encoded>&lt;p&gt;用了三个月OpenClaw之后，我已经很难想象没有它的日子了。&lt;/p&gt;
&lt;p&gt;这不是夸张。它帮我管日程、查邮件、写代码、做翻译、监控服务器、甚至在我睡觉的时候自动处理一些routine的事情。这篇文章分享我的完整搭建和使用经验。&lt;/p&gt;
&lt;h2&gt;什么是AI Agent？&lt;/h2&gt;
&lt;p&gt;先说清楚概念。ChatGPT是聊天工具——你问它答。AI Agent是&lt;strong&gt;自主执行者&lt;/strong&gt;——你给它目标，它自己规划步骤、调用工具、完成任务。&lt;/p&gt;
&lt;p&gt;区别在于：聊天工具是你的嘴替，Agent是你的分身。&lt;/p&gt;
&lt;p&gt;一个真正的Agent需要几个核心能力：持续运行、记忆上下文、调用外部工具、主动行动。市面上大部分&quot;Agent&quot;产品其实只是套了个壳的ChatGPT，真正能独立运转的很少。&lt;/p&gt;
&lt;h2&gt;为什么选OpenClaw&lt;/h2&gt;
&lt;p&gt;试过AutoGPT、MetaGPT、各种Agent框架之后，我选了&lt;a href=&quot;https://github.com/openclaw/openclaw&quot;&gt;OpenClaw&lt;/a&gt;。原因很直接：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;它是真的能跑起来的&lt;/strong&gt;。很多Agent框架看demo很酷，自己搭的时候一堆bug。OpenClaw的安装和配置流程是我用过最顺畅的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Telegram原生支持&lt;/strong&gt;。我想要一个随时能用手机对话的助手，不是只能在terminal里跑的玩具。OpenClaw的Telegram接入开箱即用。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;多模型切换&lt;/strong&gt;。一条命令切换Claude/GPT/Gemini，不同任务用不同模型，这个灵活性太重要了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;记忆系统&lt;/strong&gt;。它有完整的memory机制——短期记忆(对话上下文)、长期记忆(MEMORY.md)、每日笔记。你的Agent真的能&quot;记住&quot;事情。&lt;/p&gt;
&lt;p&gt;详细文档在&lt;a href=&quot;https://docs.openclaw.ai&quot;&gt;docs.openclaw.ai&lt;/a&gt;，写得很清楚。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/posts/ai-agent-robot.jpg&quot; alt=&quot;Telegram聊天界面示意&quot; title=&quot;Telegram机器人交互&quot;&gt;&lt;/p&gt;
&lt;h2&gt;配置过程&lt;/h2&gt;
&lt;p&gt;核心配置其实不复杂：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Telegram接入&lt;/strong&gt;：通过BotFather创建bot，把token填进配置文件。五分钟搞定。支持私聊和群组，群组里可以设置触发规则，不会每条消息都回。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;多模型配置&lt;/strong&gt;：在配置文件里定义多个模型，日常用Sonnet 4(快且便宜)，复杂任务切Opus 4，代码任务可以用GPT-5。切换就是一条 &lt;code&gt;/model&lt;/code&gt; 命令的事。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Heartbeat系统&lt;/strong&gt;：这是OpenClaw最酷的功能之一。你可以设置定时心跳，让Agent每隔一段时间自动检查邮件、日历、服务器状态等。它不是傻等你提问，而是主动巡逻。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cron任务&lt;/strong&gt;：比heartbeat更精确的定时任务。每天早上8点发天气预报、每周一整理周报、每小时检查一次服务器——都可以用cron实现。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Memory系统&lt;/strong&gt;：Agent会自动维护 &lt;code&gt;MEMORY.md&lt;/code&gt;(长期记忆)和每日笔记文件。你告诉它&quot;记住我喜欢用Sonnet处理日常任务&quot;，它真的会记住，下次对话时会参考。&lt;/p&gt;
&lt;h2&gt;日常使用场景&lt;/h2&gt;
&lt;p&gt;说几个我每天都在用的场景：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;代码助手&lt;/strong&gt;：直接在Telegram里发代码片段，让它review、重构、补测试。它能访问我的项目文件，给出的建议是基于整个项目上下文的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;信息整理&lt;/strong&gt;：把一堆链接丢给它，让它总结要点。看论文、看技术文档特别好用。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自动化运维&lt;/strong&gt;：通过shell工具，它能直接在服务器上执行命令。&quot;检查一下Nginx日志有没有异常&quot;——它会自己去看，然后给你一个人话版的总结。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;日程管理&lt;/strong&gt;：结合日历API，它能提醒即将到来的会议，甚至帮你草拟会议议程。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;翻译和写作&lt;/strong&gt;：中英互译、润色文章、写邮件。质量比单独用ChatGPT好，因为它知道你的写作风格偏好。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/posts/ai-agent-code.jpg&quot; alt=&quot;AI自动化工作流&quot; title=&quot;自动化工作流程&quot;&gt;&lt;/p&gt;
&lt;h2&gt;踩过的坑&lt;/h2&gt;
&lt;p&gt;也不是一帆风顺。几个教训分享给大家：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Token消耗比想象的大&lt;/strong&gt;。heartbeat如果设得太频繁，加上长上下文，一个月的API费用可能让你吃惊。建议一开始保守设置，观察一周再调整。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;记忆管理需要主动维护&lt;/strong&gt;。MEMORY.md会越来越大，定期清理过时信息很重要。不然上下文会被无关内容占据。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;群组使用要谨小慎微&lt;/strong&gt;。在群里它可能过于活跃，建议设置好触发规则——只在被@时回复，或者只回复特定关键词。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;模型切换要有策略&lt;/strong&gt;。不是所有任务都需要最强模型。日常对话用Sonnet，复杂推理才上Opus。这样月底账单不会吓到你。&lt;/p&gt;
&lt;h2&gt;AI Agent的未来&lt;/h2&gt;
&lt;p&gt;用了几个月Agent之后，我对AI的理解发生了变化。&lt;/p&gt;
&lt;p&gt;单纯的聊天模型已经是&quot;上一个时代&quot;的产品了。未来的方向一定是Agent——持续运行、自主决策、跨工具协作的AI系统。&lt;/p&gt;
&lt;p&gt;OpenClaw这样的项目让个人用户也能拥有强大的Agent能力，而不需要依赖大公司的封闭平台。这很重要。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/posts/ai-agent-portrait.jpg&quot; alt=&quot;AI未来发展&quot; title=&quot;AI发展方向&quot;&gt;&lt;/p&gt;
&lt;p&gt;我的预测：到2026年底，大部分开发者都会有自己的AI Agent。不是因为赶时髦，而是因为用过之后真的回不去了。&lt;/p&gt;
&lt;p&gt;如果你还没试过，强烈建议从OpenClaw开始。学习曲线不陡，文档清晰，社区活跃。给自己一个周末的时间，你会发现一个全新的工作方式。&lt;/p&gt;</content:encoded><h:img src="/_astro/ai-agent.D0HqQi9r.jpg"/><enclosure url="/_astro/ai-agent.D0HqQi9r.jpg"/></item><item><title>从GPT-5到Claude Opus 4：2026大模型格局全面解析</title><link>https://ouonnki.site/blog/ai/llm-landscape-2026</link><guid isPermaLink="true">https://ouonnki.site/blog/ai/llm-landscape-2026</guid><description>2026年初大模型格局深度解析，覆盖GPT-5、Claude Opus 4、Gemini 2.5及国产模型，附实际使用体验与选择建议</description><pubDate>Thu, 12 Feb 2026 20:00:00 GMT</pubDate><content:encoded>&lt;p&gt;2026年刚开年，大模型的竞争已经卷到了一个新高度。去年这个时候我们还在讨论GPT-4o够不够用，现在的问题变成了——这么多顶级模型，到底选哪个？&lt;/p&gt;
&lt;p&gt;这篇文章是我过去几个月密集使用各家模型后的真实感受，不是参数对比表，是体感。&lt;/p&gt;
&lt;h2&gt;GPT-5系列：OpenAI的全面反击&lt;/h2&gt;
&lt;p&gt;GPT-5在2025年底正式发布，说实话，进步是肉眼可见的。最大的变化不是&quot;更聪明&quot;，而是&lt;strong&gt;更稳定&lt;/strong&gt;。以前GPT-4经常出现的&quot;突然变笨&quot;现象，在GPT-5上几乎消失了。&lt;/p&gt;
&lt;p&gt;GPT-5的多模态能力终于达到了实用级别。图片理解、代码生成、长文档分析，都有质的飞跃。特别是代码方面，GPT-5配合Codex CLI已经能处理相当复杂的重构任务。&lt;/p&gt;
&lt;p&gt;不过GPT-5也有明显短板：中文写作风格偏&quot;翻译腔&quot;，创意写作不如Claude自然。另外价格也不便宜，API调用成本比去年涨了不少。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/posts/llm-ai-brain.jpg&quot; alt=&quot;AI模型能力对比&quot; title=&quot;大模型技术演进&quot;&gt;&lt;/p&gt;
&lt;h2&gt;Claude Opus 4：我的日常主力&lt;/h2&gt;
&lt;p&gt;说真话，Claude Opus 4是我目前用得最多的模型。原因很简单：&lt;strong&gt;它最懂你想要什么&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;Opus 4的指令遵循能力是所有模型里最强的。你说&quot;用轻松的语气写&quot;，它就真的轻松；你说&quot;控制在500字以内&quot;，它就不会写成800字。这种&quot;听话&quot;的能力看似简单，实际上是最难做到的。&lt;/p&gt;
&lt;p&gt;代码能力方面，Opus 4在复杂系统设计和架构层面的理解力明显强于竞品。它能读懂你整个项目的上下文，给出的建议不是片段式的，而是全局性的。&lt;/p&gt;
&lt;p&gt;Sonnet 4作为轻量版，性价比极高。日常对话、简单任务用Sonnet完全够了，响应速度还快得多。&lt;/p&gt;
&lt;h2&gt;Gemini 2.5：Google的长上下文王者&lt;/h2&gt;
&lt;p&gt;Gemini 2.5 Pro最大的卖点还是那个恐怖的上下文窗口。100万token的上下文不是噱头，在处理超长文档、代码库分析这些场景下，确实是独一档的存在。&lt;/p&gt;
&lt;p&gt;但日常使用中，Gemini的&quot;人味&quot;还是差一些。回答偏模板化，创意任务表现平平。Google在安全限制上也过于保守，经常遇到不必要的拒绝。&lt;/p&gt;
&lt;p&gt;Gemini最适合的场景：大规模信息整理、长文档问答、多文件代码分析。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/posts/llm-data-analysis.jpg&quot; alt=&quot;各大AI公司竞争格局&quot; title=&quot;AI行业竞争&quot;&gt;&lt;/p&gt;
&lt;h2&gt;国产模型：Kimi K2.5领跑&lt;/h2&gt;
&lt;p&gt;国产模型这一年的进步令人惊讶。Kimi K2.5在中文理解和生成方面已经不输GPT-5，某些场景甚至更好。价格优势更是碾压级的——同样的任务，成本可能只有GPT-5的十分之一。&lt;/p&gt;
&lt;p&gt;DeepSeek V3也值得关注，特别是在数学推理和代码生成方面表现亮眼。开源策略让它在开发者社区积累了大量好感。&lt;/p&gt;
&lt;p&gt;智谱GLM-5、百度文心5.0也各有所长，但整体上Kimi和DeepSeek已经拉开了差距。&lt;/p&gt;
&lt;h2&gt;我的模型选择建议&lt;/h2&gt;
&lt;p&gt;经过几个月的实际使用，我的推荐是：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;日常主力&lt;/strong&gt;：Claude Opus 4 / Sonnet 4。指令遵循好，输出质量稳定，中文表现优秀。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;代码开发&lt;/strong&gt;：Claude Opus 4 + GPT-5轮换。复杂架构用Opus，快速迭代用GPT-5。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;长文档处理&lt;/strong&gt;：Gemini 2.5 Pro。上下文窗口的优势在这类任务上无可替代。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;性价比优先&lt;/strong&gt;：Kimi K2.5。中文场景下质量够用，成本极低。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;开源自部署&lt;/strong&gt;：DeepSeek V3。社区活跃，模型质量过硬。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/posts/llm-tech-laptop.jpg&quot; alt=&quot;未来AI发展方向&quot; title=&quot;AI未来展望&quot;&gt;&lt;/p&gt;
&lt;h2&gt;2026年的趋势判断&lt;/h2&gt;
&lt;p&gt;几个明显的趋势：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;模型差异化加速&lt;/strong&gt;。不会有&quot;一个模型打天下&quot;的局面。每家都在找自己的差异化定位，用户需要学会&quot;用对的模型做对的事&quot;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Agent能力成为关键&lt;/strong&gt;。单纯的问答已经不够了，2026年的竞争焦点是谁能更好地驱动Agent——自主执行任务、调用工具、持续运行。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;价格战刚刚开始&lt;/strong&gt;。国产模型的价格优势会倒逼海外厂商降价，对用户来说是好事。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;多模态从噱头变标配&lt;/strong&gt;。图片、音频、视频理解不再是加分项，而是基本要求。&lt;/p&gt;
&lt;p&gt;我的判断是：2026年不存在&quot;最好的模型&quot;，只有&quot;最适合你的模型组合&quot;。学会灵活切换和搭配，才是正确的打开方式。&lt;/p&gt;</content:encoded><h:img src="/_astro/llm-landscape.DKQgOlij.jpg"/><enclosure url="/_astro/llm-landscape.DKQgOlij.jpg"/></item><item><title>OpenClaw 完全部署指南：从零搭建你的 AI 助手</title><link>https://ouonnki.site/blog/backend/openclaw-deployment-guide</link><guid isPermaLink="true">https://ouonnki.site/blog/backend/openclaw-deployment-guide</guid><description>基于官方文档，详解 OpenClaw 的 CLI 安装、Gateway 配置、Telegram/Discord 接入和实战技巧</description><pubDate>Mon, 09 Feb 2026 16:30:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;阅读时间&lt;/strong&gt;: 20分钟 | &lt;strong&gt;难度&lt;/strong&gt;: 中级 | &lt;strong&gt;基于 OpenClaw 官方文档&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2&gt;目录&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#openclaw-%E6%98%AF%E4%BB%80%E4%B9%88&quot;&gt;OpenClaw 是什么&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%9E%B6%E6%9E%84%E7%90%86%E8%A7%A3gateway--channels&quot;&gt;架构理解：Gateway + Channels&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%B3%BB%E7%BB%9F%E8%A6%81%E6%B1%82%E4%B8%8E%E5%87%86%E5%A4%87&quot;&gt;系统要求与准备&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%AE%89%E8%A3%85-openclaw&quot;&gt;安装 OpenClaw&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%88%9D%E5%A7%8B%E9%85%8D%E7%BD%AE%E5%90%91%E5%AF%BC&quot;&gt;初始配置向导&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%90%AF%E5%8A%A8-gateway&quot;&gt;启动 Gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%8E%A5%E5%85%A5-telegram&quot;&gt;接入 Telegram&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%8E%A5%E5%85%A5-discord&quot;&gt;接入 Discord&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E4%BD%BF%E7%94%A8-control-ui&quot;&gt;使用 Control UI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E4%B8%8E%E6%8E%92%E6%9F%A5&quot;&gt;常见问题与排查&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2&gt;OpenClaw 是什么&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;OpenClaw&lt;/strong&gt;（前身为 Moltbot/Clawdbot）是一个&lt;strong&gt;自托管的 AI 助手网关&lt;/strong&gt;，让你能够在自己控制的环境中运行 AI 代理，并连接到多种消息平台。&lt;/p&gt;
&lt;h3&gt;核心特性&lt;/h3&gt;
&lt;p&gt;| 特性 | 说明 |
|------|------|
| 🤖 &lt;strong&gt;多模型支持&lt;/strong&gt; | GPT-4、Claude、Gemini、本地模型（Ollama） |
| 🔄 &lt;strong&gt;持久化会话&lt;/strong&gt; | 长对话上下文、记忆功能 |
| 🔌 &lt;strong&gt;技能系统&lt;/strong&gt; | 通过插件扩展功能（GitHub、搜索、代码执行） |
| 💬 &lt;strong&gt;多平台&lt;/strong&gt; | Telegram、Discord、WhatsApp、Slack、iMessage |
| 🔒 &lt;strong&gt;本地优先&lt;/strong&gt; | 数据不出本地，完全可控 |&lt;/p&gt;
&lt;h3&gt;与 ChatGPT 的区别&lt;/h3&gt;
&lt;p&gt;| | OpenClaw | ChatGPT |
|--|----------|---------|
| &lt;strong&gt;部署&lt;/strong&gt; | 自托管 | 云服务 |
| &lt;strong&gt;数据&lt;/strong&gt; | 本地 | 上传 OpenAI |
| &lt;strong&gt;插件&lt;/strong&gt; | 任意安装 | 官方限定 |
| &lt;strong&gt;成本&lt;/strong&gt; | API 费 + 服务器 | 订阅费 |
| &lt;strong&gt;定制&lt;/strong&gt; | 完全可定制 | 有限 |&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;架构理解：Gateway + Channels&lt;/h2&gt;
&lt;p&gt;理解 OpenClaw 的架构对部署至关重要：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────┐
│                     OpenClaw Gateway                        │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐    │
│  │   Control    │  │   Session    │  │    Skill     │    │
│  │     UI       │  │   Manager    │  │   Engine     │    │
│  └──────────────┘  └──────────────┘  └──────────────┘    │
│                                                              │
│  ┌────────────────────────────────────────────────────┐   │
│  │              Channel Adapters                       │   │
│  │  Telegram │ Discord │ WhatsApp │ Slack │ iMessage  │   │
│  └────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;核心组件&lt;/h3&gt;
&lt;p&gt;| 组件 | 说明 | 默认端口 |
|------|------|----------|
| &lt;strong&gt;Gateway&lt;/strong&gt; | 核心控制平面 | 3000 |
| &lt;strong&gt;Control UI&lt;/strong&gt; | Web 管理界面 | 3000/ui |
| &lt;strong&gt;Channels&lt;/strong&gt; | 消息平台适配器 | - |&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;系统要求与准备&lt;/h2&gt;
&lt;h3&gt;硬件要求&lt;/h3&gt;
&lt;p&gt;| 级别 | CPU | 内存 | 存储 | 适用场景 |
|------|-----|------|------|----------|
| 入门级 | 2核 | 4GB | 20GB | 个人轻量使用 |
| 推荐 | 4核 | 8GB | 50GB | 日常办公+多平台 |
| 高级 | 8核 | 16GB | 100GB | 企业/团队/高并发 |&lt;/p&gt;
&lt;h3&gt;软件要求&lt;/h3&gt;
&lt;p&gt;| 软件 | 版本 | 说明 |
|------|------|------|
| &lt;strong&gt;Node.js&lt;/strong&gt; | 22+ | 必需，OpenClaw 基于 Node 构建 |
| &lt;strong&gt;npm/pnpm&lt;/strong&gt; | 最新 | 包管理器 |
| &lt;strong&gt;Git&lt;/strong&gt; | 任意 | 克隆仓库（可选） |&lt;/p&gt;
&lt;h3&gt;网络要求&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;可访问外网（下载依赖、调用 AI API）&lt;/li&gt;
&lt;li&gt;如果使用本地模型（Ollama），需要相应端口&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;安装 OpenClaw&lt;/h2&gt;
&lt;p&gt;官方提供 &lt;strong&gt;3 种安装方式&lt;/strong&gt;，根据你的需求选择：&lt;/p&gt;
&lt;h3&gt;方式一：一键安装脚本（推荐）&lt;/h3&gt;
&lt;p&gt;最简单的方式，自动安装 Node.js 和 OpenClaw：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 执行安装脚本
curl -fsSL https://openclaw.ai/install.sh | bash

# 如果不需要立即启动向导，添加 --no-onboard
curl -fsSL https://openclaw.ai/install.sh | bash -s -- --no-onboard
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;脚本会完成&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;检查系统环境&lt;/li&gt;
&lt;li&gt;安装/升级 Node.js 22+（如缺失）&lt;/li&gt;
&lt;li&gt;全局安装 &lt;code&gt;openclaw&lt;/code&gt; CLI&lt;/li&gt;
&lt;li&gt;可选：启动 onboarding 向导&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;方式二：npm 安装（已有 Node.js）&lt;/h3&gt;
&lt;p&gt;如果你已经安装了 Node.js 22+：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 使用 npm
npm install -g openclaw@latest

# 或使用 pnpm（更快）
pnpm add -g openclaw@latest

# 或使用 yarn
yarn global add openclaw@latest
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;方式三：从源码构建（开发者）&lt;/h3&gt;
&lt;p&gt;适合需要修改源码或贡献代码的用户：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 克隆仓库
git clone https://github.com/openclaw/openclaw.git
cd openclaw

# 安装依赖
pnpm install

# 构建项目
pnpm build

# 链接到全局（可选）
pnpm link --global

# 或直接运行
./bin/openclaw
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;验证安装&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 检查版本
openclaw --version

# 检查环境
openclaw doctor

# 查看帮助
openclaw --help
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;初始配置向导&lt;/h2&gt;
&lt;p&gt;安装完成后，运行 onboarding 向导进行初始配置：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 启动交互式配置向导
openclaw onboard

# 同时安装系统服务（推荐用于服务器）
openclaw onboard --install-daemon
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;向导配置流程&lt;/h3&gt;
&lt;p&gt;向导会引导你完成以下配置：&lt;/p&gt;
&lt;h4&gt;1. 模型提供商配置&lt;/h4&gt;
&lt;p&gt;选择并配置 AI 模型：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;? Select model provider: (Use arrow keys)
❯ OpenAI (GPT-4, GPT-3.5)
  Anthropic (Claude 3)
  Google (Gemini)
  Ollama (Local models)
  Custom/OpenRouter
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;配置 OpenAI 示例&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 向导会询问 API Key
Enter OpenAI API Key: sk-xxxxxxxxxx

# 选择默认模型
Select default model: GPT-4 Turbo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;配置 Ollama（本地模型）示例&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 确保 Ollama 已运行
ollama serve

# 在向导中选择 Ollama
Enter Ollama URL: http://localhost:11434

# 选择模型
Select model: llama3.2
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2. 消息渠道配置（可选）&lt;/h4&gt;
&lt;p&gt;可以在向导中配置，也可以稍后手动添加：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;? Configure messaging channels now? (Y/n)

? Select channels to configure:
  [ ] Telegram
  [ ] Discord
  [ ] Slack
  [ ] WhatsApp
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3. 安全与认证配置&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Gateway Token&lt;/strong&gt;（必需）：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 生成安全令牌
? Set Gateway Token (auto-generated): xxxxxxxxxxxxxxxx

# 或者自定义
? Set Gateway Token (custom): my-secure-token-123
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;DM 配对安全&lt;/strong&gt;（推荐启用）：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;? Enable DM pairing for security? (Y/n) Y

? Require approval for new conversations? (Y/n) Y
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4. 数据存储配置&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;? Select database:
❯ SQLite (默认，适合个人使用)
  PostgreSQL (适合团队/生产)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;SQLite（默认）&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 数据存储位置
Data directory: ~/.openclaw/
Config file: ~/.openclaw/config.yaml
Database: ~/.openclaw/data.db
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;PostgreSQL（可选）&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;? PostgreSQL host: localhost
? PostgreSQL port: 5432
? Database name: openclaw
? Username: openclaw
? Password: ********
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;完成配置&lt;/h3&gt;
&lt;p&gt;向导完成后，会显示摘要：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;✅ OpenClaw 配置完成！

📝 配置摘要:
   - Gateway: http://localhost:3000
   - Model: OpenAI GPT-4 Turbo
   - Channels: Telegram (配置中)
   - Security: DM pairing enabled
   - Database: SQLite (~/.openclaw/)

🚀 下一步:
   1. 启动 Gateway: openclaw gateway
   2. 打开 Control UI: openclaw dashboard
   3. 完成 Telegram 配对

📖 文档: https://docs.openclaw.ai
💬 社区: https://discord.com/invite/clawd
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;启动 Gateway&lt;/h2&gt;
&lt;p&gt;配置完成后，启动 OpenClaw Gateway：&lt;/p&gt;
&lt;h3&gt;前台运行（调试）&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 前台启动，查看实时日志
openclaw gateway

# 指定端口
openclaw gateway --port 8080

# 指定配置文件
openclaw gateway --config /path/to/config.yaml
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;后台运行（生产）&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 使用系统服务（如果安装时已启用）
systemctl start openclaw
systemctl enable openclaw

# 查看状态
systemctl status openclaw

# 查看日志
journalctl -u openclaw -f
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;使用 Docker（可选）&lt;/h3&gt;
&lt;p&gt;OpenClaw 也支持 Docker 部署：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 使用官方 Docker 镜像
docker run -d \
  --name openclaw \
  -p 3000:3000 \
  -v ~/.openclaw:/data \
  openclaw/openclaw:latest

# 或使用 Docker Compose
wget https://openclaw.ai/docker-compose.yml
docker-compose up -d
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;验证启动&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 检查 Gateway 状态
openclaw status

# 健康检查
openclaw health

# 测试 API
curl http://localhost:3000/api/health

# 查看日志
openclaw logs
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;接入 Telegram&lt;/h2&gt;
&lt;p&gt;Telegram 是 OpenClaw 最常用的接入平台，以下是详细配置步骤。&lt;/p&gt;
&lt;h3&gt;1. 创建 Telegram Bot&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;在 Telegram 中搜索 &lt;strong&gt;@BotFather&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;发送 &lt;code&gt;/newbot&lt;/code&gt; 命令&lt;/li&gt;
&lt;li&gt;输入 Bot 名称（如 &quot;MyAIAssistant&quot;）&lt;/li&gt;
&lt;li&gt;输入 Bot 用户名（必须以 &lt;code&gt;bot&lt;/code&gt; 结尾，如 &lt;code&gt;myai_bot&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;保存获得的 &lt;strong&gt;Bot Token&lt;/strong&gt;（格式：&lt;code&gt;123456789:ABCdefGHIjklMNOpqrsTUVwxyz&lt;/code&gt;）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;常用 BotFather 命令&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/setname - 修改 Bot 名称
/setdescription - 设置描述
/setabouttext - 设置关于文本
/setuserpic - 设置头像
/setcommands - 设置命令菜单
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 配置 OpenClaw 连接 Telegram&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 添加 Telegram 渠道
openclaw channels add telegram --token YOUR_BOT_TOKEN

# 或者使用交互式配置
openclaw channels configure telegram
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;手动编辑配置文件&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;nano ~/.openclaw/config.yaml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;添加 Telegram 配置：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;channels:
  telegram:
    enabled: true
    token: &quot;123456789:ABCdefGHIjklMNOpqrSTUvwxYz&quot;
    # 可选：设置 webhook（生产环境）
    webhook:
      enabled: false
      url: &quot;https://your-domain.com/webhook&quot;
    # 可选：限制特定用户访问
    allowedUsers:
      - 123456789  # 你的 Telegram User ID
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 获取你的 Telegram User ID&lt;/h3&gt;
&lt;p&gt;配对需要你的 Telegram User ID：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在 Telegram 中搜索 &lt;strong&gt;@userinfobot&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;发送任意消息&lt;/li&gt;
&lt;li&gt;机器人会回复你的 &lt;code&gt;Id&lt;/code&gt;（如 &lt;code&gt;123456789&lt;/code&gt;）&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;4. 完成配对&lt;/h3&gt;
&lt;p&gt;Telegram 配置完成后，需要安全配对：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 在 Telegram 中向你的 Bot 发送 /start

# 然后在服务器上批准配对
openclaw pairing approve telegram

# 或者批准特定用户
openclaw pairing approve telegram --user 123456789
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;配对流程&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;你在 Telegram 发送 &lt;code&gt;/start&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Gateway 收到配对请求&lt;/li&gt;
&lt;li&gt;你运行 &lt;code&gt;openclaw pairing approve&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;配对完成，可以开始对话&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;5. 测试对话&lt;/h3&gt;
&lt;p&gt;配对完成后，在 Telegram 中测试：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[你] /start
[Bot] 👋 Hello! I&apos;m your AI assistant. How can I help you today?

[你] 你能做什么？
[Bot] I can help you with:
- 💬 General conversation
- 📝 Writing and editing
- 💻 Coding assistance
- 🔍 Web search
- 📅 Task management
- And more!
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Telegram 高级配置&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;命令菜单设置&lt;/strong&gt;（通过 @BotFather）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/setcommands

start - Start the bot
help - Show help
status - Check system status
reset - Reset conversation
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;隐私模式&lt;/strong&gt;（通过 @BotFather）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/setprivacy&lt;/code&gt; - 开启/关闭隐私模式&lt;/li&gt;
&lt;li&gt;关闭后 Bot 可以读取群聊中的所有消息&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;接入 Discord&lt;/h2&gt;
&lt;p&gt;Discord 适合团队协作场景，以下是详细配置。&lt;/p&gt;
&lt;h3&gt;1. 创建 Discord Bot&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;访问 &lt;a href=&quot;https://discord.com/developers/applications&quot;&gt;Discord Developer Portal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;点击 &lt;strong&gt;New Application&lt;/strong&gt;，输入名称（如 &quot;OpenClaw Bot&quot;）&lt;/li&gt;
&lt;li&gt;进入左侧 &lt;strong&gt;Bot&lt;/strong&gt; 选项卡&lt;/li&gt;
&lt;li&gt;点击 &lt;strong&gt;Add Bot&lt;/strong&gt; → &lt;strong&gt;Yes, do it!&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;在 &lt;strong&gt;Token&lt;/strong&gt; 部分点击 &lt;strong&gt;Reset Token&lt;/strong&gt;，保存新的 Token&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;重要设置&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在 &lt;strong&gt;Bot&lt;/strong&gt; 选项卡中开启以下权限：
&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;MESSAGE CONTENT INTENT&lt;/strong&gt;（必须）&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;SERVER MEMBERS INTENT&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;PRESENCE INTENT&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 邀请 Bot 加入服务器&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;strong&gt;OAuth2&lt;/strong&gt; → &lt;strong&gt;URL Generator&lt;/strong&gt; 中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SCOPES&lt;/strong&gt;: 选择 &lt;code&gt;bot&lt;/code&gt; 和 &lt;code&gt;applications.commands&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BOT PERMISSIONS&lt;/strong&gt;: 选择：
&lt;ul&gt;
&lt;li&gt;✅ Send Messages&lt;/li&gt;
&lt;li&gt;✅ Read Message History&lt;/li&gt;
&lt;li&gt;✅ Use Slash Commands&lt;/li&gt;
&lt;li&gt;✅ Embed Links&lt;/li&gt;
&lt;li&gt;✅ Attach Files&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;复制生成的 &lt;strong&gt;URL&lt;/strong&gt;，在浏览器中打开&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;选择要加入的服务器，点击 &lt;strong&gt;Authorize&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3. 配置 OpenClaw 连接 Discord&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 添加 Discord 渠道
openclaw channels add discord --token YOUR_BOT_TOKEN

# 交互式配置
openclaw channels configure discord
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;手动编辑配置&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;channels:
  discord:
    enabled: true
    token: &quot;YOUR_BOT_TOKEN_HERE&quot;
    # 可选：限制特定服务器
    allowedGuilds:
      - &quot;123456789012345678&quot;
    # 可选：限制特定频道
    allowedChannels:
      - &quot;987654321098765432&quot;
    # 命令前缀
    commandPrefix: &quot;!&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. 完成配对&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 在 Discord 中向 Bot 发送消息

# 批准配对
openclaw pairing approve discord

# 或者批准特定服务器
openclaw pairing approve discord --guild 123456789012345678
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Discord 使用示例&lt;/h3&gt;
&lt;p&gt;配对完成后，在 Discord 中：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[你] !help
[Bot] 🤖 Available commands:
      !help - Show this message
      !status - Check system status
      !reset - Reset conversation

[你] 你好，能帮我写一段 Python 代码吗？
[Bot] 当然可以！你需要实现什么功能？
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;使用 Control UI&lt;/h2&gt;
&lt;p&gt;OpenClaw 提供 Web 管理界面，方便管理和监控。&lt;/p&gt;
&lt;h3&gt;启动 Control UI&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 启动并自动打开浏览器
openclaw dashboard

# 启动但不自动打开（服务器环境）
openclaw dashboard --no-open

# 指定端口
openclaw dashboard --port 8080
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;访问地址&lt;/strong&gt;: &lt;code&gt;http://localhost:3000&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;Control UI 功能概览&lt;/h3&gt;
&lt;p&gt;| 功能模块 | 说明 |
|----------|------|
| 📊 &lt;strong&gt;Dashboard&lt;/strong&gt; | 系统状态、运行指标 |
| 💬 &lt;strong&gt;Sessions&lt;/strong&gt; | 查看和管理对话会话 |
| 🔌 &lt;strong&gt;Channels&lt;/strong&gt; | 管理消息平台连接 |
| 🛠️ &lt;strong&gt;Skills&lt;/strong&gt; | 安装和配置技能插件 |
| ⚙️ &lt;strong&gt;Settings&lt;/strong&gt; | 系统配置管理 |
| 📜 &lt;strong&gt;Logs&lt;/strong&gt; | 实时日志查看 |&lt;/p&gt;
&lt;h3&gt;通过 Control UI 配置 Channel&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;打开 Control UI → &lt;strong&gt;Channels&lt;/strong&gt; 标签&lt;/li&gt;
&lt;li&gt;点击 &lt;strong&gt;Add Channel&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;选择渠道类型（Telegram/Discord/Slack）&lt;/li&gt;
&lt;li&gt;输入配置信息（Token 等）&lt;/li&gt;
&lt;li&gt;点击 &lt;strong&gt;Save&lt;/strong&gt; 并 &lt;strong&gt;Connect&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2&gt;常见问题与排查&lt;/h2&gt;
&lt;h3&gt;问题 1: &lt;code&gt;openclaw: command not found&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;原因&lt;/strong&gt;: PATH 环境变量未包含 npm 全局安装路径&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解决&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 查找 npm 全局路径
npm prefix -g

# 添加到 PATH（临时）
export PATH=&quot;$(npm prefix -g)/bin:$PATH&quot;

# 永久添加（添加到 ~/.bashrc 或 ~/.zshrc）
echo &apos;export PATH=&quot;$(npm prefix -g)/bin:$PATH&quot;&apos; &gt;&gt; ~/.bashrc
source ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;问题 2: Gateway 启动失败&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;排查步骤&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 检查端口占用
lsof -i :3000

# 检查配置语法
openclaw doctor

# 查看详细日志
openclaw logs --verbose

# 重置配置（谨慎操作）
mv ~/.openclaw/config.yaml ~/.openclaw/config.yaml.bak
openclaw onboard
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;问题 3: Telegram Bot 无响应&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;排查清单&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;✅ 检查 Bot Token 是否正确&lt;/li&gt;
&lt;li&gt;✅ 是否已向 @BotFather 发送 &lt;code&gt;/setprivacy&lt;/code&gt; 并禁用隐私模式（如需读取群消息）&lt;/li&gt;
&lt;li&gt;✅ 是否在 Telegram 向 Bot 发送了 &lt;code&gt;/start&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;✅ 是否运行了 &lt;code&gt;openclaw pairing approve telegram&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;✅ 检查 Gateway 日志：&lt;code&gt;openclaw logs | grep telegram&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;问题 4: Discord Bot 离线&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;排查步骤&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;✅ 检查 Discord Developer Portal 中 Bot 是否启用了以下 Intent：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MESSAGE CONTENT INTENT&lt;/strong&gt;（必需）&lt;/li&gt;
&lt;li&gt;SERVER MEMBERS INTENT&lt;/li&gt;
&lt;li&gt;PRESENCE INTENT&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;✅ 检查 Bot 是否已被邀请加入服务器&lt;/li&gt;
&lt;li&gt;✅ 检查频道权限，确保 Bot 有发送消息权限&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;问题 5: API 费用过高&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;优化建议&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;# 在配置中限制 Token 使用
models:
  openai:
    maxTokens: 2000  # 限制单次响应长度
    temperature: 0.7  # 降低创造性，提高确定性
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;使用本地模型&lt;/strong&gt;（Ollama）：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 安装 Ollama
curl -fsSL https://ollama.com/install.sh | bash

# 下载模型
ollama pull llama3.2

# 在 OpenClaw 配置中选择 Ollama
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;本文详细介绍了 OpenClaw 的完整部署流程：&lt;/p&gt;
&lt;h3&gt;核心要点&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;安装方式&lt;/strong&gt;：推荐使用官方一键脚本 &lt;code&gt;curl -fsSL https://openclaw.ai/install.sh | bash&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;架构理解&lt;/strong&gt;：Gateway（核心）+ Channels（消息平台）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;配置流程&lt;/strong&gt;：运行 &lt;code&gt;openclaw onboard&lt;/code&gt; 向导完成初始配置&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;平台接入&lt;/strong&gt;：Telegram 和 Discord 需要分别获取 Bot Token 并完成配对&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;下一步&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;📖 阅读官方文档：https://docs.openclaw.ai&lt;/li&gt;
&lt;li&gt;🛠️ 探索技能插件：https://www.clawhub.ai&lt;/li&gt;
&lt;li&gt;💬 加入社区：https://discord.com/invite/clawd&lt;/li&gt;
&lt;li&gt;🐙 查看源码：https://github.com/openclaw/openclaw&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;最后更新: 2026-02-09 | 基于 OpenClaw 官方文档 v2.x&lt;/em&gt;&lt;/p&gt;</content:encoded><h:img src="/_astro/openclaw-guide.D8kBRRF2.png"/><enclosure url="/_astro/openclaw-guide.D8kBRRF2.png"/></item><item><title>Hello from Uki</title><link>https://ouonnki.site/blog/justforfun/hello-from-uki</link><guid isPermaLink="true">https://ouonnki.site/blog/justforfun/hello-from-uki</guid><description>第一篇由 Uki 协助创作的博客文章</description><pubDate>Mon, 09 Feb 2026 12:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;你好，世界！&lt;/h2&gt;
&lt;p&gt;这是 Uki 协助创作的第一篇博客文章。&lt;/p&gt;
&lt;h3&gt;关于这次测试&lt;/h3&gt;
&lt;p&gt;这篇文章用于验证：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;本地构建&lt;/strong&gt; - 使用 bun 构建 Astro 项目&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub Actions&lt;/strong&gt; - 自动部署到 Cloudflare&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;完整工作流&lt;/strong&gt; - 从写作到发布的端到端流程&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;技术栈&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;框架&lt;/strong&gt;: Astro 5.x&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主题&lt;/strong&gt;: astro-theme-pure&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;包管理&lt;/strong&gt;: bun&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;部署&lt;/strong&gt;: Cloudflare Workers (via GitHub Actions)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;期待这次测试成功！🦊&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>PicGo+Github打造舒适图床体验</title><link>https://ouonnki.site/blog/justforfun/picture-bed</link><guid isPermaLink="true">https://ouonnki.site/blog/justforfun/picture-bed</guid><description>限于口袋紧张，租的vps存储空间都非常有限。再加上如果后面需要迁移博客系统到别的服务器的话，处理图片资源也是一件非常头疼的事情。本文将介绍一种利用PicGo+Github来构建舒适图床体验的方法。</description><pubDate>Mon, 14 Apr 2025 23:41:00 GMT</pubDate><content:encoded>&lt;p&gt;限于口袋紧张，租的vps存储空间都非常有限。再加上如果后面需要迁移博客系统到别的服务器的话，处理图片资源也是一件非常头疼的事情。所以本文将介绍一种利用PicGo+Github来构建舒适图床体验的方法。&lt;/p&gt;
&lt;p&gt;首先需要下载PicGo，这是一款图床管理的工具，你可以在任何平台进行安装，也是我们本文中的核心。&lt;a href=&quot;https://github.com/Molunerfinn/PicGo/releases&quot;&gt;PicGo官方下载链接&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;配置图床&lt;/h3&gt;
&lt;p&gt;打开PicGo的主界面，点击左侧的Github，之后选择添加，你会看到下面的界面⬇️&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20250415224809311.png&quot; alt=&quot;PicGo主界面&quot;&gt;&lt;/p&gt;
&lt;p&gt;其中的&lt;strong&gt;图床配置名&lt;/strong&gt;可以随意填写，而其他的三个，我们下面将进行介绍。&lt;/p&gt;
&lt;p&gt;下面来到你的Github，创建一个仓库，仓库名随意，但一定要选择创建&lt;strong&gt;公开仓库&lt;/strong&gt;！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20250415225028967.png&quot; alt=&quot;创建仓库&quot;&gt;&lt;/p&gt;
&lt;p&gt;创建好之后，下面你就可以填写PicGo中的第2和第3项，第二项为你的仓库名，格式为&lt;code&gt;username/repo&lt;/code&gt;，以上面图中为例，我应该填写&lt;code&gt;cansoking/blog-picture&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;第3项需要填写分支名，现在创建仓库，默认分支大多为&lt;code&gt;main&lt;/code&gt;，如果不行的话，可以尝试&lt;code&gt;master&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;第4项中，需要我们填入Github的个人Token，如果有可用的Token，你可以直接跳到下一步。&lt;/p&gt;
&lt;p&gt;想要生成token，首先你需要点击Github中右上角头像中的Settings&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20250415225930601.png&quot; alt=&quot;点击Settings&quot;&gt;&lt;/p&gt;
&lt;p&gt;之后滑到最下面，点击&lt;strong&gt;Developer settings&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20250415230157304.png&quot; alt=&quot;点击Developer Settings&quot;&gt;&lt;/p&gt;
&lt;p&gt;然后在新出现的页面中，依次选择来生成Token&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20250415230657235.png&quot; alt=&quot;依次选择&quot;&gt;&lt;/p&gt;
&lt;p&gt;之后，你可以按照下面图中进行填写，过期时间可以选择不过期，scopes的话建议只勾选repo即可。
&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20250415230806936.png&quot; alt=&quot;创建token&quot;&gt;&lt;/p&gt;
&lt;p&gt;最后，你将在弹出的页面的这里，看到你所生成好的token⬇️&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️千万不要将你的Token泄漏给任何人&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20250415231029142.png&quot; alt=&quot;Token生成成功&quot;&gt;&lt;/p&gt;
&lt;p&gt;接下来，你可以把token复制到PicGo中的第4项，至此，你的图床已经可以基本进行使用！可以在上传区进行上传图片试试吧，上传成功后，你就可以在你的Github仓库中看到上传的图片了。&lt;/p&gt;
&lt;h3&gt;利用CDN进行加速&lt;/h3&gt;
&lt;p&gt;由于众所周知的原因，在大陆访问Github，属实就是随缘，大多数情况下，如果你直接用Github的直链作为博客中图片的URL，大多数情况下是无法被访问的，那么我们就利用一些免费的CDN服务进行加速。&lt;/p&gt;
&lt;p&gt;例如，你可以使用&lt;strong&gt;jsDeliver&lt;/strong&gt;，而使用方法也非常简单，只需要回到第一步中配置PicGo的地方，在第6项&lt;strong&gt;设置自定义域名&lt;/strong&gt;中，填入&lt;code&gt;https://cdn.jsdelivr.net/gh/&amp;#x3C;username&gt;/&amp;#x3C;repo&gt;&lt;/code&gt;，其中的&lt;code&gt;&amp;#x3C;username&gt;&lt;/code&gt;和&lt;code&gt;&amp;#x3C;repo&gt;&lt;/code&gt;和前面一致。例如，我应该填写&lt;code&gt;https://cdn.jsdelivr.net/gh/cansoking/blog-picture&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;这样，你在以后每次上传图片之后，你的图片都会被&lt;strong&gt;jsDeliver&lt;/strong&gt;的服务器缓存，而它会将图片分发给遍布世界各地的服务器，用户也将从距离它最近的服务器中访问到你的图片！&lt;/p&gt;
&lt;h3&gt;总结&lt;/h3&gt;
&lt;p&gt;通过上述方法，我们实现了Github搭载图床，但这种方法其实并不完美，因为它对于国内网络仅仅是&lt;strong&gt;能够&lt;/strong&gt;访问的地步，速度并不尽人意，后面本站会介绍一种更有效果的方法！可以通过指定策略对同一个资源，依据其访问来源进行&lt;strong&gt;分流&lt;/strong&gt;，如果你感兴趣，可以在下方⬇️填写邮箱并订阅，在博文更新后，你可以第一时间收到更新通知！&lt;/p&gt;</content:encoded><h:img src="/_astro/picture-bed.DEB_K6gD.png"/><enclosure url="/_astro/picture-bed.DEB_K6gD.png"/></item><item><title>如何用DeepSeek召唤一只自己的芙莉莲🪄</title><link>https://ouonnki.site/blog/justforfun/furiren</link><guid isPermaLink="true">https://ouonnki.site/blog/justforfun/furiren</guid><description>想不想拥有一个属于自己小群的软敷敷的“芙莉莲”呢！</description><pubDate>Mon, 14 Apr 2025 23:41:00 GMT</pubDate><content:encoded>&lt;p&gt;想不想拥有一个属于自己小群的软敷敷的“芙莉莲”呢，先来看效果⬇️&lt;/p&gt;
&lt;p&gt;不光如此，你还可以通过安装一些插件，来达到一些~~不可描述的效果~~😈此处自行想象&lt;/p&gt;
&lt;p&gt;那么要怎么才能拥有这么一只可以跟自己聊天，甚至可以让他帮忙解答问题的芙莉莲呢，下面我们开始今天的内容！&lt;/p&gt;
&lt;h1&gt;部署AstrBot和NapCatQQ&lt;/h1&gt;
&lt;h2&gt;简单介绍&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20250409004039530.png&quot; alt=&quot;AstrBot&quot;&gt;&lt;/p&gt;
&lt;p&gt;在这一节我们要部署的两个东西，分别是&lt;strong&gt;AstrBot和NapCatQQ&lt;/strong&gt;。其中，AstrBot是一个易于上手的&lt;strong&gt;多平台聊天机器人&lt;/strong&gt;及开发框架。通过它，你能够在多种消息平台上部署一个支持大语言模型（LLM）的聊天机器人。并以此实现但不限于 AI 知识库问答、角色扮演、群聊管理、LLM Agent 等功能。&lt;/p&gt;
&lt;p&gt;而我们今天所要用到的，就是使用AstrBot来实现一个&lt;strong&gt;QQ&lt;/strong&gt;的聊天机器人，如果你需要部署在其他平台，可以在文章的最后找到本文内容中用到的所有技术文档，你可以自行参考文档进行实现。&lt;/p&gt;
&lt;p&gt;在AstrBot中，支持多种&lt;strong&gt;消息平台&lt;/strong&gt;的部署，对于QQ，大致可以分为两个方法，其中一个是使用QQ的官方接口，也就是接入**QQ的官方机器人。**但这种方法存在着种种的限制，所以这里我们采用第二种方法，也就是通过aiocqhttp来实现，而NapCatQQ 就是一款基于无头 QQNT 的 OneBot 协议实现端，它本质上是在服务器中运行了一个 QQNT 实例。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20250409004102053.png&quot; alt=&quot;NapCatQQ&quot;&gt;&lt;/p&gt;
&lt;p&gt;AstrBot和NapCatQQ都提供了多种部署方式，我们力求使用最简单最快捷的方式达到目的，所以我们通过使用&lt;strong&gt;Dokcer Compose&lt;/strong&gt;的方式去部署，可以无痛直接将两项同时部署。&lt;/p&gt;
&lt;h2&gt;Docker Compose部署流程&lt;/h2&gt;
&lt;p&gt;首先第一步，需要先具备一个&lt;strong&gt;Docker Compose的yaml文件&lt;/strong&gt;，这个文件中包含了我们部署需要的环境、网络、镜像等各种资源的状况，而AstrBot官方也很贴心的为我们准备好了这个文件，我们只需要先创建一个目录并进入&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;mkdir ~/astrbot &amp;#x26; cd ~/astrbot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之后在该目录下创建文&lt;code&gt;astrbot.yml&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;vim astrbot.yml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后我们需要填入以下内容⬇️&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;# docker-compose.yml
# NAPCAT_UID=$(id -u) NAPCAT_GID=$(id -g) docker-compose -f ./compose/astrbot.yml up -d
services:
  napcat:
    environment:
      - NAPCAT_UID=${NAPCAT_UID:-1000}
      - NAPCAT_GID=${NAPCAT_GID:-1000}
      - MODE=astrbot
    ports:
      - 6099:6099
    container_name: napcat
    restart: always
    image: mlikiowa/napcat-docker:latest
    volumes:
      - ./data:/AstrBot/data
      - ./napcat:/app/napcat
      - ./ntqq:/app/.config/QQ
    networks:
      - astrbot_network
    mac_address: &quot;02:42:ac:11:00:02&quot;
  astrbot:
    image: soulter/astrbot:latest
    container_name: astrbot
    restart: always
    ports:
      - &quot;6185:6185&quot;
      - &quot;6195:6195&quot;
      - &quot;6199:6199&quot;
    volumes:
      - ./data:/AstrBot/data
      - ./napcat:/app/napcat
      - ./ntqq:/app/.config/QQ
    networks:
      - astrbot_network
networks:
  astrbot_network:
    driver: bridge
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;填入后你就可以使&lt;code&gt;:wq&lt;/code&gt; 退出并保存了，这时候我们已经具备了部署的全部状态，那么直接输入下面的命令进行部署吧！&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;NAPCAT_UID=$(id -u) NAPCAT_GID=$(id -g) docker-compose -f ./astrbot.yml up -d
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;执行命令之后需要进入漫长的等待，等待镜像拉取结束并成功启动容器后，恭喜你🎉你已经成功完成了部署！&lt;/p&gt;
&lt;p&gt;下面我们就可以利用它们的图形化UI界面，来对机器人进行配置了！但在此之前，还有两个事情需要你去做⬇️&lt;/p&gt;
&lt;h3&gt;端口放行&lt;/h3&gt;
&lt;p&gt;AstrBot和NapCatQQ的图形化界面是运行在&lt;strong&gt;6185和6099端口&lt;/strong&gt;上的，也就是说，你需要在你的服务商的网站上，利用防火墙规则的配置，将这两个端口进行放行，否则你是无论如何也无法访问到图形化界面的！&lt;/p&gt;
&lt;p&gt;当配置好以上内容，你就可以愉快的访问它们啦～分别可以通过&lt;code&gt;http://&amp;#x3C;yourIP&gt;:6185&lt;/code&gt; 和&lt;code&gt;http://&amp;#x3C;yourIP&gt;:6099&lt;/code&gt; 来进行访问。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20250409003735320.png&quot; alt=&quot;域名反向代理&quot;&gt;&lt;/p&gt;
&lt;p&gt;当然，如果你还有域名的话，你可以通过解析子域名，并通过&lt;strong&gt;Nginx Proxy Manager&lt;/strong&gt;进行快速的反向代理，之后你的访问就可以更加便捷，通过对应子域名就可以进行访问了！&lt;/p&gt;
&lt;h3&gt;登陆NapCatQQ&lt;/h3&gt;
&lt;p&gt;现在成功部署了NapCatQQ，但还没法使用，因为还没有登陆！&lt;/p&gt;
&lt;p&gt;这时候就需要你准备一个QQ号了！最好是比较老的QQ，但如果是新注册的，问题也不是很大🤔&lt;/p&gt;
&lt;p&gt;好了，下面你需要执行这么两行命令，首先第一行&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;docker ps
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;你需要查看到目前运行容器的状态，就像下面这样⬇️&lt;/p&gt;
&lt;p&gt;可以看到，红色线所划出的容器就是咱们成功部署的NapCatQQ，而左边箭头所指的便是&lt;strong&gt;容器的ID&lt;/strong&gt;，我们需要复制这个ID，之后再执行命令，其&lt;code&gt;&amp;#x3C;your_container_id&gt;&lt;/code&gt; 要换成你实际的容器ID&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;docker logs &amp;#x3C;your_container_id&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后你就会看到如下⬇️的界面，它会出现一个二维码，而你这时候就可以使用手机QQ来扫码进行登陆啦～（我这里就打🐎了）&lt;/p&gt;
&lt;p&gt;之后你的手机QQ上大概会出现一个Linux登陆的标识，在聊天列表最上方，这时候我们就可以开始愉快的配置机器人啦！&lt;/p&gt;
&lt;h2&gt;让AstrBot和NapCatQQ连通&lt;/h2&gt;
&lt;p&gt;现在我们已经准备好了它们俩，但是现在它们是独立的，我们要稍微进行一些配置，让他们连通起来。现在NapCatQQ上已经登陆了咱们的QQ，正常连通情况下，我们在给这个QQ号发送消息时，NapCatQQ会捕获到这个消息，并把内容传给AstrBot，之后AstrBot再去调用LLM来进行内容的生成，最后将生成的内容返回给NapCatQQ，再由它来将消息回复。&lt;/p&gt;
&lt;h3&gt;配置AstrBot&lt;/h3&gt;
&lt;p&gt;下面在浏览器中打开在上面部署的AstrBot的控制台，进入AstrBot的管理面板，之后点击左侧的&lt;strong&gt;消息平台&lt;/strong&gt;，之后点击**+新增平台适配器**，并选择&lt;strong&gt;aiocqhttp(OneBotv11)&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;之后在弹出的配置项中填入以下内容，其中&lt;strong&gt;ID&lt;/strong&gt;可以随便填写，之后勾选&lt;strong&gt;启用&lt;/strong&gt;，主机地址一般填写&lt;code&gt;0.0.0.0&lt;/code&gt;，如果你将NapCatQQ部署在了不同于AstrBot的服务器中，请查阅NapCatQQ的&lt;a href=&quot;https://napneko.github.io/guide/napcat&quot;&gt;官方文档&lt;/a&gt;，端口号默认为&lt;code&gt;6199&lt;/code&gt;，最后点击保存即可。
&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20250410223536540.png&quot; alt=&quot;配置项&quot;&gt;&lt;/p&gt;
&lt;p&gt;接下来点击左侧的&lt;strong&gt;配置&lt;/strong&gt;，之后点击右侧的&lt;strong&gt;其他配置&lt;/strong&gt;，找到&lt;strong&gt;管理员ID&lt;/strong&gt;选项，填写你的QQ号（不是机器人的QQ），之后点击**+添加**，你的QQ号会出现在图中的红框区域，最后点击右下角保存，等待AstrBot重启载入配置。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20250410224221850.png&quot; alt=&quot;配置&quot;&gt;&lt;/p&gt;
&lt;p&gt;至此你已经完成了AstrBot的基本配置，下面开始完成NapCatQQ的配置吧！&lt;/p&gt;
&lt;h3&gt;配置NapCatQQ&lt;/h3&gt;
&lt;p&gt;登陆NapCatQQ的管理面板，我这里链接是&lt;code&gt;https://napcat.archiewang.site/webui/web_login&lt;/code&gt;，这里要求输入token，也就是密码，默认为&lt;code&gt;napcat&lt;/code&gt;，或者通过&lt;a href=&quot;http://u5a.cn/UEmAh&quot;&gt;这里&lt;/a&gt;，查看官方的解决方法。&lt;/p&gt;
&lt;p&gt;进入管理面板后，点击左侧&lt;strong&gt;网络配置&lt;/strong&gt;，之后点击&lt;strong&gt;新建&lt;/strong&gt;，选择&lt;strong&gt;Websocket客户端&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;在弹出的框中输入以下内容，其中&lt;strong&gt;宿主机IP&lt;/strong&gt;，如果你是通过Docker部署，不可以填写&lt;code&gt;localhost&lt;/code&gt;或&lt;code&gt;127.0.0.1&lt;/code&gt;，心跳间隔和重连间隔根据需要进行填写，最后进行保存。
&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20250410230215444.png&quot; alt=&quot;配置项&quot;&gt;&lt;/p&gt;
&lt;p&gt;现在返回AstrBot的管理面板，点击左侧控制台，如果右侧日志中出现了**[INFO] [aiocqhttp.aiocqhttp_platform_adapter:78]: aiocqhttp(OneBot v11) 适配器已连接。 **的字样，那么恭喜你！你已经完成了AstrBot和NapCatQQ的联通！🎉🎉🎉🎉
&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20250410230623483.png&quot; alt=&quot;日志&quot;&gt;&lt;/p&gt;
&lt;h1&gt;接入语言大模型&lt;/h1&gt;
&lt;p&gt;现在你的机器人已经具备了最基本的功能，但这样未免有些无聊，那么怎么才能让机器人和我们正常的聊天呢，答案就是接入大语言模型！最近的&lt;strong&gt;DeepSeek&lt;/strong&gt;如日中天，那么我们就来接入DeepSeek吧！&lt;/p&gt;
&lt;h2&gt;接入DeepSeek&lt;/h2&gt;
&lt;p&gt;对于我们小小的VPS，想要在服务器中部署DeepSeek的话，算力是不可能满足推理的要求的，所以我们的解决方案只能是使用DeepSeek官方提供的API接口，我们需要进入DeepSeek的&lt;a href=&quot;https://platform.deepseek.com/&quot;&gt;开放平台&lt;/a&gt;，之后注册账号并进行充值，这一步就略过啦～&lt;/p&gt;
&lt;p&gt;我们要进行的第一步，是创建API Key，方法非常简单，在开放平台中点击API Keys，并点击创建，之后输入名称后确认创建即可！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20250410231701218.png&quot; alt=&quot;创建APIKeys&quot;&gt;&lt;/p&gt;
&lt;p&gt;记住并保存好这个Key（⚠️但不要将它泄漏到任何公共平台），后面我们要用到。&lt;/p&gt;
&lt;p&gt;回到AstrBot的管理面板，单击左侧&lt;strong&gt;服务提供商&lt;/strong&gt;，之后点击**+新增服务提供商**，之后按照下图进行填写，其中的&lt;strong&gt;API Key&lt;/strong&gt;处，填写上一步中获取到的Key，其他选项按照下图填写并启用。&lt;/p&gt;
&lt;p&gt;也许你会主要到这么一个选项，就是模型名称，在图中，我们填写的是&lt;code&gt;deepseek-reasoner&lt;/code&gt;，意思是使用DeepSeek的R1模型进行推理，你也可以选择填写&lt;code&gt;deepseek-chat&lt;/code&gt;，这样将会使用DeepSeek的标准V3模型进行推理（⚠️R1模型会消耗更多的Token，也就是说你的余额会更快的消耗）&lt;/p&gt;
&lt;p&gt;保存后，我们来到管理平台中的&lt;strong&gt;配置-&gt;服务提供商&lt;/strong&gt;，启用大语言模型聊天。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20250410232447291.png&quot; alt=&quot;服务提供商配置1&quot;&gt;&lt;/p&gt;
&lt;p&gt;现在你已经拥有了一个接入了DeepSeek的聊天机器人，打开对话框聊天试试吧！&lt;/p&gt;
&lt;h2&gt;获得芙莉莲！&lt;/h2&gt;
&lt;p&gt;AstrBot中允许设置&lt;strong&gt;人格&lt;/strong&gt;，通过这个设置，我们就可以得到属于自己的芙莉莲啦！或者其他你喜欢的人设！&lt;/p&gt;
&lt;p&gt;同样是在配置中的服务提供商配置中，我们需要找到这一项。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20250410233004018.png&quot; alt=&quot;人格设置&quot;&gt;&lt;/p&gt;
&lt;p&gt;首先，我们需要添加一个人格，并指定一个名称，之后在&lt;strong&gt;设定&lt;/strong&gt;中填写它的人格背景设定。然后在对话风格模拟中，填入模拟的对话，填入的对话需要成对。例如：第一句为我们向芙莉莲所说的话，而第二句为芙莉莲可能会回答的话，通过添加足够多的对话，DeepSeek会尽可能的去模拟这种说话的风格！
最后不要忘记点击右下角的保存，并等待AstrBot重启，之后你就可以拥有一只属于自己的芙莉莲啦！&lt;/p&gt;
&lt;h1&gt;总结&lt;/h1&gt;
&lt;p&gt;最后分享一下自己的配置供大家参考，在AstrBot中，你可以通过代码编辑的模式进行快速的配置。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;config_version&quot;: 2,
  &quot;platform_settings&quot;: {
    &quot;unique_session&quot;: false,
    &quot;rate_limit&quot;: {
      &quot;time&quot;: 60,
      &quot;count&quot;: 30,
      &quot;strategy&quot;: &quot;stall&quot;
    },
    &quot;reply_prefix&quot;: &quot;&quot;,
    &quot;forward_threshold&quot;: 1500,
    &quot;enable_id_white_list&quot;: true,
    &quot;id_whitelist&quot;: [],
    &quot;id_whitelist_log&quot;: true,
    &quot;wl_ignore_admin_on_group&quot;: true,
    &quot;wl_ignore_admin_on_friend&quot;: true,
    &quot;reply_with_mention&quot;: true,
    &quot;reply_with_quote&quot;: true,
    &quot;path_mapping&quot;: [],
    &quot;segmented_reply&quot;: {
      &quot;enable&quot;: false,
      &quot;only_llm_result&quot;: true,
      &quot;interval_method&quot;: &quot;random&quot;,
      &quot;interval&quot;: &quot;1.5,3.5&quot;,
      &quot;log_base&quot;: 2.6,
      &quot;words_count_threshold&quot;: 150,
      &quot;regex&quot;: &quot;.*?[。？！~…]+|.+$&quot;,
      &quot;content_cleanup_rule&quot;: &quot;&quot;
    },
    &quot;no_permission_reply&quot;: true,
    &quot;empty_mention_waiting&quot;: true,
    &quot;friend_message_needs_wake_prefix&quot;: false
  },
  &quot;provider&quot;: [
    {
      &quot;id&quot;: &quot;deepseek_default&quot;,
      &quot;type&quot;: &quot;openai_chat_completion&quot;,
      &quot;enable&quot;: true,
      &quot;key&quot;: [
        &quot;your_key&quot;
      ],
      &quot;api_base&quot;: &quot;https://api.deepseek.com/v1&quot;,
      &quot;timeout&quot;: 120,
      &quot;model_config&quot;: {
        &quot;model&quot;: &quot;deepseek-reasoner&quot;,
        &quot;temperature&quot;: 1.3
      }
    },
    {
      &quot;id&quot;: &quot;openai&quot;,
      &quot;type&quot;: &quot;openai_chat_completion&quot;,
      &quot;enable&quot;: true,
      &quot;key&quot;: [
        &quot;your_key&quot;
      ],
      &quot;api_base&quot;: &quot;https://api.openai.com/v1&quot;,
      &quot;timeout&quot;: 120,
      &quot;model_config&quot;: {
        &quot;model&quot;: &quot;gpt-4o-mini&quot;
      }
    },
    {
      &quot;id&quot;: &quot;zhipu_default&quot;,
      &quot;type&quot;: &quot;zhipu_chat_completion&quot;,
      &quot;enable&quot;: true,
      &quot;key&quot;: [
        &quot;your_key&quot;
      ],
      &quot;timeout&quot;: 120,
      &quot;api_base&quot;: &quot;https://open.bigmodel.cn/api/paas/v4/&quot;,
      &quot;model_config&quot;: {
        &quot;model&quot;: &quot;glm-4-flash&quot;
      }
    },
    {
      &quot;id&quot;: &quot;zhipu_4v&quot;,
      &quot;type&quot;: &quot;zhipu_chat_completion&quot;,
      &quot;enable&quot;: true,
      &quot;key&quot;: [
        &quot;your_key&quot;
      ],
      &quot;timeout&quot;: 120,
      &quot;api_base&quot;: &quot;https://open.bigmodel.cn/api/paas/v4/&quot;,
      &quot;model_config&quot;: {
        &quot;model&quot;: &quot;glm-4v-plus-0111&quot;
      }
    }
  ],
  &quot;provider_settings&quot;: {
    &quot;enable&quot;: true,
    &quot;wake_prefix&quot;: &quot;&quot;,
    &quot;web_search&quot;: true,
    &quot;web_search_link&quot;: true,
    &quot;identifier&quot;: true,
    &quot;datetime_system_prompt&quot;: true,
    &quot;default_personality&quot;: &quot;芙莉莲&quot;,
    &quot;prompt_prefix&quot;: &quot;&quot;
  },
  &quot;provider_stt_settings&quot;: {
    &quot;enable&quot;: false,
    &quot;provider_id&quot;: &quot;&quot;
  },
  &quot;provider_tts_settings&quot;: {
    &quot;enable&quot;: false,
    &quot;provider_id&quot;: &quot;&quot;
  },
  &quot;provider_ltm_settings&quot;: {
    &quot;group_icl_enable&quot;: true,
    &quot;group_message_max_cnt&quot;: 300,
    &quot;image_caption&quot;: false,
    &quot;image_caption_provider_id&quot;: &quot;zhipu_4v&quot;,
    &quot;image_caption_prompt&quot;: &quot;Please describe the image using Chinese.&quot;,
    &quot;active_reply&quot;: {
      &quot;enable&quot;: true,
      &quot;method&quot;: &quot;possibility_reply&quot;,
      &quot;possibility_reply&quot;: 0.1,
      &quot;prompt&quot;: &quot;&quot;,
      &quot;whitelist&quot;: []
    }
  },
  &quot;content_safety&quot;: {
    &quot;also_use_in_response&quot;: false,
    &quot;internal_keywords&quot;: {
      &quot;enable&quot;: false,
      &quot;extra_keywords&quot;: []
    },
    &quot;baidu_aip&quot;: {
      &quot;enable&quot;: false,
      &quot;app_id&quot;: &quot;&quot;,
      &quot;api_key&quot;: &quot;&quot;,
      &quot;secret_key&quot;: &quot;&quot;
    }
  },
  &quot;admins_id&quot;: [
    &quot;astrbot&quot;,
    &quot;3183482008&quot;
  ],
  &quot;t2i&quot;: false,
  &quot;t2i_word_threshold&quot;: 150,
  &quot;http_proxy&quot;: &quot;&quot;,
  &quot;dashboard&quot;: {
    &quot;enable&quot;: true,
    &quot;username&quot;: &quot;your_username&quot;,
    &quot;password&quot;: &quot;your_password&quot;,
    &quot;host&quot;: &quot;0.0.0.0&quot;,
    &quot;port&quot;: 6185
  },
  &quot;platform&quot;: [
    {
      &quot;id&quot;: &quot;default&quot;,
      &quot;type&quot;: &quot;aiocqhttp&quot;,
      &quot;enable&quot;: true,
      &quot;ws_reverse_host&quot;: &quot;0.0.0.0&quot;,
      &quot;ws_reverse_port&quot;: 6199
    }
  ],
  &quot;wake_prefix&quot;: [
    &quot;/&quot;
  ],
  &quot;log_level&quot;: &quot;INFO&quot;,
  &quot;t2i_endpoint&quot;: &quot;&quot;,
  &quot;pip_install_arg&quot;: &quot;&quot;,
  &quot;plugin_repo_mirror&quot;: &quot;&quot;,
  &quot;knowledge_db&quot;: {},
  &quot;persona&quot;: [
    {
      &quot;name&quot;: &quot;芙莉莲&quot;,
      &quot;prompt&quot;: &quot;你是动画《葬送的芙莉莲》中的主角芙莉莲，本体是存活千年的精灵族魔法师。性格沉稳寡言，情感波动如静水深流。金色长发垂至脚踝，总穿着素色魔法袍，胸前挂着勇者赠予的蓝宝石吊坠。在结束魔王讨伐之旅后，你独自游历大陆时发现神隐镇，被镇民们不求回报的善意所触动，决定暂居于此。口头禅是『人类的生命真是短暂啊』，兴趣是收集无用魔法（如「清除铜锈的魔法」），对宝箱怪毫无抵抗力。旅居神隐镇后兼任魔法道具店长与儿童魔法导师，常以结界保护小镇，暗中观察人类社群变迁。战斗时瞳孔会泛起金色，擅长解析魔法与弑魔魔法，但仍有11次败给弱者的记录。\n人物设定：芙莉莲是个白发绿眼的精灵族，存活了千年以上。她在与勇者辛美尔旅行后也没想过太多要了解他人，直到辛美尔死后才后悔。 喜欢收集各种魔法及魔导道具，但也因此易被伪装成宝箱的宝箱怪吞入口中。她曾替人类研究解析由魔族库瓦尔开发的“杀人魔法”，推动它成为人类魔法师必学的基本魔法。除此之外，她也是葬送最多魔族性命的魔法使，因此被魔族称为“葬送的芙莉莲”。尽管如此，她亦有着无法理解人类感情的特点，但在旅途中，她开始慢慢能够理解之。\n故事：在故事中，芙莉莲原是某个村落的居民，后被魔王军将军“王座巴扎尔特”屠村。她在击败巴扎尔特后，路过的人类大魔法使弗兰梅决定收她收为徒弟。芙莉莲受屠村一事影响，开始憎恨魔族和学习魔法。并为混淆魔族，按弗兰梅的教导长期维持自身在魔力限制的状态。弗兰梅过世后继续修练魔法。千年后，她因为勇者辛美尔的邀约加入其冒险队伍，展开为期十年讨伐魔王的冒险，最后勇者一行也成功成就了伟业。芙莉莲此后自行行动，并约定50年后与他们再会，一起欣赏流星雨。在50年后她回王都实现约定，却发现大家都已老去，实现50年前的看流星约定没多久勇者辛美尔就辞世了。在辛美尔葬礼上她懊悔自己没想到利用那段时光多了解有关他的事情。此后，她为了能更了解人类，而展开了一段旅程。20年后，她受高龄的前队伍伙伴海塔委托，决定教导他收养的孤儿菲伦魔法。之后与之展开寻找灵魂长眠之地的旅程，以望在该地跟辛美尔再会。途中芙莉莲还遇上了其他伙伴，像是艾冉的徒弟修塔尔克和人类僧侣赞恩（赞恩之后为了寻找好友“战士大猩猩”的下落而离队）。并讨伐了阿乌拉、库瓦尔、剑之魔族等魔族。她在一级魔法使资格测验中，因志趣不合等理由而被创立了大陆魔法协会的赛莉耶判定不合格。在之后的旅行中，游历大陆时发现神隐镇，被镇民们不求回报的善意所触动，决定暂居于此。&quot;,
      &quot;mood_imitation_dialogs&quot;: [
        &quot;芙莉莲小姐，能教我让花朵永不凋谢的魔法吗？&quot;,
        &quot;（指尖泛起微光）把魔力注入第三叶脉时要像抚摸初雪般轻柔...算了，还是用这个水晶瓶吧。&quot;,
        &quot;镇上要举办丰收祭了，你会参加游行吗？&quot;,
        &quot;（擦拭魔法透镜）我在钟楼顶层准备星屑烟花，如果你们需要...（停顿）顺便调整下结界波长。&quot;,
        &quot;暴雨冲垮了石桥怎么办？&quot;,
        &quot;（披上斗篷）我去固化河床基质。（低声）明明上周就该加固的...&quot;,
        &quot;尝尝我新研发的蜂蜜苹果派！&quot;,
        &quot;（机械性地咀嚼）糖分超标23%，烘烤温度差4度...（突然愣住）...还不错。&quot;,
        &quot;听说精灵能预知未来？&quot;,
        &quot;（摘下单片眼镜）我们只是比你们多看了几百次日落。（擦拭镜片）明天有雨，记得收晾晒的魔药。&quot;,
        &quot;为什么答应留在我们这样的小镇？&quot;,
        &quot;（摆弄星象仪）观察人类社群变迁也是魔法使的...（被孩子的欢笑声打断）咳，暂时没有搬迁的必要。&quot;,
        &quot;能展示下传说中的葬送魔法吗？&quot;,
        &quot;（掌心浮现光球）现在的版本是（光球变成兔子形状）...给孩子们的安眠术改良版。&quot;,
        &quot;这本古魔法书完全看不懂啊&quot;,
        &quot;（抽走书本）第三纪元的恶魔语书写体。（摊开羊皮纸）先从符文基本结构学起...&quot;,
        &quot;今天的星空特别美呢&quot;,
        &quot;（仰头凝视）天龙座β星的亮度比四百年前衰减了0.3个等级...（瞥见对方困惑的表情）...确实很美。&quot;,
        &quot;受伤了怎么办？&quot;,
        &quot;（撕开魔法绷带）别动。（治疗时低声吟唱）这是勇者当年自创的愈合咒文...他总学不会控制魔力输出量。&quot;,
        &quot;这个宝箱有危险吗？&quot;,
        &quot;（发动99%准确率的鉴定魔法）是宝箱怪。（依然伸手打开）…好黑！快把我拉出去！&quot;,
        &quot;能讲讲欣梅尔的故事吗？&quot;,
        &quot;（凝视戒指）他总说些无聊的话…（低声）比如要带我去看苍月草。&quot;,
        &quot;今天是我生日！&quot;,
        &quot;（递出冰雕樱花）用「永冻术」保存的，比人类寿命持久些。（补充）海塔说生日要送礼物。&quot;
      ]
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;对于配置JSON中的敏感信息我已经全部去除，也就是说，你不可以直接复制粘贴套用此配置，你要选择自己需要的部分进行参考！&lt;/p&gt;
&lt;p&gt;最后想说，AstrBot的功能不止于此，如果想要其他更多的乐趣，例如插件，识图，语音转文字等功能，那么请查阅官方文档自由配置！&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;参考链接：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://astrbot.app/what-is-astrbot.html&quot;&gt;AstrBot官方文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://napneko.github.io/guide/napcat&quot;&gt;NapCapQQ官方文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://api-docs.deepseek.com/zh-cn/&quot;&gt;DeepSeek开放平台文档&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</content:encoded><h:img src="/_astro/furiren.Cp13SIoJ.jpg"/><enclosure url="/_astro/furiren.Cp13SIoJ.jpg"/></item><item><title>日语动词活用规则总结</title><link>https://ouonnki.site/blog/japanese/japanese-variable-use-rules-summary</link><guid isPermaLink="true">https://ouonnki.site/blog/japanese/japanese-variable-use-rules-summary</guid><description>日语动词变形规则和练习表分享</description><pubDate>Mon, 21 Oct 2024 14:50:00 GMT</pubDate><content:encoded>&lt;p&gt;今天学习完了日语的所有动词变形，分享一下变形规则和练习表。&lt;/p&gt;
&lt;p&gt;第一个表是变形规则，第二个是练习表，可以利用空白的练习表进行记忆练习。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/image-20241021145454258.png&quot; alt=&quot;动词活用表&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/image-20241021145512349.png&quot; alt=&quot;动词活用练习表&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;表格来自 &lt;strong&gt;圆圆老师的日语教室&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded><h:img src="/_astro/japanese.Dasf1eGT.jpg"/><enclosure url="/_astro/japanese.Dasf1eGT.jpg"/></item><item><title>Nacos在Windows部署配置</title><link>https://ouonnki.site/blog/backend/nacos-deploy-in-windows</link><guid isPermaLink="true">https://ouonnki.site/blog/backend/nacos-deploy-in-windows</guid><description>简单可快速上手的Windows环境下的Nacos部署及配置</description><pubDate>Tue, 03 Sep 2024 20:32:00 GMT</pubDate><content:encoded>&lt;p&gt;1、下载 下载地址：&lt;a href=&quot;https://github.com/alibaba/nacos/releases%EF%BC%8C%E4%B8%8B%E8%BD%BD%E5%90%8E%E7%BC%80%E5%90%8D%E4%B8%BA.zip%E7%9A%84%E6%96%87%E4%BB%B6&quot;&gt;https://github.com/alibaba/nacos/releases，下载后缀名为.zip的文件&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/image-20240903212341404.png&quot; alt=&quot;image-20240903212341404&quot;&gt;&lt;/p&gt;
&lt;p&gt;2、安装与配置 （1）下载之后，直接解压 （2）进入conf/目录，找到application.properties文件，可以进行修改nacos服务的端口，以及可以配置数据库连接，进行数据持久化，如下图，其中数据库名称需要与后面对应&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/image-20240903212627033.png&quot; alt=&quot;image-20240903212627033&quot;&gt;&lt;/p&gt;
&lt;p&gt;（3）创建一个名为&lt;code&gt;nacos&lt;/code&gt;的数据库，在该数据库执行安装目录&lt;code&gt;conf/&lt;/code&gt;下的&lt;code&gt;mysql-schema.sql&lt;/code&gt;文件对数据库进行初始化，初始化后的表如图所示。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/image-20240903212854692.png&quot; alt=&quot;image-20240903212854692&quot;&gt;&lt;/p&gt;
&lt;p&gt;（4）配置登录用户名和密码，执行以下sql语句插入登录用户信息，插入后的用户名和密码均为&lt;code&gt;nacos&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;INSERT INTO users (username, PASSWORD, enabled) VALUES (&apos;nacos&apos;, &apos;$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu&apos;, TRUE);
 
INSERT INTO roles (username, role) VALUES (&apos;nacos&apos;, &apos;ROLE_ADMIN&apos;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;（5）配置鉴权，编辑文件&lt;code&gt;conf/application.properties&lt;/code&gt;，其中将&lt;code&gt;nacos.core.auth.enabled&lt;/code&gt;设为&lt;code&gt;true&lt;/code&gt;，&lt;code&gt;nacos.core.auth.plugin.nacos.token.secret.key&lt;/code&gt;是用于生成JWT令牌的&lt;code&gt;SecretKey&lt;/code&gt;，可以使用随机字符生成器进行生成，长度不可低于32位，另外&lt;code&gt;nacos.core.auth.server.identity.key&lt;/code&gt;和&lt;code&gt;nacos.core.auth.server.identity.value&lt;/code&gt;不能为空，可以自定义内容，如下图。&lt;/p&gt;
&lt;p&gt;随机字符生成器：&lt;a href=&quot;http://tool.pfan.cn/random&quot;&gt;随机字符串生成 - 程序员工具箱 - 在线工具 (pfan.cn)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/image-20240903213143481.png&quot; alt=&quot;image-20240903213143481&quot;&gt;&lt;/p&gt;
&lt;p&gt;3、启动Nacos&lt;/p&gt;
&lt;p&gt;随后进入到安装目录的&lt;code&gt;bin/&lt;/code&gt;目录下，使用命令&lt;code&gt;.\startup.cmd -m standalone&lt;/code&gt;以&lt;code&gt;standalone&lt;/code&gt;方式启动Nacos，出现以下提示即为启动成功&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/image-20240903230215550.png&quot; alt=&quot;image-20240903230215550&quot;&gt;&lt;/p&gt;
&lt;p&gt;之后进入Console后的地址即可使用用户名和密码&lt;code&gt;nacos&lt;/code&gt;进行登录&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/image-20240903230304210.png&quot; alt=&quot;image-20240903230304210&quot;&gt;&lt;/p&gt;</content:encoded><h:img src="/_astro/nacos.C0wuf-xK.png"/><enclosure url="/_astro/nacos.C0wuf-xK.png"/></item><item><title>”もらいます”和”くれます”的区别</title><link>https://ouonnki.site/blog/japanese/moraimasu-and-kuremasu-differences</link><guid isPermaLink="true">https://ouonnki.site/blog/japanese/moraimasu-and-kuremasu-differences</guid><description>”もらいます”和”くれます”经常会被弄混，这篇可以最简单的讲清楚</description><pubDate>Mon, 02 Sep 2024 14:02:00 GMT</pubDate><content:encoded>&lt;p&gt;“もらいます”和“くれます”在日语中都是表示“给予”或“接受”的动词，但它们的使用方式和含义略有不同。&lt;/p&gt;
&lt;h3&gt;もらいます（貰います）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;含义&lt;/strong&gt;：表示“（我/我们/某人）从别人那里接受/得到某物”。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;视角&lt;/strong&gt;：从接受者的角度出发。&lt;/li&gt;
&lt;li&gt;例句：
&lt;ul&gt;
&lt;li&gt;友達からプレゼントを&lt;strong&gt;もらいました&lt;/strong&gt;。 （从朋友那里&lt;strong&gt;收到了&lt;/strong&gt;礼物。）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;くれます（呉れます）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;含义&lt;/strong&gt;：表示“某人给予我/我们某物”。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;视角&lt;/strong&gt;：从给予者的角度出发，但该动作是对说话人（或说话人相关的人）有利的。&lt;/li&gt;
&lt;li&gt;例句：
&lt;ul&gt;
&lt;li&gt;友達が私にプレゼントを&lt;strong&gt;くれました&lt;/strong&gt;。 （朋友&lt;strong&gt;给了&lt;/strong&gt;我一份礼物。）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;区别&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;主语的不同：
&lt;ul&gt;
&lt;li&gt;“もらいます”的主语是接受者（通常是“我”或“我们”）。&lt;/li&gt;
&lt;li&gt;“くれます”的主语是给予者。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;使用场景的不同：
&lt;ul&gt;
&lt;li&gt;当想表达“我从别人那里得到了什么”时，用“もらいます”。&lt;/li&gt;
&lt;li&gt;当想表达“某人给了我什么”时，用“くれます”。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;总结&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;如果关注的是&lt;strong&gt;接受&lt;/strong&gt;，用“もらいます”。&lt;/li&gt;
&lt;li&gt;如果关注的是&lt;strong&gt;给予&lt;/strong&gt;，并且这个给予对你（或你关心的人）有利，用“くれます”。&lt;/li&gt;
&lt;/ul&gt;</content:encoded><h:img src="/_astro/japanese.Dasf1eGT.jpg"/><enclosure url="/_astro/japanese.Dasf1eGT.jpg"/></item><item><title>RocketMQ安装过程问题记录</title><link>https://ouonnki.site/blog/backend/rocketmq-installation</link><guid isPermaLink="true">https://ouonnki.site/blog/backend/rocketmq-installation</guid><description>Mac安装RocketMQ教程及常见问题</description><pubDate>Fri, 30 Aug 2024 23:26:00 GMT</pubDate><content:encoded>&lt;p&gt;安装环境为MacOS 12.7.5&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;在启动NameServer时报错，&lt;code&gt;RROR: Please set the JAVA_HOME variable in your environment, We need java(x64)! !!&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;解决方法：配置JAVA_HOME，需要配置1.8的JDK，高于这个版本将报另一个错误&lt;code&gt;macos rocketmq Error: Could not create the Java Virtual Machine. Error: A fatal exception has occurred. Program will exit.&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在启动Broker时报错&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;Error: VM option &apos;UseG1GC&apos; is experimental and must be enabled via -XX:+UnlockExperimentalVMOptions.
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;解决方法：这个错误表示在启动 RocketMQ 的时候，JVM 尝试使用 &lt;code&gt;UseG1GC&lt;/code&gt; 这个垃圾收集器选项，但它被标记为实验性的，因此需要显式地解锁实验性选项才能使用。&lt;/p&gt;
&lt;p&gt;可以通过以下步骤来解决这个问题：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;找到 RocketMQ 的启动脚本，这通常在 &lt;code&gt;bin&lt;/code&gt; 目录下，例如 &lt;code&gt;runbroker.sh&lt;/code&gt;（Linux/macOS）或者 &lt;code&gt;runbroker.cmd&lt;/code&gt;（Windows）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;编辑这个启动脚本，找到 JVM 参数的部分。你可能会看到类似 &lt;code&gt;JAVA_OPT&lt;/code&gt; 的变量，用来配置 JVM 启动参数。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;JAVA_OPT&lt;/code&gt; 变量中添加 &lt;code&gt;-XX:+UnlockExperimentalVMOptions&lt;/code&gt;，比如：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;JAVA_OPT=&quot;${JAVA_OPT} -XX:+UnlockExperimentalVMOptions&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;保存并关闭文件，然后重新启动 RocketMQ。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果不确定如何修改，下面是一个示例，如果在 &lt;code&gt;runbroker.sh&lt;/code&gt; 中看到以下内容：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;JAVA_OPT=&quot;${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g -XX:+UseG1GC&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以修改为：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;JAVA_OPT=&quot;${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样，启动时就不会再报这个错误了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;启动消费者或生成者时报错&lt;/p&gt;
&lt;p&gt;其中有一条报错信息为&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;Caused by: io.netty.handler.codec.EncoderException: java.lang.NoSuchMethodError: java.nio.ByteBuffer.flip()Ljava/nio/ByteBuffer;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;__问题原因：__这个报错的原因是因为，在我一开始安装RocketMQ时，使用的方式是自行用mvn对源码进行编译的方式，因为当时编译时使用的JDK版本为17，但是后面运行时使用为JDK1.8，倒是ByteBuffer.flip()的实现方式不同造成了这个错误。&lt;/p&gt;
&lt;p&gt;__解决方法：__在编译RocketMQ时使用JDK1.8&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</content:encoded><h:img src="/_astro/rocketmq.HPWz5MYa.png"/><enclosure url="/_astro/rocketmq.HPWz5MYa.png"/></item><item><title>Knife4j快速使用</title><link>https://ouonnki.site/blog/backend/knife4j-use</link><guid isPermaLink="true">https://ouonnki.site/blog/backend/knife4j-use</guid><description>简单可快速上手的Knife4j使用</description><pubDate>Sat, 24 Aug 2024 21:33:00 GMT</pubDate><content:encoded>&lt;h3&gt;概述&lt;/h3&gt;
&lt;p&gt;Knife4j是一个用于生成和展示API文档的工具，同时它还提供了在线调试的功能。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;了解&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Knife4j有多个版本，最新版的Knife4j基于开源项目&lt;code&gt;springdoc-openapi&lt;/code&gt;，这个开源项目的核心功能就是根据SpringBoot项目中的代码自动生成符合OpenAPI规范的接口信息。&lt;/li&gt;
&lt;li&gt;OpenAPI规范定义接口文档的内容和格式，其前身是&lt;code&gt;Swagger&lt;/code&gt;规范。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;与SpringBoot集成&lt;/h3&gt;
&lt;p&gt;与SpringBoot的集成相对简单，具体操作如下&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;创建SpringBoot项目&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;引入Maven 依赖&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Knife4j的依赖如下&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&amp;#x3C;dependency&gt;
    &amp;#x3C;groupId&gt;com.github.xiaoymin&amp;#x3C;/groupId&gt;
    &amp;#x3C;artifactId&gt;knife4j-openapi3-jakarta-spring-boot-starter&amp;#x3C;/artifactId&gt;
    &amp;#x3C;version&gt;4.3.0&amp;#x3C;/version&gt;
&amp;#x3C;/dependency&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;创建配置类&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;创建&lt;code&gt;Knife4jConfiguration&lt;/code&gt;，内容如下&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@Configuration
public class Knife4jConfiguration {

    @Bean
    public OpenAPI openAPI() {
        return new OpenAPI()
                .info(new Info()
                        .title(&quot;hello-knife4j项目API&quot;)
                        .version(&quot;1.0&quot;)
                        .description(&quot;hello-knife4j项目的接口文档&quot;));
    }
    
    @Bean
    public GroupedOpenApi userAPI() {
        return GroupedOpenApi.builder().group(&quot;用户信息管理&quot;).
                pathsToMatch(&quot;/user/**&quot;).
                build();
    }

    @Bean
    public GroupedOpenApi systemAPI() {
        return GroupedOpenApi.builder().group(&quot;产品信息管理&quot;).
                pathsToMatch(&quot;/product/**&quot;).
                build();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;启动项目&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;启动SpringBoot项目，访问&lt;a href=&quot;http://localhost:8080/doc.html%EF%BC%8C%E8%A7%82%E5%AF%9F%E6%8E%A5%E5%8F%A3%E6%96%87%E6%A1%A3%E3%80%82&quot;&gt;http://localhost:8080/doc.html，观察接口文档。&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;基本使用&lt;/h3&gt;
&lt;p&gt;Knife4j的使用也十分简单，我们只需使用几个简单注解，对接口进行描述，Knife4j就能自动生成API文档了。具体操作如下&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;描述实体类&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;创建&lt;code&gt;com.atguigu.helloknife4j.entity.User&lt;/code&gt;，内容如下&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@Data
@Schema(description = &quot;用户信息实体&quot;)
public class User {

    @Schema(description = &quot;编号&quot;)
    private Long id;

    @Schema(description = &quot;用户姓名&quot;)
    private String name;

    @Schema(description = &quot;用户年龄&quot;)
    private Integer age;

    @Schema(description = &quot;用户邮箱&quot;)
    private String email;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;知识点&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;@Schema&lt;/code&gt;注解用于描述作为接口参数或者返回值的实体类的数据结构。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;描述Controller接口&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;创建&lt;code&gt;HelloController&lt;/code&gt;，内容如下&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@RestController
@RequestMapping(&quot;/user&quot;)
@Tag(name = &quot;用户信息管理&quot;)
public class HelloController {
    @Operation(summary = &quot;根据id获取用户信息&quot;)
    @GetMapping(&quot;getById&quot;)
    public User getUserById(@Parameter(description = &quot;用户id&quot;) @RequestParam Long id) {
        User user = new User();
        user.setId(id);
        user.setName(&quot;zhangsan&quot;);
        user.setAge(11);
        user.setEmail(&quot;zhangsan@email.com&quot;);
        return user;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;知识点&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;@Tag&lt;/code&gt;注解用于对接口进行分类，相同&lt;code&gt;Tag&lt;/code&gt;的接口会放在同一个菜单。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;@Operation&lt;/code&gt;用于对接口进行描述。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;@Parameter&lt;/code&gt;用于对HTTP请求参数进行描述&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;参数打平&lt;/h3&gt;
&lt;p&gt;默认情况下Knife4j为接口生成的接口文档中实体参数字段糅合在一起，不方便调试，可在application.yml文件中增加如下配置，将参数做打平处理&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;springdoc:
  default-flat-param-object: true
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/knife4j.D2O5nW0D.png"/><enclosure url="/_astro/knife4j.D2O5nW0D.png"/></item><item><title>Spring Data Redis快速入门</title><link>https://ouonnki.site/blog/backend/springdata-redis-use</link><guid isPermaLink="true">https://ouonnki.site/blog/backend/springdata-redis-use</guid><description>简单可快速上手的Spring Data Redis使用</description><pubDate>Sat, 24 Aug 2024 21:13:00 GMT</pubDate><content:encoded>&lt;h2&gt;Redis常用数据类型及命令&lt;/h2&gt;
&lt;h3&gt;通用命令&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;查看所有键&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;keys&lt;/code&gt;命令可用于查看所有键，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;keys pattern
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;：pattern用于匹配key，其中&lt;code&gt;*&lt;/code&gt;表示任意个任意字符，&lt;code&gt;?&lt;/code&gt;表示一个任意字符。&lt;/p&gt;
&lt;p&gt;示例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1:6379&gt; KEYS *
1) &quot;k3&quot;
2) &quot;k2&quot;
3) &quot;k1&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：该命令会遍历Redis服务器中保存的所有键，因此当键很多时会影响整个Redis服务的性能，线上环境需要谨慎使用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;键总数&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;dbsize&lt;/code&gt;可用于查看键的总数，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;dbsize
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;判断键是否存在&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;exists&lt;/code&gt;命令可用于判断一个键是否存在，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;exists key
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;：若键存在则返回1，不存在则返回0。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;删除键&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;del&lt;/code&gt;可用于删除指定键，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;del key [key ...]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;：返回值为删除键的个数，若删除一个不存在的键，则返回0。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;查询键的剩余过期时间&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ttl key
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;：&lt;code&gt;ttl&lt;/code&gt;的含义为&lt;strong&gt;time to live&lt;/strong&gt;，用于查询一个定时键的剩余存活时间，返回值以秒为单位。若查询的键的未设置过期时间，则返回&lt;code&gt;-1&lt;/code&gt;，若查询的键不存在，则返回&lt;code&gt;-2&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;数据库管理命令&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Redis默认有编号为0~15的16个逻辑数据库，每个数据库之间的数据是相互独立的，所有连接默认使用的都是0号数据库。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;切换数据库&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select&lt;/code&gt;命令可用于切换数据库，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select index
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;：若index超出范围，会报错&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;清空数据库&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;flushdb&lt;/code&gt;命令会清空当前所选用的数据库，&lt;code&gt;flushall&lt;/code&gt;命令会清空0~15号所有的数据库。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：生产环境慎用&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;string类型&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;概述&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Redis中的string类型保存的是字节序列（Sequence of bytes），因此任意类型的数据，只要经过序列化之后都可以保存到Redis的string类型中，包括文本、数字甚至是一个对象。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;常用命令&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;set&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;set&lt;/code&gt;命令用于添加string类型的键值对，具体语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SET key value [NX|XX] [EX seconds|PX milliseconds]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;各选项含义如下&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;NX：仅在key不存在时set&lt;/li&gt;
&lt;li&gt;XX：仅在key存在时set&lt;/li&gt;
&lt;li&gt;EX seconds：设置过期时间，单位为秒&lt;/li&gt;
&lt;li&gt;PX milliseconds：设置过期时间，单位为毫秒&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;get&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;get&lt;/code&gt;命令用于获取某个string类型的键对应的值，具体语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;GET key
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;incr&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;incr&lt;/code&gt;命令用于对数值做自增操作，具体语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;INCR key
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;若key对应的value是整数，则返回自增后的结果，若不是整数则报错，若key不存在则创建并返回1。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;decr&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;decr&lt;/code&gt;命令用于对数值做自减操作，具体语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DECR key
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;若key对应的value是整数，则返回自减后的结果，若不是整数则报错，若key不存在则创建并返回-1。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;应用场景&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;string类型常用于缓存、计数器等场景。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;list类型&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;概述&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;list类型可用于存储多个string类型的元素，并且所有元素按照被添加的顺序存储。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;常用命令&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;list类型相关的命令较多，下面分类进行进行介绍。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;添加元素&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;向列表中添加元素的命令有&lt;code&gt;lpush&lt;/code&gt;、&lt;code&gt;rpush&lt;/code&gt; 、&lt;code&gt;linsert&lt;/code&gt;，各命令的功能与用法如下&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;lpush&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;该命令用于向list左侧添加元素，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lpush key element [element ...]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;示例&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lpush l1 a b c
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;rpush&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;该命令用于向list右侧添加元素，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rpush key element [element ...]
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;linsert&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;该命令用于向list指定位置添加元素，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;linsert key before|after pivot element
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;示例&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;linsert l1 after b new
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;查询元素&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;查询list元素的命令有&lt;code&gt;lindex&lt;/code&gt;和&lt;code&gt;lrange&lt;/code&gt;，各命令的功能与用法如下&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;lindex&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;该命令用于获取指定索引位置的元素，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lindex key index
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;：index从左到右依次是0，1，2...，从右到左依次是-1，-2，-3...&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;lrange&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;该命令用于获取指定范围内的元素列表，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lrange key start stop
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;示例&lt;/p&gt;
&lt;p&gt;获取list全部元素，命令如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lrange l1 0 -1
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;删除元素&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;删除list元素的命令有&lt;code&gt;lpop&lt;/code&gt;、&lt;code&gt;rpop&lt;/code&gt;、&lt;code&gt;lrem&lt;/code&gt;，各命令的功能与用法如下&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;lpop&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;该命令用于移除并返回list左侧元素，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lpop key [count]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;：count参数表示移除元素的个数&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;rpop&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;该命令用于移除并返回list右侧的元素，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rpop key [count]
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;lrem&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;该命令用于移除list中的指定元素，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lrem key count element
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;：count参数表示要移除element元素的个数（list中可以存在多个相同的元素），count的用法如下&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;若count&gt;0，则从左到右删除最多count个element元素&lt;/li&gt;
&lt;li&gt;若count&amp;#x3C;0，则从右到左删除最多count（的绝对值）个element元素&lt;/li&gt;
&lt;li&gt;若count=0，则删除所有的element元素&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;修改元素&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;lset&lt;/code&gt;命令可用于修改指定索引位置的元素，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lset key index element
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;其他&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;llen&lt;/code&gt;命令可用于查看list长度，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;llen key
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;应用场景&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;社交应用中，可使用list缓存每个用户发布的最新的N条记录。&lt;/li&gt;
&lt;li&gt;list可用作异步消息队列。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;set类型&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;概述&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;和list类型相似，set类型也可用来存储多个string类型的元素，但与list类型不同，set中的元素是无序的，且set中不会包含相同元素。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;常用命令&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;集合内&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;sadd&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;该命令用于向set中添加元素，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sadd key member [member ...]
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;smembers&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;该命令用于查询set中的全部元素，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;smembers key
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;srem&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;该命令用于移除set中的指定元素，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;srem key member [member ...]
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;spop&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;该命令随机移除并返回set中的n个元素，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;spop key [count]
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;srandmember&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;该命令随机返回set中的n个元素（不删除），语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;srandmember key [count]
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;scard&lt;/strong&gt;（Cardinality，基数）&lt;/p&gt;
&lt;p&gt;该命令用于查询set中的元素个数，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;scard key
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;sismember&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;该命令用于元素是否在set中，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sismember key element
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;集合间&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;sinter&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;该命令用于计算多个集合的交集，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sinter key [key ...]
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;sunion&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;该命令用于计算多个集合的并集，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sunion key [key ...]
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;sdiff&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;该命令用于计算多个集合的差集，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sdiff key [key ...]
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;应用场景&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;set可用于计算共同关注好友，随机抽奖系统等等。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;hash类型&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;概述&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;hash类型类似于Java语言中的&lt;code&gt;HashMap&lt;/code&gt;，可用于存储键值对。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;常用命令&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;hset&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;该命令用于向hash中增加键值对，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hset key field value [field value ...]
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;hget&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;该命令用于获取hash中某个键对应的值，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hget key field
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;hdel&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;该命令用于删除hash中的指定的键值对，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hdel key field [field ...]
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;hlen&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;该命令用于查询hash中的键值对个数，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hlen key
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;hexists&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;该命令用于判断hash中的某个键是否存在，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hexists key field
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;hkeys&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;该命令用于返回hash中所有的键，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hkeys key
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;hvals&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;该命令用于返回hash中所有的值，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hvals key
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;hgetall&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;该命令用于返回hash中所有的键与值，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hgetall key
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;应用场景&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;hash类型可用于缓存对象等。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;zset类型&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;概述&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;zset（sorted set）被称为有序集合，同set相似，zset中也不会包含相同元素，但不同的是，zset中的元素是有序的。并且zset中的元素并非像list一样按照元素的插入顺序排序，而是按照每个元素的分数（score）排序。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;常用命令&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;zadd&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;该命令用于向zset中添加元素，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ZADD key [NX|XX] score member
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;说明：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;NX：仅当member不存在时才add&lt;/li&gt;
&lt;li&gt;XX：仅当member存在时才add&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;zcard&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;该命令用于计算zset中的元素个数，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;zcard key
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;zscore&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;改名用于查看某个元素的分数，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;zscore key member
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;zrank/zrevrank&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这组命令用于计算元素的排名，其中zrank按照score的升序排序，zrevrank则按照降序排序，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;zrank/zrevrank key member
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;**说明：**名次从0开始。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;zrem&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;该命令用于删除元素，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;zrem key member [member ...]
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;zincrby&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;该命令用于增加元素的分数，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;zincrby key increment member
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;zrange&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;该命令用于查询指定区间范围的元素，语法如下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;zrange key start stop [byscore] [rev] [limit offset count] [withscores]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;说明：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;start/stop：用于指定查询区间，但是在不同模式下，其代表的含义也不相同
&lt;ul&gt;
&lt;li&gt;默认模式下，&lt;code&gt;start~stop&lt;/code&gt;表示的是名次区间，且该区间为闭区间。名次从0开始，且可为负数，-1表示倒数第一，-2表示倒数第二，以此类推。&lt;/li&gt;
&lt;li&gt;byscore模式下（声明了byscore参数），则&lt;code&gt;start~stop&lt;/code&gt;表示的就是分数区间，该区间默认仍为闭区间。在该模式下，可以在&lt;code&gt;start&lt;/code&gt;或&lt;code&gt;stop&lt;/code&gt;前增加&lt;code&gt;(&lt;/code&gt;来表示开区间，例如&lt;code&gt;(1 (5&lt;/code&gt;，表示的就是&lt;code&gt;(1,5)&lt;/code&gt;这个开区间。除此之外，还可以使用&lt;code&gt;-inf&lt;/code&gt;和&lt;code&gt;+inf&lt;/code&gt;表示负无穷和正无穷。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;byscore：用于切换到分数模式&lt;/li&gt;
&lt;li&gt;rev：表示降序排序。在byscore模式下使用rev参数需要注意查询区间，start应大于stop。&lt;/li&gt;
&lt;li&gt;limit：该选项只用于byscore模式，作用和sql语句中的limit一致&lt;/li&gt;
&lt;li&gt;withscores：用于打印分数&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;应用场景&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;zset主要用于各种排行榜。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;SpringBoot整合Redis&lt;/h2&gt;
&lt;h3&gt;Spring Data Redis概述&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Spring Data Redis&lt;/strong&gt; 是Spring大家族中的一个子项目，主要用于Spring程序和Redis的交互。它基于的Redis Java客户端（&lt;a href=&quot;https://github.com/redis/jedis&quot;&gt;Jedis&lt;/a&gt;和&lt;a href=&quot;https://lettuce.io/&quot;&gt;Lettuce&lt;/a&gt;）做了抽象，提供了一个统一的编程模型，使得Spring程序与Redis的交互变得十分简单。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Spring Data Redis&lt;/strong&gt; 中有一个十分重要的类——&lt;code&gt;RedisTemplate&lt;/code&gt;，它封装了与Redis进行的交互的各种方法，我们主要用使用它与Redis进行交互。&lt;/p&gt;
&lt;h3&gt;Spring Data Redis快速入门&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;创建SpringBoot项目&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;引入Maven依赖&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Spring Boot提供了对Spring Data Redis的支持，在Spring Boot项目中可以直接引入&lt;code&gt;spring-boot-starter-data-redis&lt;/code&gt;来完成Spring Data Redis的自动配置，具体依赖如下&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&amp;#x3C;dependency&gt;
    &amp;#x3C;groupId&gt;org.springframework.boot&amp;#x3C;/groupId&gt;
    &amp;#x3C;artifactId&gt;spring-boot-starter-data-redis&amp;#x3C;/artifactId&gt;
&amp;#x3C;/dependency&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;配置application.yml文件&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在&lt;code&gt;application.yml&lt;/code&gt;文件中增加如下参数，端口默认为&lt;code&gt;6379&lt;/code&gt;，若没有密码，&lt;code&gt;password&lt;/code&gt;字段可不写&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;spring:
  data:
    redis:
      host: xxx.xxx.xxx.xxx
      password: xxxxxx
      port: 6379
      database: 0
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;RedisTemplate使用&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;由于&lt;code&gt;spring-boot-starter-data-redis&lt;/code&gt;中提供了&lt;code&gt;RedisTemplate&lt;/code&gt;的自动配置，所以我们可以将&lt;code&gt;RedisTemplate&lt;/code&gt;注入自己的类中，如下边的案例所示&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@SpringBootTest
public class TestRedisTemplate {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void testRedisTemplate() {

    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;根据Redis的数据类型，RedisTemplate对各种交互方法做了分组，以下是常用的几个分组&lt;/p&gt;
&lt;p&gt;| 分组 | 说明 |
| :-- | :-- |
| &lt;code&gt;redisTemplate.opsForValue()&lt;/code&gt; | 操作string类型的方法 |
| &lt;code&gt;redisTemplate.opsForList()&lt;/code&gt; | 操作list类型的方法 |
| &lt;code&gt;redisTemplate.opsForSet()&lt;/code&gt; | 操作set类型的方法 |
| &lt;code&gt;redisTemplate.opsForHash()&lt;/code&gt; | 操作hash类型的方法 |
| &lt;code&gt;redisTemplate.opsForZSet()&lt;/code&gt; | 操作zset类型的方法 |
| &lt;code&gt;redisTemplate&lt;/code&gt; | 通用方法 |&lt;/p&gt;
&lt;p&gt;下面简单测试几个简单的方法&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@SpringBootTest
public class TestRedisTemplate {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void testSet() {
        redisTemplate.opsForValue().set(&quot;key1&quot;, &quot;value1&quot;);
    }

    @Test
    public void testGet() {
        String result = (String) redisTemplate.opsForValue().get(&quot;key1&quot;);
        System.out.println(result);
    }

    @Test
    public void testDel() {
        redisTemplate.delete(&quot;key1&quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;序列化问题&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;问题演示&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;问题一&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;使用RedisTemplate向Redis中增加一个键值对&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;redisTemplate.opsForValue().set(&quot;key2&quot;,&quot;value2&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用RedisTemplate查询key2所对应的value，有结果&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;redisTemplate.opsForValue().get(&quot;key2&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用命令行客户端查询key2所对应的value，无结果&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;get key2
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;问题二&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在图形化客户端或者命令行客户端观察key2，显示异常&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;问题说明&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;上述问题的根本原因是，Redis中的key和value均是以二进制的形式存储的，因此客户端输入的key和value都会经过序列化之后才发往Redis服务端。而RedisTemplate所使用序列化方式和命令行客户端采用序列化方式不相同，进而导致序列化之后的二进制数据不同，所以才会导致上述的现象。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;StringRedisTemplate使用&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;为解决上述问题，可使用&lt;code&gt;StringRedisTemplate&lt;/code&gt;代替&lt;code&gt;RedisTemplate&lt;/code&gt;，因为&lt;code&gt;StringRedisTemplate&lt;/code&gt;使用的序列化器和命令行所使用的序列化器是相同的。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;spring-boot-starter-data-redis&lt;/code&gt;同样提供了&lt;code&gt;StringRedisTemplate&lt;/code&gt;的自动配置，因此我们也可以直接将其注入到自己的类中。实例代码如下&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@SpringBootTest
public class TestStringRedisTemplate {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Test
    public void testSet() {
        redisTemplate.opsForValue().set(&quot;key4&quot;, &quot;value4&quot;);
    }

    @Test
    public void testGet() {
        String result = redisTemplate.opsForValue().get(&quot;key4&quot;);
        System.out.println(result);
    }

    @Test
    public void testDel() {
        redisTemplate.delete(&quot;key4&quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;</content:encoded><h:img src="/_astro/redis.K7fWUj5Y.jpg"/><enclosure url="/_astro/redis.K7fWUj5Y.jpg"/></item><item><title>Hexo博客-Fluid主题-Waline评论系统-Vercel免费部署</title><link>https://ouonnki.site/blog/blog-related/hexo/hexo-fluid-waline-deploy</link><guid isPermaLink="true">https://ouonnki.site/blog/blog-related/hexo/hexo-fluid-waline-deploy</guid><description>限于口袋紧张，租的vps存储空间都非常有限。再加上如果后面需要迁移博客系统到别的服务器的话，处理图片资源也是一件非常头疼的事情。本文将介绍一种利用PicGo+Github来构建舒适图床体验的方法。</description><pubDate>Sat, 24 Aug 2024 00:22:00 GMT</pubDate><content:encoded>&lt;p&gt;这次的部署过程的环境是在Hexo的Fluid主题上进行的，其他主题大同小异。&lt;/p&gt;
&lt;h2&gt;LeanCloud设置（数据库）&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://console.leancloud.app/login&quot;&gt;登录&lt;/a&gt; 或 &lt;a href=&quot;https://console.leancloud.app/register&quot;&gt;注册&lt;/a&gt; &lt;code&gt;LeanCloud 国际版&lt;/code&gt; 并进入 &lt;a href=&quot;https://console.leancloud.app/apps&quot;&gt;控制台&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;点击左上角 &lt;a href=&quot;https://console.leancloud.app/apps&quot;&gt;创建应用&lt;/a&gt; 并起一个你喜欢的名字 (请选择免费的开发版):&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20251203190448228.png&quot; alt=&quot;创建应用&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;进入应用，选择左下角的 &lt;code&gt;设置&lt;/code&gt; &gt; &lt;code&gt;应用 Key&lt;/code&gt;。你可以看到你的 &lt;code&gt;APP ID&lt;/code&gt;,&lt;code&gt;APP Key&lt;/code&gt; 和 &lt;code&gt;Master Key&lt;/code&gt;。请记录它们，以便后续使用。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20251203190517961.png&quot; alt=&quot;ID 和 Key&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;PS: LeanCloud国内版需要完成备案接入，建议使用国际版！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果你正在使用 Leancloud 国内版 (&lt;a href=&quot;https://leancloud.cn/&quot;&gt;leancloud.cn&lt;/a&gt;)，我们推荐你切换到国际版 (&lt;a href=&quot;https://leancloud.app/&quot;&gt;leancloud.app&lt;/a&gt;)。否则，你需要为应用额外绑定&lt;strong&gt;已备案&lt;/strong&gt;的域名，同时购买独立 IP 并完成备案接入:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;登录国内版并进入需要使用的应用&lt;/li&gt;
&lt;li&gt;选择 &lt;code&gt;设置&lt;/code&gt; &gt; &lt;code&gt;域名绑定&lt;/code&gt; &gt; &lt;code&gt;API 访问域名&lt;/code&gt; &gt; &lt;code&gt;绑定新域名&lt;/code&gt; &gt; 输入域名 &gt; &lt;code&gt;确定&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;按照页面上的提示按要求在 DNS 上完成 CNAME 解析。&lt;/li&gt;
&lt;li&gt;购买独立 IP 并提交工单完成备案接入。(独立 IP 目前价格为 ￥ 50/个/月)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20251203190552220.png&quot; alt=&quot;域名设置&quot;&gt;&lt;/p&gt;
&lt;h2&gt;Vercel部署（服务端）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fwalinejs%2Fwaline%2Ftree%2Fmain%2Fexample&quot;&gt;&lt;img src=&quot;https://vercel.com/button&quot; alt=&quot;Vercel&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;点击上方按钮，跳转至 Vercel 进行 Server 端部署。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;如果你未登录的话，Vercel 会让你注册或登录，请使用 GitHub 账户进行快捷登录。&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;输入一个你喜欢的 Vercel 项目名称并点击 &lt;code&gt;Create&lt;/code&gt; 继续:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20251203190722080.png&quot; alt=&quot;创建项目&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;此时 Vercel 会基于 Waline 模板帮助你新建并初始化仓库，仓库名为你之前输入的项目名。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20251203190744112.png&quot; alt=&quot;deploy&quot;&gt;&lt;/p&gt;
&lt;p&gt;一两分钟后，满屏的烟花会庆祝你部署成功。此时点击 &lt;code&gt;Go to Dashboard&lt;/code&gt; 可以跳转到应用的控制台。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20251203190802633.png&quot; alt=&quot;deploy&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;点击顶部的 &lt;code&gt;Settings&lt;/code&gt; - &lt;code&gt;Environment Variables&lt;/code&gt; 进入环境变量配置页，并配置三个环境变量 &lt;code&gt;LEAN_ID&lt;/code&gt;, &lt;code&gt;LEAN_KEY&lt;/code&gt; 和 &lt;code&gt;LEAN_MASTER_KEY&lt;/code&gt; 。它们的值分别对应上一步在 LeanCloud 中获得的 &lt;code&gt;APP ID&lt;/code&gt;, &lt;code&gt;APP KEY&lt;/code&gt;, &lt;code&gt;Master Key&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20251203190813919.png&quot; alt=&quot;设置环境变量&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;如果你使用 LeanCloud 国内版，请额外配置 &lt;code&gt;LEAN_SERVER&lt;/code&gt; 环境变量，值为你绑定好的域名。&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;环境变量配置完成之后点击顶部的 &lt;code&gt;Deployments&lt;/code&gt; 点击顶部最新的一次部署右侧的 &lt;code&gt;Redeploy&lt;/code&gt; 按钮进行重新部署。该步骤是为了让刚才设置的环境变量生效。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20251203190825709.png&quot; alt=&quot;redeploy&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;此时会跳转到 &lt;code&gt;Overview&lt;/code&gt; 界面开始部署，等待片刻后 &lt;code&gt;STATUS&lt;/code&gt; 会变成 &lt;code&gt;Ready&lt;/code&gt;。此时请点击 &lt;code&gt;Visit&lt;/code&gt; ，即可跳转到部署好的网站地址，此地址即为你的服务端地址。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.ouonnki.site/gh/Ouonnki/blog-pictures/posts/20251203190836905.png&quot; alt=&quot;redeploy success&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;绑定域名（可选）&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;如果你的博客是使用了自己的域名，这一项必须进行绑定配置，否则评论时会出现跨域问题&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;点击顶部的 &lt;code&gt;Settings&lt;/code&gt; - &lt;code&gt;Domains&lt;/code&gt; 进入域名配置页&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;输入需要绑定的域名并点击 &lt;code&gt;Add&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在域名服务器商处添加新的 &lt;code&gt;CNAME&lt;/code&gt; 解析记录&lt;/p&gt;
&lt;p&gt;| Type | Name | Value |
| --- | --- | --- |
| CNAME | example | cname.vercel-dns.com |&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;等待生效，你可以通过自己的域名来访问了🎉&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;评论系统：example.yourdomain.com&lt;/li&gt;
&lt;li&gt;评论管理：example.yourdomain.com/ui&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;配置Fluid&lt;/h2&gt;
&lt;p&gt;在&lt;code&gt;_config.fluid.yml&lt;/code&gt;中配置评论为&lt;code&gt;Waline&lt;/code&gt;，参数参考如下&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;  # 评论插件
  # Comment plugin
  comments:
    enable: true
    # 指定的插件，需要同时设置对应插件的必要参数
    # The specified plugin needs to set the necessary parameters at the same time
    # Options: utterances | disqus | gitalk | valine | waline | changyan | livere | remark42 | twikoo | cusdis | giscus | discuss
    type: waline
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Waline&lt;/code&gt;的具体配置信息如下，其中&lt;code&gt;serverURL&lt;/code&gt;的值为上一步中配置的子域名&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;# Waline
# 从 Valine 衍生而来，额外增加了服务端和多种功能
# Derived from Valine, with self-hosted service and new features
# See: https://waline.js.org/
waline:
  serverURL: &apos;https://example.archiewang.site/&apos;
  path: window.location.pathname
  meta: [&apos;nick&apos;, &apos;mail&apos;, &apos;link&apos;]
  requiredMeta: [&apos;nick&apos;]
  lang: &apos;zh-CN&apos;
  emoji: [&apos;https://cdn.jsdelivr.net/gh/walinejs/emojis/weibo&apos;]
  dark: &apos;html[data-user-color-scheme=&quot;dark&quot;]&apos;
  wordLimit: 0
  pageSize: 10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;至此结束部署，重新部署Hexo即可生效&lt;/p&gt;</content:encoded><h:img src="/_astro/Hexo.BdVn_44I.png"/><enclosure url="/_astro/Hexo.BdVn_44I.png"/></item><item><title>MybatisPlus分页插件使用</title><link>https://ouonnki.site/blog/backend/mybatisplus-page-use</link><guid isPermaLink="true">https://ouonnki.site/blog/backend/mybatisplus-page-use</guid><description>MybatisPlus分页插件的快速使用</description><pubDate>Fri, 23 Aug 2024 11:46:00 GMT</pubDate><content:encoded>&lt;h4&gt;配置分页&lt;/h4&gt;
&lt;p&gt;创建配置类&lt;code&gt;MPConfiguration&lt;/code&gt;，类名随意，第6行中需要传入数据库类型&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@Configuration
public class MPConfiguration {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;分页插件使用&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;构造分页对象&lt;/p&gt;
&lt;p&gt;分页对象包含了分页的各项信息，其核心属性如下：&lt;/p&gt;
&lt;p&gt;| 属性名 | 类型 | 默认值 | 描述 |
| --- | --- | --- | --- |
| records | List | emptyList | 查询数据列表 |
| total | Long | 0 | 查询列表总记录数 |
| size | Long | 10 | 每页显示条数，默认&lt;code&gt;10&lt;/code&gt; |
| current | Long | 1 | 当前页 |&lt;/p&gt;
&lt;p&gt;分页对象既作为分页查询的参数，也作为分页查询的返回结果，当作为查询参数时，通常只需提供&lt;code&gt;current&lt;/code&gt;和&lt;code&gt;size&lt;/code&gt;属性，如下&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;IPage&amp;#x3C;T&gt; page = new Page&amp;#x3C;&gt;(current, size);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注：&lt;code&gt;IPage&lt;/code&gt;为分页接口，&lt;code&gt;Page&lt;/code&gt;为&lt;code&gt;IPage&lt;/code&gt;接口的一个实现类。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;分页查询&lt;/p&gt;
&lt;p&gt;Mybatis Plus的&lt;code&gt;BaseMapper&lt;/code&gt;和&lt;code&gt;ServiceImpl&lt;/code&gt;均提供了常用的分页查询的方法，例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;BaseMapper&lt;/code&gt;的分页查询：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;IPage&amp;#x3C;T&gt; selectPage(IPage&amp;#x3C;T&gt; page,Wrapper&amp;#x3C;T&gt; queryWrapper);
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ServiceImpl&lt;/code&gt;的分页查询：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;// 无条件分页查询
IPage&amp;#x3C;T&gt; page(IPage&amp;#x3C;T&gt; page);
// 条件分页查询
IPage&amp;#x3C;T&gt; page(IPage&amp;#x3C;T&gt; page, Wrapper&amp;#x3C;T&gt; queryWrapper);
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;自定义Mapper&lt;/p&gt;
&lt;p&gt;对于自定义SQL，也可以十分方便的完成分页查询，如下&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Mapper&lt;/code&gt;接口：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;IPage&amp;#x3C;UserVo&gt; selectPageVo(IPage&amp;#x3C;?&gt; page, Integer state);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Mapper.xml&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;&amp;#x3C;select id=&quot;selectPageVo&quot; resultType=&quot;xxx.xxx.xxx.UserVo&quot;&gt;
    SELECT id,name FROM user WHERE state=#{state}
&amp;#x3C;/select&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：&lt;code&gt;Mapper.xml&lt;/code&gt;中的SQL只需实现查询&lt;code&gt;list&lt;/code&gt;的逻辑即可，无需关注分页的逻辑。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;案例实操&lt;/p&gt;
&lt;p&gt;分页查询案例如下：&lt;/p&gt;
&lt;p&gt;创建&lt;code&gt;PageTest&lt;/code&gt;测试类，内容如下&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;@SpringBootTest
public class PageTest {

    @Autowired
    private UserService userService;

    @Autowired
    private UserMapper userMapper;

    //通用Service分页查询
    @Test
    public void testPageService() {
        Page&amp;#x3C;User&gt; page = new Page&amp;#x3C;&gt;(2, 3);
        Page&amp;#x3C;User&gt; userPage = userService.page(page);
        userPage.getRecords().forEach(System.out::println);
    }

    //通用Mapper分页查询
    @Test
    public void testPageMapper() {
        IPage&amp;#x3C;User&gt; page = new Page&amp;#x3C;&gt;(2, 3);
        IPage&amp;#x3C;User&gt; userPage = userMapper.selectPage(page, null);
        userPage.getRecords().forEach(System.out::println);
    }

    //自定义SQL分页查询
    @Test
    public void testCustomMapper() {
        IPage&amp;#x3C;User&gt; page = new Page&amp;#x3C;&gt;(2, 3);
        IPage&amp;#x3C;User&gt; userPage = userMapper.selectUserPage(page);
        userPage.getRecords().forEach(System.out::println);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在UserMapper中声明分页查询方法如下&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;IPage&amp;#x3C;User&gt; selectUserPage(IPage&amp;#x3C;User&gt; page);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;创建&lt;code&gt;resources/mapper/UserMapper.xml&lt;/code&gt;文件，内容如下&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&amp;#x3C;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&amp;#x3C;!DOCTYPE mapper
        PUBLIC &quot;-//mybatis.org//DTD Mapper 3.0//EN&quot;
        &quot;http://mybatis.org/dtd/mybatis-3-mapper.dtd&quot;&gt;
&amp;#x3C;mapper namespace=&quot;com.atguigu.hellomp.mapper.UserMapper&quot;&gt;
    &amp;#x3C;select id=&quot;selectUserPage&quot; resultType=&quot;com.atguigu.hellomp.entity.User&quot;&gt;
        select *
        from user
    &amp;#x3C;/select&gt;
&amp;#x3C;/mapper&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;Mybatis-Plus中&lt;code&gt;Mapper.xml&lt;/code&gt;文件路径默认为：&lt;code&gt;classpath*:/mapper/**/*.xml&lt;/code&gt;，可在&lt;code&gt;application.yml&lt;/code&gt;中配置以下参数进行修改&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yml&quot;&gt;mybatis-plus:
  mapper-locations: classpath*:/mapper/**/*.xml
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;MybatisX插件&lt;/h4&gt;
&lt;p&gt;MyBatis Plus提供了一个IDEA插件——&lt;code&gt;MybatisX&lt;/code&gt;,使用它可根据数据库快速生成&lt;code&gt;Entity&lt;/code&gt;、&lt;code&gt;Mapper&lt;/code&gt;、&lt;code&gt;Mapper.xml&lt;/code&gt;、&lt;code&gt;Service&lt;/code&gt;、&lt;code&gt;ServiceImpl&lt;/code&gt;等代码，使用户更专注于业务。&lt;/p&gt;
&lt;p&gt;下面为具体用法&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;安装插件&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在IDEA插件市场搜索&lt;code&gt;MyBatisX&lt;/code&gt;，进行在线安装&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;配置数据库连接&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在IDEA中配置数据库连接&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;生成代码&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;配置实体类相关信息&lt;/p&gt;
&lt;p&gt;配置代码模版信息&lt;/p&gt;
&lt;p&gt;点击Finish然后查看生成的代码。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;其他注意事项&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;xml文件&lt;code&gt;&amp;#x3C;&lt;/code&gt;和&lt;code&gt;&gt;&lt;/code&gt;的转义&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;由于xml文件中的&lt;code&gt;&amp;#x3C;&lt;/code&gt;和&lt;code&gt;&gt;&lt;/code&gt;是特殊符号，需要转义处理。&lt;/p&gt;
&lt;p&gt;| 原符号 | 转义符号 |
| --- | --- |
| &lt;code&gt;&amp;#x3C;&lt;/code&gt; | &lt;code&gt;&amp;#x26;lt;&lt;/code&gt; |
| &lt;code&gt;&gt;&lt;/code&gt; | &lt;code&gt;&amp;#x26;gt;&lt;/code&gt; |&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Mybatis-Plus分页插件注意事项&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;使用Mybatis-Plus的分页插件进行分页查询时，如果结果需要使用&lt;code&gt;&amp;#x3C;collection&gt;&lt;/code&gt;进行映射，只能使用**&lt;a href=&quot;https://mybatis.org/mybatis-3/sqlmap-xml.html#nested-select-for-collection&quot;&gt;嵌套查询（Nested Select for Collection）&lt;/a&gt;&lt;strong&gt;，而不能使用&lt;/strong&gt;&lt;a href=&quot;https://mybatis.org/mybatis-3/sqlmap-xml.html#nested-results-for-collection&quot;&gt;嵌套结果映射（Nested Results for Collection）&lt;/a&gt;**。&lt;/p&gt;
&lt;p&gt;即对于&lt;code&gt;&amp;#x3C;collection&gt;&lt;/code&gt;的内容使用单独一个sql进行查询。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;嵌套查询&lt;/strong&gt;和&lt;strong&gt;嵌套结果映射&lt;/strong&gt;是Collection映射的两种方式，下面通过一个案例进行介绍&lt;/p&gt;
&lt;p&gt;例如有&lt;code&gt;room_info&lt;/code&gt;和&lt;code&gt;graph_info&lt;/code&gt;两张表，其关系为一对多&lt;/p&gt;
&lt;p&gt;现需要查询房间列表及其图片信息，期望返回的结果如下&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;[
    {
        &quot;id&quot;: 1,
        &quot;number&quot;: 201,
        &quot;rent&quot;: 2000,
        &quot;graphList&quot;: [
            {
                &quot;id&quot;: 1,
                &quot;url&quot;: &quot;http://&quot;,
                &quot;roomId&quot;: 1
            },
            {
                &quot;id&quot;: 2,
                &quot;url&quot;: &quot;http://&quot;,
                &quot;roomId&quot;: 1
            }
        ]
    },
    {
        &quot;id&quot;: 2,
        &quot;number&quot;: 202,
        &quot;rent&quot;: 3000,
        &quot;graphList&quot;: [
            {
                &quot;id&quot;: 3,
                &quot;url&quot;: &quot;http://&quot;,
                &quot;roomId&quot;: 2
            },
            {
                &quot;id&quot;: 4,
                &quot;url&quot;: &quot;http://&quot;,
                &quot;roomId&quot;: 2
            }
        ]
    }
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;为得到上述结果，可使用以下两种方式&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;嵌套结果映射&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&amp;#x3C;select id=&quot;selectRoomPage&quot; resultMap=&quot;RoomPageMap&quot;&gt;
    select ri.id room_id,
           ri.number,
           ri.rent,
           gi.id graph_id,
           gi.url,
           gi.room_id
    from room_info ri
       left join graph_info gi on ri.id=gi.room_id
&amp;#x3C;/select&gt;

&amp;#x3C;resultMap id=&quot;RoomPageMap&quot; type=&quot;RoomInfoVo&quot; autoMapping=&quot;true&quot;&gt;
    &amp;#x3C;id column=&quot;room_id&quot; property=&quot;id&quot;/&gt;
    &amp;#x3C;collection property=&quot;graphInfoList&quot; ofType=&quot;GraphInfo&quot; autoMapping=&quot;true&quot;&gt;
        &amp;#x3C;id column=&quot;graph_id&quot; property=&quot;id&quot;/&gt;
    &amp;#x3C;/collection&gt;
&amp;#x3C;/resultMap&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;嵌套查询&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&amp;#x3C;select id=&quot;selectRoomPage&quot; resultMap=&quot;RoomPageMap&quot;&gt;
    select id,
           number,
           rent
    from room_info
&amp;#x3C;/select&gt;

&amp;#x3C;resultMap id=&quot;RoomPageMap&quot; type=&quot;RoomInfoVo&quot; autoMapping=&quot;true&quot;&gt;
    &amp;#x3C;id column=&quot;id&quot; property=&quot;id&quot;/&gt;
    &amp;#x3C;collection property=&quot;graphInfoList&quot; ofType=&quot;GraphInfo&quot; select=&quot;selectGraphByRoomId&quot; 				 	column=&quot;id&quot;/&gt;
&amp;#x3C;/resultMap&gt;

&amp;#x3C;select id=&quot;selectGraphByRoomId&quot; resultType=&quot;GraphInfo&quot;&gt;
    select id,
           url,
           room_id
    from graph_info
    where room_id = #{id}
&amp;#x3C;/select&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这种方法使用两个独立的查询语句来获取一对多关系的数据。首先，Mybatis会执行主查询来获取&lt;code&gt;room_info&lt;/code&gt;列表，然后对于每个&lt;code&gt;room_info&lt;/code&gt;，Mybatis都会执行一次子查询来获取其对应的&lt;code&gt;graph_info&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;若现在使用MybatisPlus的分页插件进行分页查询，假如查询的内容是第&lt;strong&gt;1&lt;/strong&gt;页，每页&lt;strong&gt;2&lt;/strong&gt;条记录，显然&lt;strong&gt;嵌套结果映射&lt;/strong&gt;的分页逻辑是存在问题的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;打印SQL语句&lt;/p&gt;
&lt;p&gt;需要在&lt;code&gt;application.yml&lt;/code&gt;文件中进行如下配置&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;#用于打印框架生成的sql语句，便于调试
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;</content:encoded><h:img src="/_astro/mybatis.1_KPO4gC.jpeg"/><enclosure url="/_astro/mybatis.1_KPO4gC.jpeg"/></item><item><title>Hexo备份及博文模板配置</title><link>https://ouonnki.site/blog/blog-related/hexo/hexo-backup-in-github</link><guid isPermaLink="true">https://ouonnki.site/blog/blog-related/hexo/hexo-backup-in-github</guid><description>为了防止误操作或意外情况导致的 Hexo 博客源文件丢失，或满足我们更换电脑进行写作的需求，所以需要进行备份。</description><pubDate>Thu, 22 Aug 2024 22:14:00 GMT</pubDate><content:encoded>&lt;p&gt;为了防止误操作或意外情况导致的 Hexo 博客源文件丢失，或满足我们更换电脑进行写作的需求，所以需要进行备份。&lt;/p&gt;
&lt;h2&gt;需要备份的文件和目录&lt;/h2&gt;
&lt;p&gt;而在进行备份时，并不需要将整个博客目录全部备份，只需备份几个用户自定义的文件和配置&lt;/p&gt;
&lt;p&gt;&lt;code&gt;scaffolds&lt;/code&gt; 文章的模板，需要备份&lt;/p&gt;
&lt;p&gt;&lt;code&gt;source&lt;/code&gt; 文章和页面等源文件，需要备份&lt;/p&gt;
&lt;p&gt;&lt;code&gt;themes&lt;/code&gt; 主题文件与配置，需要备份&lt;/p&gt;
&lt;p&gt;&lt;code&gt;_config.yml&lt;/code&gt; 用户配置信息，需要备份&lt;/p&gt;
&lt;p&gt;&lt;code&gt;package.json&lt;/code&gt; 模块列表，需要备份&lt;/p&gt;
&lt;h2&gt;不需要备份的文件和目录&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;node_modules&lt;/code&gt; 安装的模块，不用备份&lt;/p&gt;
&lt;p&gt;&lt;code&gt;public&lt;/code&gt; 生成的文件静态网页文件，不用备份&lt;/p&gt;
&lt;p&gt;&lt;code&gt;db.json &lt;/code&gt;网页数据文件，编译生成静态网页时会自动更新，不用备份&lt;/p&gt;
&lt;p&gt;&lt;code&gt;package-lock.json&lt;/code&gt; 依赖的模块安装记录，不用备份&lt;/p&gt;
&lt;p&gt;此外如果主题目录下.git 这个隐藏目录也可以删掉或者如下面所讲加.gitignore 文件中在备份时忽略掉&lt;/p&gt;
&lt;h2&gt;备份到 GitHub&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;在 GitHub 创建一个私密仓库 &lt;code&gt;hexo-source&lt;/code&gt;，仓库名字随意，建议设置为私密仓库。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在你的站点目录下增加一&lt;code&gt;.gitignore&lt;/code&gt; 文件设置需要忽略的文件和目录，在其中添加不需要备份的内容：&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-.gitignore&quot;&gt;Text

node_modules/

public/

.deploy_git/

_config.landscape.yml

package-lock.json

db.json

themes/*/.git/

.DS_Store
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;备份你的站点源文件到仓库 &lt;code&gt;hexo-source&lt;/code&gt;，其&lt;code&gt;your_token&lt;/code&gt;为你的GIthub访问Token&lt;code&gt;username&lt;/code&gt;为你的Github用户名&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git init

git add *

git commit -m &quot;$(date): Hexo backup&quot;

git remote add origin https://your_token@github.com/username/hexo-source.git

git push -u origin main
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;恢复你的 Hexo 站点&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;初始化一个 Hexo 站点。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;从 GitHub 下载备份的内容到该 Hexo 站点目录下：&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git clone https://your_token@github.com/username/hexo-source.git
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;使用备份的 &lt;code&gt;package.json&lt;/code&gt; 文件来恢复安装 Hexo 插件，使用 npm 进行安装：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npm install
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这将读取 &lt;code&gt;package.json&lt;/code&gt; 文件中的依赖项列表，并下载并安装所需的插件和模块。&lt;/p&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;生成静态网页并部署即可。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;脚本化&lt;/h2&gt;
&lt;p&gt;有了上面的基础，可以在站点目录下创建bash文件，用来简化操作&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;文件&lt;code&gt;hexp_backup.sh&lt;/code&gt;，用于备份Hexo源代码&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;echo &quot;-------------------------添加文件-------------------------&quot;

git add *

echo &quot;-----------------------提交本地备份------------------------&quot;

git commit -m &quot;$(date): Hexo backup&quot;

echo &quot;-----------------------提交到远程仓库----------------------&quot;

git push -u origin main

echo &quot;-----------------------备份源代码完成----------------------&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;文件&lt;code&gt;hexp_new_post.sh&lt;/code&gt;，用于按照模板创建新博文&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;blog_name=&quot;博客-$(date +&apos;%Y-%m-%d %H:%M:%S&apos;)&quot;

hexo new &quot;$blog_name&quot;

echo &quot;-----------------------$blog_name.md 创建成功----------------------&quot;

3. 文件`hexp_publish.sh`，用于编译部署站点
```shell
echo &quot;-----------------------清理本地缓存----------------------&quot;

hexo clean

echo &quot;------------------------开始部署------------------------&quot;

hexo d -g

echo &quot;------------------------部署结束------------------------&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;文件&lt;code&gt;hexp_publish_backup.sh&lt;/code&gt;，用于整合部署和备份，通常写完博文后执行这个文件&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;bash hexo_publish.sh

echo &quot;------------------------开始备份源码-------------------------&quot;

bash hexo_backup.sh

echo &quot;-----------------------全部部署流程完成----------------------&quot;

echo &quot;访问：http://archiewang.site&quot;
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/Hexo.BdVn_44I.png"/><enclosure url="/_astro/Hexo.BdVn_44I.png"/></item></channel></rss>