[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"site-settings":3,"footer-friends":48,"tag-posts-ming-ling-xing-gong-ju":63,"tag-projects-ming-ling-xing-gong-ju":116,"sidebar-tags":120,"sidebar-donations":261,"ad-sidebar_top":268,"ad-sidebar_mid":270,"ad-sidebar_bottom":272},{"alipayQr":4,"beianNumber":5,"commentsRequireApproval":6,"contactEmail":7,"copyrightNotice":5,"donationEnabled":6,"emailCodeExpireMinutes":8,"enableRegistration":6,"followBilibiliUrl":9,"followGithubUrl":10,"followQqGroup":11,"followQqQr":12,"followWechatQr":13,"footerHtml":5,"gaTrackingId":5,"heroEnabled":6,"heroSearchPlaceholder":5,"heroSubtitle":14,"heroTitle":15,"homeCategoryTabsCount":16,"homePageSize":17,"homeProjectsCount":18,"homeSpecialsCount":19,"homeToolsCount":18,"icpNumber":20,"inviteDefaultQuota":21,"inviteRequired":22,"logoUrl":23,"mailPasswordChangedBody":24,"mailPasswordChangedSubject":25,"mailRegisterCodeBody":26,"mailRegisterCodeSubject":27,"mailResetCodeBody":28,"mailResetCodeSubject":29,"mailWelcomeBody":30,"mailWelcomeSubject":31,"miniappAppid":32,"miniappEnabled":6,"profileAvatar":33,"profileBio":34,"profileName":35,"profileWechatQr":36,"promoteEnabled":6,"promoteNotice":5,"promoteWechat":5,"requireEmailVerify":6,"sectionArticleEnabled":6,"sectionArticleTitle":37,"sectionProjectsEnabled":6,"sectionProjectsTitle":38,"sectionSpecialEnabled":6,"sectionSpecialTitle":39,"sectionToolsEnabled":6,"sectionToolsTitle":40,"seoAuthor":41,"seoBaiduTongjiId":5,"seoBaiduVerify":5,"seoCanonicalEnabled":6,"seoDescription":42,"seoGoogleVerify":5,"seoKeywords":5,"seoOgImage":23,"seoRobots":5,"seoSitemapEnabled":6,"seoTitle":43,"seoTitleTemplate":44,"showHeroStats":6,"showSidebarDonations":6,"showSidebarFeedback":6,"showSidebarFollowUs":6,"showSidebarProfile":6,"showSidebarTagCloud":6,"siteDescription":42,"siteFavicon":45,"siteName":41,"siteUrl":46,"wechatQr":47},"\u002Fstatic\u002Fuploads\u002Fimages\u002F2026\u002F09\u002F29\u002F1790628031878385634.png","","true","enghin110@qq.com","10","https:\u002F\u002Fspace.bilibili.com\u002F470616503","https:\u002F\u002Fgithub.com\u002Fitwuge","606262780","\u002Fstatic\u002Fuploads\u002Fimages\u002F2026\u002F09\u002F29\u002F1790627647190853446.png","\u002Fstatic\u002Fuploads\u002Fimages\u002F2026\u002F09\u002F29\u002F1790627638856258082.jpg","精选 AI 教程、开源项目与实用工具，助你从入门到精通","探索人工智能的无限可能","6","7","4","3","赣ICP备2023014108号-2","5","false","\u002Fimages\u002Flogo\u002Flogo.png","\u003C!DOCTYPE html>\n\u003Chtml lang=\"zh-CN\">\n\u003Chead>\u003Cmeta charset=\"UTF-8\">\u003Cmeta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\">\u003C\u002Fhead>\n\u003Cbody style=\"margin:0;padding:24px 0;background:#f1f5f9;font-family:'Microsoft YaHei','PingFang SC',Helvetica,Arial,sans-serif;\">\n  \u003Ctable role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background:#f1f5f9;\">\n    \u003Ctr>\n      \u003Ctd align=\"center\" style=\"padding:0 16px;\">\n        \u003Ctable role=\"presentation\" width=\"600\" cellpadding=\"0\" cellspacing=\"0\" style=\"max-width:600px;width:100%;\">\n          \u003C!-- 品牌头部 -->\n          \u003Ctr>\n            \u003Ctd style=\"background:#3b82f6;border-radius:12px 12px 0 0;padding:20px 28px;\">\n              \u003Cspan style=\"font-size:18px;font-weight:bold;color:#ffffff;\">\u003Ca href=\"{site_url}\" style=\"color:#ffffff;text-decoration:none;\">{site_name}\u003C\u002Fa>\u003C\u002Fspan>\n              \u003Cspan style=\"float:right;font-size:12px;color:#dbeafe;line-height:26px;\">{site_description}\u003C\u002Fspan>\n            \u003C\u002Ftd>\n          \u003C\u002Ftr>\n          \u003C!-- 正文卡片 -->\n          \u003Ctr>\n            \u003Ctd style=\"background:#ffffff;padding:32px 28px;border-radius:0 0 12px 12px;box-shadow:0 2px 8px rgba(15,23,42,0.06);\">\n              \n  \u003Ch2 style=\"margin:0 0 16px;font-size:20px;color:#1e293b;\">🔒 账户密码修改成功\u003C\u002Fh2>\n  \u003Cp style=\"margin:0 0 16px;font-size:14px;line-height:1.8;color:#475569;\">\n    你好，\u003Cstrong style=\"color:#1e293b;\">{username}\u003C\u002Fstrong>，你的账户密码已于刚刚修改成功。\n  \u003C\u002Fp>\n  \u003Ctable role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background:#f8fafc;border-radius:10px;margin:8px 0 4px;\">\n    \u003Ctr>\u003Ctd style=\"padding:14px 18px;font-size:13px;line-height:2;color:#475569;\">\n      账户用户名：\u003Cstrong style=\"color:#1e293b;\">{username}\u003C\u002Fstrong>\u003Cbr>\n      账户邮箱：\u003Cstrong style=\"color:#1e293b;\">{email}\u003C\u002Fstrong>\u003Cbr>\n      修改时间：\u003Cstrong style=\"color:#1e293b;\">{change_time}\u003C\u002Fstrong>\n    \u003C\u002Ftd>\u003C\u002Ftr>\n  \u003C\u002Ftable>\n  \u003Cp style=\"margin:16px 0 0;font-size:13px;line-height:1.8;color:#64748b;\">\n    如果这是你本人的操作，请忽略本邮件；\u003Cstrong style=\"color:#dc2626;\">如果不是你本人操作，说明账户密码可能已泄露\u003C\u002Fstrong>，\n    请立即使用「忘记密码」功能重置密码，并通过页脚联系邮箱告知站长。\n  \u003C\u002Fp>\n  \n  \u003Cp style=\"text-align:center;margin:28px 0 8px;\">\n    \u003Ca href=\"{site_url}\" style=\"display:inline-block;padding:12px 36px;background:#3b82f6;color:#ffffff;font-size:15px;font-weight:bold;text-decoration:none;border-radius:8px;\">进入{site_name}\u003C\u002Fa>\n  \u003C\u002Fp>\n            \u003C\u002Ftd>\n          \u003C\u002Ftr>\n          \u003C!-- 页脚 -->\n          \u003Ctr>\n            \u003Ctd align=\"center\" style=\"padding:20px 16px 0;\">\n              \n              \u003Cp style=\"margin:6px 0 0;font-size:12px;color:#94a3b8;\">联系邮箱：\u003Ca href=\"mailto:{contact_email}\" style=\"color:#64748b;text-decoration:none;\">{contact_email}\u003C\u002Fa>\u003C\u002Fp>\n              \u003Cp style=\"margin:6px 0 0;font-size:12px;color:#94a3b8;\">此邮件由系统自动发送，请勿直接回复 · © {year} {site_name}\u003C\u002Fp>\n            \u003C\u002Ftd>\n          \u003C\u002Ftr>\n        \u003C\u002Ftable>\n      \u003C\u002Ftd>\n    \u003C\u002Ftr>\n  \u003C\u002Ftable>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>","【{site_name}】你的账户密码已修改","\u003C!DOCTYPE html>\n\u003Chtml lang=\"zh-CN\">\n\u003Chead>\u003Cmeta charset=\"UTF-8\">\u003Cmeta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\">\u003C\u002Fhead>\n\u003Cbody style=\"margin:0;padding:24px 0;background:#f1f5f9;font-family:'Microsoft YaHei','PingFang SC',Helvetica,Arial,sans-serif;\">\n  \u003Ctable role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background:#f1f5f9;\">\n    \u003Ctr>\n      \u003Ctd align=\"center\" style=\"padding:0 16px;\">\n        \u003Ctable role=\"presentation\" width=\"600\" cellpadding=\"0\" cellspacing=\"0\" style=\"max-width:600px;width:100%;\">\n          \u003C!-- 品牌头部 -->\n          \u003Ctr>\n            \u003Ctd style=\"background:#3b82f6;border-radius:12px 12px 0 0;padding:20px 28px;\">\n              \u003Cspan style=\"font-size:18px;font-weight:bold;color:#ffffff;\">\u003Ca href=\"{site_url}\" style=\"color:#ffffff;text-decoration:none;\">{site_name}\u003C\u002Fa>\u003C\u002Fspan>\n              \u003Cspan style=\"float:right;font-size:12px;color:#dbeafe;line-height:26px;\">{site_description}\u003C\u002Fspan>\n            \u003C\u002Ftd>\n          \u003C\u002Ftr>\n          \u003C!-- 正文卡片 -->\n          \u003Ctr>\n            \u003Ctd style=\"background:#ffffff;padding:32px 28px;border-radius:0 0 12px 12px;box-shadow:0 2px 8px rgba(15,23,42,0.06);\">\n              \n  \u003Ch2 style=\"margin:0 0 16px;font-size:20px;color:#1e293b;\">注册邮箱验证码\u003C\u002Fh2>\n  \u003Cp style=\"margin:0 0 16px;font-size:14px;line-height:1.8;color:#475569;\">欢迎注册 \u003Cstrong>{site_name}\u003C\u002Fstrong>！感谢你的加入，请使用下方验证码完成邮箱验证：\u003C\u002Fp>\n  \u003Ctable role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"margin:8px 0 4px;\">\n    \u003Ctr>\n      \u003Ctd align=\"center\" style=\"background:#f8fafc;border:1px dashed #cbd5e1;border-radius:10px;padding:22px 0;\">\n        \u003Cspan style=\"font-size:32px;font-weight:bold;letter-spacing:10px;color:#3b82f6;font-family:Consolas,Menlo,monospace;\">{code}\u003C\u002Fspan>\n      \u003C\u002Ftd>\n    \u003C\u002Ftr>\n  \u003C\u002Ftable>\n  \u003Cp style=\"margin:12px 0 0;font-size:13px;color:#64748b;\">\n    验证码 \u003Cstrong style=\"color:#dc2626;\">{expire} 分钟\u003C\u002Fstrong> 内有效，为保障账户安全，请勿向他人泄露。\n  \u003C\u002Fp>\n  \u003Chr style=\"border:none;border-top:1px solid #e2e8f0;margin:24px 0;\">\n  \n  \u003Cp style=\"margin:0 0 12px;font-size:14px;line-height:1.8;color:#475569;\">\n    这里是 \u003Cstrong style=\"color:#1e293b;\">{site_name}\u003C\u002Fstrong>，{site_description}\n  \u003C\u002Fp>\n  \u003Ctable role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"margin:8px 0 4px;\">\n    \u003Ctr>\n      \u003Ctd width=\"33%\" valign=\"top\" style=\"padding:6px;\">\n        \u003Cdiv style=\"background:#eff6ff;border-radius:8px;padding:14px 10px;text-align:center;\">\n          \u003Cdiv style=\"font-size:15px;\">📚\u003C\u002Fdiv>\n          \u003Cdiv style=\"font-size:13px;font-weight:bold;color:#1e40af;margin-top:4px;\">精选教程\u003C\u002Fdiv>\n          \u003Cdiv style=\"font-size:12px;color:#64748b;margin-top:2px;\">从入门到实战\u003C\u002Fdiv>\n        \u003C\u002Fdiv>\n      \u003C\u002Ftd>\n      \u003Ctd width=\"33%\" valign=\"top\" style=\"padding:6px;\">\n        \u003Cdiv style=\"background:#ecfdf5;border-radius:8px;padding:14px 10px;text-align:center;\">\n          \u003Cdiv style=\"font-size:15px;\">🚀\u003C\u002Fdiv>\n          \u003Cdiv style=\"font-size:13px;font-weight:bold;color:#065f46;margin-top:4px;\">开源项目\u003C\u002Fdiv>\n          \u003Cdiv style=\"font-size:12px;color:#64748b;margin-top:2px;\">精选可部署方案\u003C\u002Fdiv>\n        \u003C\u002Fdiv>\n      \u003C\u002Ftd>\n      \u003Ctd width=\"34%\" valign=\"top\" style=\"padding:6px;\">\n        \u003Cdiv style=\"background:#fff7ed;border-radius:8px;padding:14px 10px;text-align:center;\">\n          \u003Cdiv style=\"font-size:15px;\">🧰\u003C\u002Fdiv>\n          \u003Cdiv style=\"font-size:13px;font-weight:bold;color:#9a3412;margin-top:4px;\">在线工具\u003C\u002Fdiv>\n          \u003Cdiv style=\"font-size:12px;color:#64748b;margin-top:2px;\">即开即用提效\u003C\u002Fdiv>\n        \u003C\u002Fdiv>\n      \u003C\u002Ftd>\n    \u003C\u002Ftr>\n  \u003C\u002Ftable>\n  \u003Cp style=\"margin:20px 0 0;font-size:12px;line-height:1.8;color:#94a3b8;\">\n    如果这不是你本人的操作，请忽略本邮件，你的账户安全不会受到影响。\n  \u003C\u002Fp>\n            \u003C\u002Ftd>\n          \u003C\u002Ftr>\n          \u003C!-- 页脚 -->\n          \u003Ctr>\n            \u003Ctd align=\"center\" style=\"padding:20px 16px 0;\">\n              \n              \u003Cp style=\"margin:6px 0 0;font-size:12px;color:#94a3b8;\">联系邮箱：\u003Ca href=\"mailto:{contact_email}\" style=\"color:#64748b;text-decoration:none;\">{contact_email}\u003C\u002Fa>\u003C\u002Fp>\n              \u003Cp style=\"margin:6px 0 0;font-size:12px;color:#94a3b8;\">此邮件由系统自动发送，请勿直接回复 · © {year} {site_name}\u003C\u002Fp>\n            \u003C\u002Ftd>\n          \u003C\u002Ftr>\n        \u003C\u002Ftable>\n      \u003C\u002Ftd>\n    \u003C\u002Ftr>\n  \u003C\u002Ftable>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>","【{site_name}】注册验证码","\u003C!DOCTYPE html>\n\u003Chtml lang=\"zh-CN\">\n\u003Chead>\u003Cmeta charset=\"UTF-8\">\u003Cmeta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\">\u003C\u002Fhead>\n\u003Cbody style=\"margin:0;padding:24px 0;background:#f1f5f9;font-family:'Microsoft YaHei','PingFang SC',Helvetica,Arial,sans-serif;\">\n  \u003Ctable role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background:#f1f5f9;\">\n    \u003Ctr>\n      \u003Ctd align=\"center\" style=\"padding:0 16px;\">\n        \u003Ctable role=\"presentation\" width=\"600\" cellpadding=\"0\" cellspacing=\"0\" style=\"max-width:600px;width:100%;\">\n          \u003C!-- 品牌头部 -->\n          \u003Ctr>\n            \u003Ctd style=\"background:#3b82f6;border-radius:12px 12px 0 0;padding:20px 28px;\">\n              \u003Cspan style=\"font-size:18px;font-weight:bold;color:#ffffff;\">\u003Ca href=\"{site_url}\" style=\"color:#ffffff;text-decoration:none;\">{site_name}\u003C\u002Fa>\u003C\u002Fspan>\n              \u003Cspan style=\"float:right;font-size:12px;color:#dbeafe;line-height:26px;\">{site_description}\u003C\u002Fspan>\n            \u003C\u002Ftd>\n          \u003C\u002Ftr>\n          \u003C!-- 正文卡片 -->\n          \u003Ctr>\n            \u003Ctd style=\"background:#ffffff;padding:32px 28px;border-radius:0 0 12px 12px;box-shadow:0 2px 8px rgba(15,23,42,0.06);\">\n              \n  \u003Ch2 style=\"margin:0 0 16px;font-size:20px;color:#1e293b;\">找回密码验证码\u003C\u002Fh2>\n  \u003Cp style=\"margin:0 0 16px;font-size:14px;line-height:1.8;color:#475569;\">你正在找回账户密码，请使用下方验证码完成重置操作：\u003C\u002Fp>\n  \u003Ctable role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"margin:8px 0 4px;\">\n    \u003Ctr>\n      \u003Ctd align=\"center\" style=\"background:#f8fafc;border:1px dashed #cbd5e1;border-radius:10px;padding:22px 0;\">\n        \u003Cspan style=\"font-size:32px;font-weight:bold;letter-spacing:10px;color:#3b82f6;font-family:Consolas,Menlo,monospace;\">{code}\u003C\u002Fspan>\n      \u003C\u002Ftd>\n    \u003C\u002Ftr>\n  \u003C\u002Ftable>\n  \u003Cp style=\"margin:12px 0 0;font-size:13px;color:#64748b;\">\n    验证码 \u003Cstrong style=\"color:#dc2626;\">{expire} 分钟\u003C\u002Fstrong> 内有效，为保障账户安全，请勿向他人泄露。\n  \u003C\u002Fp>\n  \u003Chr style=\"border:none;border-top:1px solid #e2e8f0;margin:24px 0;\">\n  \n  \u003Cp style=\"margin:0 0 12px;font-size:14px;line-height:1.8;color:#475569;\">\n    这里是 \u003Cstrong style=\"color:#1e293b;\">{site_name}\u003C\u002Fstrong>，{site_description}\n  \u003C\u002Fp>\n  \u003Ctable role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"margin:8px 0 4px;\">\n    \u003Ctr>\n      \u003Ctd width=\"33%\" valign=\"top\" style=\"padding:6px;\">\n        \u003Cdiv style=\"background:#eff6ff;border-radius:8px;padding:14px 10px;text-align:center;\">\n          \u003Cdiv style=\"font-size:15px;\">📚\u003C\u002Fdiv>\n          \u003Cdiv style=\"font-size:13px;font-weight:bold;color:#1e40af;margin-top:4px;\">精选教程\u003C\u002Fdiv>\n          \u003Cdiv style=\"font-size:12px;color:#64748b;margin-top:2px;\">从入门到实战\u003C\u002Fdiv>\n        \u003C\u002Fdiv>\n      \u003C\u002Ftd>\n      \u003Ctd width=\"33%\" valign=\"top\" style=\"padding:6px;\">\n        \u003Cdiv style=\"background:#ecfdf5;border-radius:8px;padding:14px 10px;text-align:center;\">\n          \u003Cdiv style=\"font-size:15px;\">🚀\u003C\u002Fdiv>\n          \u003Cdiv style=\"font-size:13px;font-weight:bold;color:#065f46;margin-top:4px;\">开源项目\u003C\u002Fdiv>\n          \u003Cdiv style=\"font-size:12px;color:#64748b;margin-top:2px;\">精选可部署方案\u003C\u002Fdiv>\n        \u003C\u002Fdiv>\n      \u003C\u002Ftd>\n      \u003Ctd width=\"34%\" valign=\"top\" style=\"padding:6px;\">\n        \u003Cdiv style=\"background:#fff7ed;border-radius:8px;padding:14px 10px;text-align:center;\">\n          \u003Cdiv style=\"font-size:15px;\">🧰\u003C\u002Fdiv>\n          \u003Cdiv style=\"font-size:13px;font-weight:bold;color:#9a3412;margin-top:4px;\">在线工具\u003C\u002Fdiv>\n          \u003Cdiv style=\"font-size:12px;color:#64748b;margin-top:2px;\">即开即用提效\u003C\u002Fdiv>\n        \u003C\u002Fdiv>\n      \u003C\u002Ftd>\n    \u003C\u002Ftr>\n  \u003C\u002Ftable>\n  \u003Cp style=\"margin:20px 0 0;font-size:12px;line-height:1.8;color:#94a3b8;\">\n    如果这不是你本人的操作，请忽略本邮件，你的账户安全不会受到影响。\n  \u003C\u002Fp>\n            \u003C\u002Ftd>\n          \u003C\u002Ftr>\n          \u003C!-- 页脚 -->\n          \u003Ctr>\n            \u003Ctd align=\"center\" style=\"padding:20px 16px 0;\">\n              \n              \u003Cp style=\"margin:6px 0 0;font-size:12px;color:#94a3b8;\">联系邮箱：\u003Ca href=\"mailto:{contact_email}\" style=\"color:#64748b;text-decoration:none;\">{contact_email}\u003C\u002Fa>\u003C\u002Fp>\n              \u003Cp style=\"margin:6px 0 0;font-size:12px;color:#94a3b8;\">此邮件由系统自动发送，请勿直接回复 · © {year} {site_name}\u003C\u002Fp>\n            \u003C\u002Ftd>\n          \u003C\u002Ftr>\n        \u003C\u002Ftable>\n      \u003C\u002Ftd>\n    \u003C\u002Ftr>\n  \u003C\u002Ftable>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>","【{site_name}】找回密码验证码","\u003C!DOCTYPE html>\n\u003Chtml lang=\"zh-CN\">\n\u003Chead>\u003Cmeta charset=\"UTF-8\">\u003Cmeta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\">\u003C\u002Fhead>\n\u003Cbody style=\"margin:0;padding:24px 0;background:#f1f5f9;font-family:'Microsoft YaHei','PingFang SC',Helvetica,Arial,sans-serif;\">\n  \u003Ctable role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background:#f1f5f9;\">\n    \u003Ctr>\n      \u003Ctd align=\"center\" style=\"padding:0 16px;\">\n        \u003Ctable role=\"presentation\" width=\"600\" cellpadding=\"0\" cellspacing=\"0\" style=\"max-width:600px;width:100%;\">\n          \u003C!-- 品牌头部 -->\n          \u003Ctr>\n            \u003Ctd style=\"background:#3b82f6;border-radius:12px 12px 0 0;padding:20px 28px;\">\n              \u003Cspan style=\"font-size:18px;font-weight:bold;color:#ffffff;\">\u003Ca href=\"{site_url}\" style=\"color:#ffffff;text-decoration:none;\">{site_name}\u003C\u002Fa>\u003C\u002Fspan>\n              \u003Cspan style=\"float:right;font-size:12px;color:#dbeafe;line-height:26px;\">{site_description}\u003C\u002Fspan>\n            \u003C\u002Ftd>\n          \u003C\u002Ftr>\n          \u003C!-- 正文卡片 -->\n          \u003Ctr>\n            \u003Ctd style=\"background:#ffffff;padding:32px 28px;border-radius:0 0 12px 12px;box-shadow:0 2px 8px rgba(15,23,42,0.06);\">\n              \n  \u003Ch2 style=\"margin:0 0 4px;font-size:20px;color:#1e293b;\">🎉 欢迎加入 {site_name}！\u003Cspan style=\"display:inline-block;margin-left:8px;padding:2px 8px;background:#dcfce7;color:#15803d;font-size:12px;border-radius:10px;vertical-align:middle;\">邮箱已验证\u003C\u002Fspan>\u003C\u002Fh2>\n  \u003Cp style=\"margin:0 0 16px;font-size:14px;line-height:1.8;color:#475569;\">\n    你好，\u003Cstrong style=\"color:#1e293b;\">{username}\u003C\u002Fstrong>，你的账户已注册成功。\n  \u003C\u002Fp>\n  \u003Ctable role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background:#f8fafc;border-radius:10px;margin:8px 0 4px;\">\n    \u003Ctr>\u003Ctd style=\"padding:14px 18px;font-size:13px;line-height:2;color:#475569;\">\n      账户用户名：\u003Cstrong style=\"color:#1e293b;\">{username}\u003C\u002Fstrong>\u003Cbr>\n      注册邮箱：\u003Cstrong style=\"color:#1e293b;\">{email}\u003C\u002Fstrong>\u003Cbr>\n      注册奖励：\u003Cstrong style=\"color:#dc2626;\">+{register_points} 积分\u003C\u002Fstrong>已发放\n    \u003C\u002Ftd>\u003C\u002Ftr>\n  \u003C\u002Ftable>\n  \u003Chr style=\"border:none;border-top:1px solid #e2e8f0;margin:24px 0;\">\n  \n  \u003Cp style=\"margin:0 0 12px;font-size:14px;line-height:1.8;color:#475569;\">\n    这里是 \u003Cstrong style=\"color:#1e293b;\">{site_name}\u003C\u002Fstrong>，{site_description}\n  \u003C\u002Fp>\n  \u003Ctable role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"margin:8px 0 4px;\">\n    \u003Ctr>\n      \u003Ctd width=\"33%\" valign=\"top\" style=\"padding:6px;\">\n        \u003Cdiv style=\"background:#eff6ff;border-radius:8px;padding:14px 10px;text-align:center;\">\n          \u003Cdiv style=\"font-size:15px;\">📚\u003C\u002Fdiv>\n          \u003Cdiv style=\"font-size:13px;font-weight:bold;color:#1e40af;margin-top:4px;\">精选教程\u003C\u002Fdiv>\n          \u003Cdiv style=\"font-size:12px;color:#64748b;margin-top:2px;\">从入门到实战\u003C\u002Fdiv>\n        \u003C\u002Fdiv>\n      \u003C\u002Ftd>\n      \u003Ctd width=\"33%\" valign=\"top\" style=\"padding:6px;\">\n        \u003Cdiv style=\"background:#ecfdf5;border-radius:8px;padding:14px 10px;text-align:center;\">\n          \u003Cdiv style=\"font-size:15px;\">🚀\u003C\u002Fdiv>\n          \u003Cdiv style=\"font-size:13px;font-weight:bold;color:#065f46;margin-top:4px;\">开源项目\u003C\u002Fdiv>\n          \u003Cdiv style=\"font-size:12px;color:#64748b;margin-top:2px;\">精选可部署方案\u003C\u002Fdiv>\n        \u003C\u002Fdiv>\n      \u003C\u002Ftd>\n      \u003Ctd width=\"34%\" valign=\"top\" style=\"padding:6px;\">\n        \u003Cdiv style=\"background:#fff7ed;border-radius:8px;padding:14px 10px;text-align:center;\">\n          \u003Cdiv style=\"font-size:15px;\">🧰\u003C\u002Fdiv>\n          \u003Cdiv style=\"font-size:13px;font-weight:bold;color:#9a3412;margin-top:4px;\">在线工具\u003C\u002Fdiv>\n          \u003Cdiv style=\"font-size:12px;color:#64748b;margin-top:2px;\">即开即用提效\u003C\u002Fdiv>\n        \u003C\u002Fdiv>\n      \u003C\u002Ftd>\n    \u003C\u002Ftr>\n  \u003C\u002Ftable>\n  \u003Cp style=\"margin:16px 0 0;font-size:14px;line-height:1.8;color:#475569;\">登录后你可以：\u003C\u002Fp>\n  \u003Cul style=\"margin:8px 0 0;padding-left:22px;font-size:14px;line-height:2;color:#475569;\">\n    \u003Cli>浏览、收藏优质内容与实用工具\u003C\u002Fli>\n    \u003Cli>投稿教程与项目，审核通过后获得积分奖励\u003C\u002Fli>\n    \u003Cli>参与评论、打分，与其他用户交流\u003C\u002Fli>\n    \u003Cli>通过签到、投稿、互动持续累积积分与等级\u003C\u002Fli>\n  \u003C\u002Ful>\n  \n  \u003Cp style=\"text-align:center;margin:28px 0 8px;\">\n    \u003Ca href=\"{site_url}\" style=\"display:inline-block;padding:12px 36px;background:#3b82f6;color:#ffffff;font-size:15px;font-weight:bold;text-decoration:none;border-radius:8px;\">进入{site_name}\u003C\u002Fa>\n  \u003C\u002Fp>\n            \u003C\u002Ftd>\n          \u003C\u002Ftr>\n          \u003C!-- 页脚 -->\n          \u003Ctr>\n            \u003Ctd align=\"center\" style=\"padding:20px 16px 0;\">\n              \n              \u003Cp style=\"margin:6px 0 0;font-size:12px;color:#94a3b8;\">联系邮箱：\u003Ca href=\"mailto:{contact_email}\" style=\"color:#64748b;text-decoration:none;\">{contact_email}\u003C\u002Fa>\u003C\u002Fp>\n              \u003Cp style=\"margin:6px 0 0;font-size:12px;color:#94a3b8;\">此邮件由系统自动发送，请勿直接回复 · © {year} {site_name}\u003C\u002Fp>\n            \u003C\u002Ftd>\n          \u003C\u002Ftr>\n        \u003C\u002Ftable>\n      \u003C\u002Ftd>\n    \u003C\u002Ftr>\n  \u003C\u002Ftable>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>","【{site_name}】欢迎加入{site_name}，账户注册成功","7111479@qq.com","\u002Fstatic\u002Fuploads\u002Fimages\u002F2026\u002F09\u002F29\u002F1790627623420492239.jpg","全栈开发者，专注 AI 应用与效率工具","武哥","\u002Fstatic\u002Fuploads\u002Fimages\u002F2026\u002F09\u002F29\u002F1790629453503799753.png","热门爆款","精选项目","精选专题","精选工具","AI导航工具站","精选优质 AI 教程、AI 工具与开源项目，助力开发者快速上手人工智能","AI导航工具站 - AI 教程 · AI 项目 · AI 工具","%s - AI导航工具站","\u002Fimages\u002Flogo\u002Ffavicon.ico","https:\u002F\u002Fwuge.fun","\u002Fstatic\u002Fuploads\u002Fimages\u002F2026\u002F09\u002F29\u002F1790628026196296604.png",[49,58],{"id":50,"name":51,"url":52,"logo":53,"description":51,"sortOrder":54,"status":55,"createdAt":56,"updatedAt":57},2,"哔哩哔哩","https:\u002F\u002Fwww.bilibili.com\u002F","\\images\\social\\bilibili.png",0,1,"0001-01-01T00:00:00Z","2026-09-29T04:44:41.867019475+08:00",{"id":55,"name":59,"url":60,"logo":61,"description":59,"sortOrder":54,"status":55,"createdAt":62,"updatedAt":62},"GitHub","https:\u002F\u002Fgithub.com","\\images\\social\\github.png","2026-09-29T04:32:39.65740234+08:00",{"items":64,"pagination":114},[65],{"id":66,"title":67,"slug":68,"summary":69,"content":70,"coverImage":71,"categoryId":72,"authorId":55,"viewCount":54,"likeCount":54,"commentCount":54,"isTop":54,"isRecommend":54,"status":55,"rejectReason":5,"publishedAt":73,"createdAt":74,"updatedAt":75,"category":76,"author":80,"tags":88},20,"用 Python 调用大模型 API：写一个命令行 AI 助手","ai-cli","毕业项目来了：用 100 行 Python 写一个命令行 AI 助手，支持流式输出、打字机效果、多轮对话记忆，最后打包成 exe 发给朋友用。","## 我们要做什么\n\n把前面几篇笔记学到的知识串起来，做一个真正能用的东西：\n\n```text\n$ python ai_chat.py\n🤖 AI 助手已启动（输入 \u002Fquit 退出，\u002Fclear 清空记忆）\n\n你 > 用一句话介绍 Python\nAI > Python 是一种简洁易读、生态丰富的通用编程语言。\n\n你 > 它适合做什么\nAI > （记得上文）Python 特别适合数据分析、AI 开发、自动化脚本……\n```\n\n功能清单：\n\n- 流式输出（打字机效果）\n- 多轮对话记忆\n- `\u002Fquit`、`\u002Fclear`、`\u002Fsave` 斜杠命令\n- 配置文件管理 API Key\n- 打包成 exe 双击即用\n\n## 第 1 步：基础对话循环\n\n```python\n# ai_chat.py\nimport os\nimport sys\n\nfrom openai import OpenAI\n\n# 从环境变量读 key，不要硬编码\nclient = OpenAI(\n    api_key=os.environ.get(\"DEEPSEEK_API_KEY\", \"sk-在这里填你的key\"),\n    base_url=\"https:\u002F\u002Fapi.deepseek.com\",\n)\nMODEL = \"deepseek-chat\"\n\n# 对话历史：system 人设 + 历轮问答\nhistory = [\n    {\"role\": \"system\", \"content\": \"你是简洁专业的 AI 助手，回答控制在 300 字以内\"}\n]\n\ndef chat(user_input: str) -> None:\n    \"\"\"发送消息并流式打印回复\"\"\"\n    history.append({\"role\": \"user\", \"content\": user_input})\n    stream = client.chat.completions.create(\n        model=MODEL, messages=history, stream=True\n    )\n    print(\"AI > \", end=\"\", flush=True)\n    full_reply = \"\"\n    for chunk in stream:\n        delta = chunk.choices[0].delta.content\n        if delta:\n            print(delta, end=\"\", flush=True)  # 逐块打印 = 打字机效果\n            full_reply += delta\n    print()\n    # 关键：把 AI 的回复存回历史，实现记忆\n    history.append({\"role\": \"assistant\", \"content\": full_reply})\n\ndef main() -> None:\n    print(\"🤖 AI 助手已启动（\u002Fquit 退出，\u002Fclear 清空记忆）\\n\")\n    while True:\n        try:\n            user_input = input(\"你 > \").strip()\n        except (KeyboardInterrupt, EOFError):  # Ctrl+C \u002F Ctrl+D 优雅退出\n            print(\"\\n再见！\")\n            break\n        if not user_input:\n            continue\n        if user_input == \"\u002Fquit\":\n            print(\"再见！\")\n            break\n        if user_input == \"\u002Fclear\":\n            history[:] = history[:1]  # 只保留 system 人设\n            print(\"（记忆已清空）\\n\")\n            continue\n        try:\n            chat(user_input)\n        except Exception as e:\n            print(f\"出错了：{e}\\n\")  # 网络错误不退出，下次还能用\n        print()\n\nif __name__ == \"__main__\":\n    main()\n```\n\n到这里已经是一个能用的 AI 助手了：流式输出、有记忆、能清空、出错不崩。\n\n## 第 2 步：控制记忆长度\n\n对话历史无限增长会撞上两个天花板：模型的上下文窗口、以及你的余额（历史每轮都重新计费）。加一个滑动窗口：\n\n```python\nMAX_HISTORY = 20  # 最多保留最近 20 条消息\n\ndef trim_history() -> None:\n    \"\"\"保留 system + 最近的对话，超出的最旧记录删掉\"\"\"\n    if len(history) > MAX_HISTORY + 1:\n        del history[1 : len(history) - MAX_HISTORY]\n```\n\n在 `chat()` 开头调用一次 `trim_history()` 即可。更精细的方案是按 token 数裁剪，但按条数对日常使用已足够。\n\n## 第 3 步：保存对话记录\n\n`\u002Fsave` 命令把当前会话存成 Markdown 文件：\n\n```python\nfrom datetime import datetime\n\ndef save_history() -> str:\n    \"\"\"导出对话到 Markdown 文件，返回文件名\"\"\"\n    lines = [f\"# AI 对话记录 {datetime.now():%Y-%m-%d %H:%M}\\n\"]\n    for msg in history[1:]:  # 跳过 system\n        role = \"**你**\" if msg[\"role\"] == \"user\" else \"**AI**\"\n        lines.append(f\"{role}：{msg['content']}\\n\")\n    filename = f\"chat_{datetime.now():%Y%m%d_%H%M%S}.md\"\n    with open(filename, \"w\", encoding=\"utf-8\") as f:\n        f.write(\"\\n\".join(lines))\n    return filename\n```\n\n在主循环里加分支：\n\n```python\n        if user_input == \"\u002Fsave\":\n            print(f\"（已保存到 {save_history()}）\\n\")\n            continue\n```\n\n## 第 4 步：配置文件管理 Key\n\nKey 写死在代码里既危险又不方便分享，改用配置文件：\n\n```python\n# config.py\nimport json\nfrom pathlib import Path\n\nCONFIG_PATH = Path.home() \u002F \".ai_chat_config.json\"\n\ndef load_config() -> dict:\n    \"\"\"读取配置，没有则引导用户创建\"\"\"\n    if not CONFIG_PATH.exists():\n        key = input(\"首次使用，请输入你的 API Key：\").strip()\n        CONFIG_PATH.write_text(\n            json.dumps({\"api_key\": key, \"model\": \"deepseek-chat\"}, ensure_ascii=False, indent=2),\n            encoding=\"utf-8\",\n        )\n        print(f\"配置已保存到 {CONFIG_PATH}\\n\")\n    return json.loads(CONFIG_PATH.read_text(encoding=\"utf-8\"))\n```\n\n主程序里：\n\n```python\nconfig = load_config()\nclient = OpenAI(api_key=config[\"api_key\"], base_url=\"https:\u002F\u002Fapi.deepseek.com\")\nMODEL = config[\"model\"]\n```\n\n配置文件放在用户主目录，既不用每次输入，也不会误提交进 Git。\n\n## 第 5 步：打包成 exe\n\n让没有 Python 环境的朋友也能用：\n\n```bash\npip install pyinstaller\npyinstaller --onefile --name ai-chat ai_chat.py\n```\n\n产物在 `dist\u002Fai-chat.exe`，双击即用，体积约 15MB（含 Python 运行时）。\n\n几个实用参数：\n\n```bash\npyinstaller --onefile --name ai-chat --clean ai_chat.py\n# --onefile  打成单个 exe\n# --clean    清掉上次构建缓存，改代码后重新打包建议加上\n```\n\n## 完整效果与扩展方向\n\n最终成品是一个 100 行左右的单文件工具。跑通之后，可以按需扩展：\n\n**加「温度」调节**：`\u002Ftemp 0.3` 命令动态调整创造性参数。\n\n**加预设角色**：`\u002Frole 翻译` 切换 system 人设，一个工具当多个助手用。\n\n**统计用量**：从响应里取 `usage` 字段，显示本次消耗了多少 token、约合多少钱：\n\n```python\n# 非流式响应可直接读 usage；流式需设置 stream_options={\"include_usage\": True}\nstream = client.chat.completions.create(\n    model=MODEL, messages=history, stream=True,\n    stream_options={\"include_usage\": True},\n)\n# 最后一个 chunk 里有 usage 信息\n```\n\n**接入本地模型**：把 `base_url` 换成 `http:\u002F\u002Flocalhost:11434\u002Fv1`（Ollama），这个工具就变成了离线版 AI 助手——代码一行都不用改，这就是 OpenAI 兼容接口的妙处。\n\n## 回顾：这个项目用到了什么\n\n| 知识点 | 出处 |\n|--------|------|\n| 虚拟环境管理依赖 | 笔记 1 |\n| 第三方库调用网络 API | 笔记 2 |\n| 异常处理与优雅退出 | 笔记 6 |\n| 配置文件与文件读写 | 笔记 6\u002F7 |\n| 字符串处理 | 笔记 9 |\n\n这就是我们 Python 专题的初衷：**学语法的最好方式是做东西**。这个命令行助手可能就是你以后每天用 AI 的方式之一——自己动手做的工具，用起来总是格外顺手。\n","\u002Fstatic\u002Fuploads\u002Fimages\u002F2026\u002F09\u002F29\u002F1790636138763089017.png",8,"2026-09-29T06:56:29.738842766+08:00","2026-09-29T06:55:38.763211716+08:00","2026-09-29T06:56:29.738903836+08:00",{"id":72,"name":77,"slug":78,"description":77,"icon":5,"sortOrder":54,"postCount":54,"parentId":54,"createdAt":79,"updatedAt":79},"Python专题","Python","2026-09-29T06:55:05.938571812+08:00",{"id":55,"username":81,"email":32,"phone":5,"nickname":82,"avatarUrl":83,"bio":5,"role":55,"status":55,"points":54,"lastLoginAt":84,"loginCount":85,"createdAt":86,"updatedAt":87},"wuge","站长","\u002Fstatic\u002Fuploads\u002Favatars\u002F2026\u002F09\u002F29\u002F1790630804049538805.jpg","2026-09-29T05:22:12.192245111+08:00",3,"2026-09-29T04:25:29.170055083+08:00","2026-09-29T05:26:46.960829427+08:00",[89,94,99,104,109],{"id":90,"name":78,"slug":91,"color":92,"postCount":54,"createdAt":93},6,"python","#e2e8f0","2026-09-29T04:25:30.347030306+08:00",{"id":95,"name":96,"slug":97,"color":92,"postCount":54,"createdAt":98},89,"DeepSeek","deepseek","2026-09-29T06:46:13.756746391+08:00",{"id":100,"name":101,"slug":102,"color":92,"postCount":54,"createdAt":103},150,"AI","ai","2026-09-29T06:55:38.743861502+08:00",{"id":105,"name":106,"slug":107,"color":92,"postCount":54,"createdAt":108},151,"命令行工具","ming-ling-xing-gong-ju","2026-09-29T06:55:38.751023469+08:00",{"id":110,"name":111,"slug":112,"color":92,"postCount":54,"createdAt":113},152,"项目实战","xiang-mu-shi-zhan","2026-09-29T06:55:38.757712461+08:00",{"page":55,"pageSize":115,"total":55,"totalPages":55},12,{"items":117,"pagination":118,"tag":119},[],{"page":55,"pageSize":115,"total":54,"totalPages":55},{"id":105,"name":106,"slug":107,"color":92,"postCount":54,"createdAt":108},[121,122,127,132,137,142,147,152,157,162,167,172,177,182,187,192,196,201,206,211,212,217,222,227,232,237,241,246,251,256],{"id":100,"name":101,"slug":102,"color":92,"postCount":54,"createdAt":103},{"id":123,"name":124,"slug":125,"color":92,"postCount":54,"createdAt":126},53,"AI 绘画","ai-hui-hua","2026-09-29T04:25:30.70107663+08:00",{"id":128,"name":129,"slug":130,"color":92,"postCount":54,"createdAt":131},94,"AIGC","aigc","2026-09-29T06:46:13.817043541+08:00",{"id":133,"name":134,"slug":135,"color":92,"postCount":54,"createdAt":136},81,"AI入门","ai-ru-men","2026-09-29T06:46:13.646321088+08:00",{"id":138,"name":139,"slug":140,"color":92,"postCount":54,"createdAt":141},113,"AI写作","ai-xie-zuo","2026-09-29T06:46:14.098797917+08:00",{"id":143,"name":144,"slug":145,"color":92,"postCount":54,"createdAt":146},95,"AI工具","ai-gong-ju","2026-09-29T06:46:13.849105815+08:00",{"id":148,"name":149,"slug":150,"color":92,"postCount":54,"createdAt":151},87,"AI技巧","ai-ji-qiao","2026-09-29T06:46:13.717351439+08:00",{"id":153,"name":154,"slug":155,"color":92,"postCount":54,"createdAt":156},92,"AI绘画","ai-hui-hua-2","2026-09-29T06:46:13.800506851+08:00",{"id":158,"name":159,"slug":160,"color":92,"postCount":54,"createdAt":161},88,"AI编程","ai-bian-cheng","2026-09-29T06:46:13.748934007+08:00",{"id":163,"name":164,"slug":165,"color":92,"postCount":54,"createdAt":166},104,"API","api","2026-09-29T06:46:13.964167454+08:00",{"id":168,"name":169,"slug":170,"color":92,"postCount":54,"createdAt":171},24,"Agent","agent","2026-09-29T04:25:30.481917452+08:00",{"id":173,"name":174,"slug":175,"color":92,"postCount":54,"createdAt":176},15,"Apache-2.0","apache-2-0","2026-09-29T04:25:30.413130076+08:00",{"id":178,"name":179,"slug":180,"color":92,"postCount":54,"createdAt":181},124,"BeautifulSoup","beautifulsoup","2026-09-29T06:55:38.372320794+08:00",{"id":183,"name":184,"slug":185,"color":92,"postCount":54,"createdAt":186},71,"C++","c","2026-09-29T04:25:30.832723566+08:00",{"id":188,"name":189,"slug":190,"color":92,"postCount":54,"createdAt":191},9,"C\u002FC++","c-c","2026-09-29T04:25:30.367438818+08:00",{"id":72,"name":193,"slug":194,"color":92,"postCount":54,"createdAt":195},"CPU 推理","cpu-tui-li","2026-09-29T04:25:30.360161464+08:00",{"id":197,"name":198,"slug":199,"color":92,"postCount":54,"createdAt":200},82,"ChatGPT","chatgpt","2026-09-29T06:46:13.65246271+08:00",{"id":202,"name":203,"slug":204,"color":92,"postCount":54,"createdAt":205},43,"ChatGPT 界面","chatgpt-jie-mian","2026-09-29T04:25:30.631791206+08:00",{"id":207,"name":208,"slug":209,"color":92,"postCount":54,"createdAt":210},109,"Coze","coze","2026-09-29T06:46:14.04772698+08:00",{"id":95,"name":96,"slug":97,"color":92,"postCount":54,"createdAt":98},{"id":213,"name":214,"slug":215,"color":92,"postCount":54,"createdAt":216},103,"Embedding","embedding","2026-09-29T06:46:13.931530378+08:00",{"id":218,"name":219,"slug":220,"color":92,"postCount":54,"createdAt":221},139,"Excel","excel","2026-09-29T06:55:38.596869557+08:00",{"id":223,"name":224,"slug":225,"color":92,"postCount":54,"createdAt":226},132,"FastAPI","fastapi","2026-09-29T06:55:38.496902061+08:00",{"id":228,"name":229,"slug":230,"color":92,"postCount":54,"createdAt":231},107,"Fine-tuning","fine-tuning","2026-09-29T06:46:14.010861283+08:00",{"id":233,"name":234,"slug":235,"color":92,"postCount":54,"createdAt":236},97,"Gamma","gamma","2026-09-29T06:46:13.863615311+08:00",{"id":85,"name":238,"slug":239,"color":92,"postCount":54,"createdAt":240},"Go","go","2026-09-29T04:25:30.324360969+08:00",{"id":242,"name":243,"slug":244,"color":92,"postCount":54,"createdAt":245},98,"Kimi","kimi","2026-09-29T06:46:13.871065157+08:00",{"id":247,"name":248,"slug":249,"color":92,"postCount":54,"createdAt":250},7,"LLM","llm","2026-09-29T04:25:30.353458642+08:00",{"id":252,"name":253,"slug":254,"color":92,"postCount":54,"createdAt":255},31,"LLMOps","llmops","2026-09-29T04:25:30.534990482+08:00",{"id":257,"name":258,"slug":259,"color":92,"postCount":54,"createdAt":260},101,"LangChain","langchain","2026-09-29T06:46:13.916898801+08:00",[262],{"id":55,"userId":263,"donorName":35,"amount":264,"message":265,"paymentMethod":266,"isAnonymous":54,"status":55,"createdAt":267},null,128,"加油","wechat","2026-09-29T04:45:44+08:00",{"materials":269},[],{"materials":271},[],{"materials":273},[]]