文章列表

如何判断用户是否离开了当前页面?

作者:微信小助手

<p data-line="1" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; data-pm-slice="0 0 []"><span leaf="">在现代 Web 开发中,我们常常需要知道用户是否还停留在当前页面。这个看似简单的需求,背后却关联着用户体验、数据分析和系统性能等多个重要方面。</span></p> <p data-line="3" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">“离开页面”这个行为本身可以被细分为多种场景:</span></p> <ol style="box-sizing: border-box;padding-left: 2rem;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">切换到其他浏览器标签页或应用</span></strong><span leaf="">(页面变为不可见,但未关闭)。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">最小化浏览器窗口</span></strong><span leaf="">(同上)。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">关闭浏览器标签页或整个浏览器</span></strong><span leaf="">。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">在当前标签页中导航到新的 URL</span></strong><span leaf="">。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">在移动设备上切换到其他 App 或返回主屏幕</span></strong><span leaf="">。</span></span></li> </ol> <p data-line="10" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">针对这些不同的场景,前端提供了多种不同的技术和 API 来进行判断。</span></p> <h2 data-line="12" style="box-sizing: border-box;margin-top: 1.2em;margin-bottom: 16px;font-weight: 400;line-height: 1.2;color: rgb(0, 0, 0);font-size: 1.4641em;padding-bottom: 0.2em;font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">方法一:Page Visibility API (页面可见性 API) - 现代首选</span></h2> <p data-line="14" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">这是处理“页面是否对用户可见”这一问题的标准方法。它专门用于检测页面是否被隐藏或显示,非常适合处理用户切换标签页、最小化窗口等场景。</span></p> <p data-line="16" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">核心概念:</span></strong></p> <ul style="box-sizing: border-box;padding-left: 2rem;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">document.hidden</span></code></strong><span leaf="">:一个只读属性,如果页面处于后台或最小化状态,则返回&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">true</span></code><span leaf="">,否则返回&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">false</span></code><span leaf="">。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">visibilitychange</span></code><span leaf="">&nbsp;事件</span></strong><span leaf="">:当页面的可见性状态发生变化时(即&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">document.hidden</span></code><span leaf="">&nbsp;的值改变时),该事件会在&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">document</span></code><span leaf="">&nbsp;对象上触发。</span></span></li> </ul> <p data-line="20" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">适用场景:</span></strong></p> <ul style="box-sizing: border-box;padding-left: 2rem;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><span leaf="">暂停/播放视频或音频。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><span leaf="">停止/启动动画或轮播图。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><span leaf="">暂停轮询服务器请求,在页面恢复可见时再继续。</span></span></li> </ul> <p data-line="25" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">代码示例:</span></strong></p> <pre style="box-sizing: border-box;font-family: SFMono-Regular, Menlo, Monaco, Consolas, " liberation mono, courier new, monospace;font-size: 0.875em;display: block;margin-top: 0px;margin-bottom: 1rem;overflow: auto;color: rgb(51, 51, 51);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><code style="box-sizing: border-box;font-family: " fira code, menlo, consolas, source code pro, monospace;font-size: 14px;color: rgb(51, 51, 51);overflow-wrap: break-word;padding: 0.5em;margin: 0px;background: rgb(248, 248, 248);border-radius: 3px;word-break: normal;display: block;overflow-x: auto;><span style="box-sizing: border-box;color: rgb(0, 128, 128);"><span leaf="">document</span></span><span leaf="">.</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">addEventListener</span></span><span leaf="">(</span><span style="box-sizing: border-box;color: rgb(221, 17, 68);"><span leaf="">'visibilitychange'</span></span><span leaf="">,</span><span style="box-sizing: border-box;"><span leaf="">&nbsp;() =&gt;</span></span><span leaf="">&nbsp;{</span><span leaf=""><br></span><span leaf="">&nbsp;</span><span style="box-sizing: border-box;color: rgb(51, 51, 51);font-weight: bold;"><span leaf="">&nbsp;if</span></span><span leaf="">&nbsp;(</span><span style="box-sizing: border-box;color: rgb(0, 128, 128);"><span leaf="">document</span></span><span leaf="">.</span><span style="box-sizing: border-box;"><span leaf="">hidden</span></span><span leaf="">) {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;</span><span style="box-sizing: border-box;color: rgb(153, 153, 136);font-style: italic;"><span leaf="">&nbsp;// 页面变得不可见</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;</span><span style="box-sizing: border-box;color: rgb(0, 128, 128);"><span leaf="">&nbsp;console</span></span><span leaf="">.</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">log</span></span><span leaf="">(</span><span style="box-sizing: border-box;color: rgb(221, 17, 68);"><span leaf="">'用户离开了当前页面(切换标签页或最小化)'</span></span><span leaf="">);</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;</span><span style="box-sizing: border-box;color: rgb(153, 153, 136);font-style: italic;"><span leaf="">&nbsp;// 在这里暂停视频、动画等</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">&nbsp;pauseMyVideo</span></span><span leaf="">();</span><span leaf=""><br></span><span leaf="">&nbsp; }</span><span style="box-sizing: border-box;color: rgb(51, 51, 51);font-weight: bold;"><span leaf="">&nbsp;else</span></span><span leaf="">&nbsp;{</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;</span><span style="box-sizing: border-box;color: rgb(153, 153, 136);font-style: italic;"><span leaf="">&nbsp;// 页面恢复可见</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;</span><span style="box-sizing: border-box;color: rgb(0, 128, 128);"><span leaf="">&nbsp;console</span></span><span leaf="">.</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">log</span></span><span leaf="">(</span><span style="box-sizing: border-box;color: rgb(221, 17, 68);"><span leaf="">'用户回到了当前页面'</span></span><span leaf="">);</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;</span><span style="box-sizing: border-box;color: rgb(153, 153, 136);font-style: italic;"><span leaf="">&nbsp;// 在这里恢复播放</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">&nbsp;playMyVideo</span></span><span leaf="">();</span><span leaf=""><br></span><span leaf="">&nbsp; }</span><span leaf=""><br></span><span leaf="">});</span><span leaf=""><br></span></code></pre> <p data-line="42" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">优点:</span></strong></p> <ul style="box-sizing: border-box;padding-left: 2rem;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">标准、可靠</span></strong><span leaf="">:W3C 标准,所有现代浏览器都支持。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">性能友好</span></strong><span leaf="">:专门为此设计,能有效节省 CPU 和电池资源。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">逻辑清晰</span></strong><span leaf="">:直接反映页面的“可见”状态。</span></span></li> </ul> <p data-line="47" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">缺点:</span></strong></p> <ul style="box-sizing: border-box;padding-left: 2rem;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><span leaf="">它无法判断用户是否正在</span><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">关闭</span></strong><span leaf="">页面。当用户关闭标签页时,</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">visibilitychange</span></code><span leaf="">&nbsp;事件可能会触发(变为 hidden),但我们无法区分这是切换还是关闭。</span></span></li> </ul> <hr style="box-sizing: border-box;margin: 1rem 0px;color: rgb(51, 51, 51);border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-image: initial;border-top-style: solid;border-top-color: rgb(51, 51, 51);opacity: 0.25;font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;> <h2 data-line="52" style="box-sizing: border-box;margin-top: 1.2em;margin-bottom: 16px;font-weight: 400;line-height: 1.2;color: rgb(0, 0, 0);font-size: 1.4641em;padding-bottom: 0.2em;font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">方法二:</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 19.9118px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">beforeunload</span></code><span leaf="">&nbsp;和&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 19.9118px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">unload</span></code><span leaf="">&nbsp;事件 - 传统告别方式</span></h2> <p data-line="54" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">这两个事件是在用户即将</span><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">真正离开</span></strong><span leaf="">页面(关闭、刷新、导航到其他链接)时触发的。</span></p> <h3 data-line="56" style="box-sizing: border-box;margin-top: 1.2em;margin-bottom: 16px;font-weight: 500;line-height: 1.2;color: rgb(0, 0, 0);font-size: 1.331em;font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">1.&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 18.1016px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">beforeunload</span></code><span leaf="">&nbsp;事件</span></h3> <p data-line="57" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">该事件在窗口、文档及其资源即将被卸载时触发。它可以用来询问用户是否确定要离开。</span></p> <p data-line="59" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">核心用途:</span></strong></p> <ul style="box-sizing: border-box;padding-left: 2rem;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><span leaf="">防止用户意外丢失未保存的数据。浏览器通常会弹出一个确认对话框。</span></span></li> </ul> <p data-line="62" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">代码示例:</span></strong></p> <section nodeleaf=""> <img src="/upload/7abe38fefd47b2cbaeb1e266365c9e2d.png" class="rich_pages wxw-img" data-ratio="0.31443298969072164" data-type="png" data-w="776" style="box-sizing: border-box;vertical-align: middle;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;max-width: 100%; data-imgfileid="504023176"> </section> <section> <span style="color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;display: inline !important;float: none;></span> </section> <p data-line="72" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">注意</span></strong><span leaf="">:出于安全考虑,现代浏览器不允许开发者自定义提示框中的文本内容,只会显示浏览器内置的标准化提示。</span></p> <h3 data-line="74" style="box-sizing: border-box;margin-top: 1.2em;margin-bottom: 16px;font-weight: 500;line-height: 1.2;color: rgb(0, 0, 0);font-size: 1.331em;font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">2.&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 18.1016px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">unload</span></code><span leaf="">&nbsp;事件</span></h3> <p data-line="75" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">该事件在页面</span><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">已经开始卸载</span></strong><span leaf="">之后触发。这是我们在用户离开时执行最后清理操作的传统位置。</span></p> <p data-line="77" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">代码示例:</span></strong></p> <pre style="box-sizing: border-box;font-family: SFMono-Regular, Menlo, Monaco, Consolas, " liberation mono, courier new, monospace;font-size: 0.875em;display: block;margin-top: 0px;margin-bottom: 1rem;overflow: auto;color: rgb(51, 51, 51);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><code style="box-sizing: border-box;font-family: " fira code, menlo, consolas, source code pro, monospace;font-size: 14px;color: rgb(51, 51, 51);overflow-wrap: break-word;padding: 0.5em;margin: 0px;background: rgb(248, 248, 248);border-radius: 3px;word-break: normal;display: block;overflow-x: auto;><span style="box-sizing: border-box;color: rgb(0, 128, 128);"><span leaf="">window</span></span><span leaf="">.</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">addEventListener</span></span><span leaf="">(</span><span style="box-sizing: border-box;color: rgb(221, 17, 68);"><span leaf="">'unload'</span></span><span leaf="">,</span><span style="box-sizing: border-box;"><span leaf="">&nbsp;() =&gt;</span></span><span leaf="">&nbsp;{</span><span leaf=""><br></span><span leaf="">&nbsp;</span><span style="box-sizing: border-box;color: rgb(0, 128, 128);"><span leaf="">&nbsp;console</span></span><span leaf="">.</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">log</span></span><span leaf="">(</span><span style="box-sizing: border-box;color: rgb(221, 17, 68);"><span leaf="">'用户正在关闭或离开页面'</span></span><span leaf="">);</span><span leaf=""><br></span><span leaf="">&nbsp;</span><span style="box-sizing: border-box;color: rgb(153, 153, 136);font-style: italic;"><span leaf="">&nbsp;// 警告:在这里执行的操作可能不会完成!</span></span><span leaf=""><br></span><span leaf="">&nbsp;</span><span style="box-sizing: border-box;color: rgb(153, 153, 136);font-style: italic;"><span leaf="">&nbsp;// sendAnalyticsData();</span></span><span leaf=""><br></span><span leaf="">});</span><span leaf=""><br></span></code></pre> <p data-line="86" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">重大缺陷:</span></strong><span leaf=""><br></span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">unload</span></code><span leaf="">&nbsp;事件非常</span><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">不可靠</span></strong><span leaf="">。浏览器在处理页面卸载时,并不会等待&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">unload</span></code><span leaf="">&nbsp;事件处理器中的异步操作(如&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">fetch</span></code><span leaf="">&nbsp;或&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">XMLHttpRequest</span></code><span leaf="">)完成。这意味着,如果我们想在这里发送一个分析数据到服务器,这个请求很可能在发送完成之前就被浏览器终止了。</span></p> <hr style="box-sizing: border-box;margin: 1rem 0px;color: rgb(51, 51, 51);border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-image: initial;border-top-style: solid;border-top-color: rgb(51, 51, 51);opacity: 0.25;font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;> <h2 data-line="91" style="box-sizing: border-box;margin-top: 1.2em;margin-bottom: 16px;font-weight: 400;line-height: 1.2;color: rgb(0, 0, 0);font-size: 1.4641em;padding-bottom: 0.2em;font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">方法三:</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 19.9118px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">navigator.sendBeacon()</span></code><span leaf="">&nbsp;- 可靠的数据上报利器</span></h2> <p data-line="93" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">为了解决&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">unload</span></code><span leaf="">&nbsp;事件中异步请求不可靠的问题,W3C 推出了&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">navigator.sendBeacon()</span></code><span leaf="">&nbsp;API。</span></p> <p data-line="95" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">核心概念:</span></strong><span leaf=""><br></span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">sendBeacon()</span></code><span leaf="">&nbsp;方法可以异步地向服务器发送少量数据,并且</span><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">浏览器保证</span></strong><span leaf="">会将其启动并排队发送,而不会阻塞或延迟页面的卸载过程。即使页面已经关闭,数据发送也会在后台继续进行。</span></p> <p data-line="98" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">适用场景:</span></strong></p> <ul style="box-sizing: border-box;padding-left: 2rem;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><span leaf="">在用户离开页面时,可靠地发送日志、分析或统计数据。</span></span></li> </ul> <p data-line="101" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">如何使用(通常与&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">unload</span></code><span leaf="">&nbsp;或&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">pagehide</span></code><span leaf="">&nbsp;结合):</span></strong></p> <section nodeleaf=""> <img src="/upload/cb0cf12e8100ae39619c33fdc14c71f3.png" class="rich_pages wxw-img" data-ratio="0.22407407407407406" data-type="png" data-w="1080" style="box-sizing: border-box;vertical-align: middle;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;max-width: 100%; data-imgfileid="504023178"> </section> <section> <span style="color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;display: inline !important;float: none;></span> </section> <p data-line="113" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">这种方式是目前在页面卸载时发送数据的</span><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">最佳实践</span></strong><span leaf="">。</span></p> <hr style="box-sizing: border-box;margin: 1rem 0px;color: rgb(51, 51, 51);border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-image: initial;border-top-style: solid;border-top-color: rgb(51, 51, 51);opacity: 0.25;font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;> <h2 data-line="117" style="box-sizing: border-box;margin-top: 1.2em;margin-bottom: 16px;font-weight: 400;line-height: 1.2;color: rgb(0, 0, 0);font-size: 1.4641em;padding-bottom: 0.2em;font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">方法四:</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 19.9118px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">pagehide</span></code><span leaf="">&nbsp;和&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 19.9118px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">pageshow</span></code><span leaf="">&nbsp;事件 - 应对往返缓存(bfcache)</span></h2> <p data-line="119" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">现代浏览器(尤其是移动端)引入了“往返缓存”(Back-Forward Cache, bfcache)。当用户导航到其他页面后,如果点击“后退”按钮,浏览器可能会直接从缓存中恢复上一个页面,而不是重新加载它。在这种情况下,</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">unload</span></code><span leaf="">&nbsp;事件可能根本不会触发。</span></p> <p data-line="121" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">pagehide</span></code><span leaf="">&nbsp;事件则可以更好地处理这种情况。</span></p> <p data-line="123" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">核心概念:</span></strong></p> <ul style="box-sizing: border-box;padding-left: 2rem;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">pagehide</span></code><span leaf="">&nbsp;事件</span></strong><span leaf="">:在用户导航离开页面时触发,无论页面是否被存入 bfcache。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">event.persisted</span></code></strong><span leaf="">:</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">pagehide</span></code><span leaf="">&nbsp;事件对象的一个属性。如果页面被存入 bfcache,它为&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">true</span></code><span leaf="">;否则为&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">false</span></code><span leaf="">。</span></span></li> </ul> <p data-line="127" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">代码示例:</span></strong></p> <pre style="box-sizing: border-box;font-family: SFMono-Regular, Menlo, Monaco, Consolas, " liberation mono, courier new, monospace;font-size: 0.875em;display: block;margin-top: 0px;margin-bottom: 1rem;overflow: auto;color: rgb(51, 51, 51);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><code style="box-sizing: border-box;font-family: " fira code, menlo, consolas, source code pro, monospace;font-size: 14px;color: rgb(51, 51, 51);overflow-wrap: break-word;padding: 0.5em;margin: 0px;background: rgb(248, 248, 248);border-radius: 3px;word-break: normal;display: block;overflow-x: auto;><span style="box-sizing: border-box;color: rgb(0, 128, 128);"><span leaf="">window</span></span><span leaf="">.</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">addEventListener</span></span><span leaf="">(</span><span style="box-sizing: border-box;color: rgb(221, 17, 68);"><span leaf="">'pagehide'</span></span><span leaf="">,</span><span style="box-sizing: border-box;"><span leaf="">&nbsp;(</span><span style="box-sizing: border-box;"><span leaf="">event</span></span><span leaf="">) =&gt;</span></span><span leaf="">&nbsp;{</span><span leaf=""><br></span><span leaf="">&nbsp;</span><span style="box-sizing: border-box;color: rgb(51, 51, 51);font-weight: bold;"><span leaf="">&nbsp;if</span></span><span leaf="">&nbsp;(event.</span><span style="box-sizing: border-box;"><span leaf="">persisted</span></span><span leaf="">) {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;</span><span style="box-sizing: border-box;color: rgb(0, 128, 128);"><span leaf="">&nbsp;console</span></span><span leaf="">.</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">log</span></span><span leaf="">(</span><span style="box-sizing: border-box;color: rgb(221, 17, 68);"><span leaf="">'页面正在进入 bfcache'</span></span><span leaf="">);</span><span leaf=""><br></span><span leaf="">&nbsp; }</span><span style="box-sizing: border-box;color: rgb(51, 51, 51);font-weight: bold;"><span leaf="">&nbsp;else</span></span><span leaf="">&nbsp;{</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;</span><span style="box-sizing: border-box;color: rgb(0, 128, 128);"><span leaf="">&nbsp;console</span></span><span leaf="">.</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">log</span></span><span leaf="">(</span><span style="box-sizing: border-box;color: rgb(221, 17, 68);"><span leaf="">'页面正在被正常卸载'</span></span><span leaf="">);</span><span leaf=""><br></span><span leaf="">&nbsp; }</span><span leaf=""><br></span><span leaf=""><br></span><span leaf="">&nbsp;</span><span style="box-sizing: border-box;color: rgb(153, 153, 136);font-style: italic;"><span leaf="">&nbsp;// 无论哪种情况,这里都是发送 Beacon 的好时机</span></span><span leaf=""><br></span><span leaf="">&nbsp; navigator.</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">sendBeacon</span></span><span leaf="">(</span><span style="box-sizing: border-box;color: rgb(221, 17, 68);"><span leaf="">'/log'</span></span><span leaf="">,</span><span style="box-sizing: border-box;color: rgb(153, 0, 0);font-weight: bold;"><span leaf="">&nbsp;getAnalyticsData</span></span><span leaf="">());</span><span leaf=""><br></span><span leaf="">});</span><span leaf=""><br></span></code></pre> <p data-line="140" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">pagehide</span></code><span leaf="">&nbsp;比&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">unload</span></code><span leaf="">&nbsp;更可靠,特别是在移动设备上。因此,推荐使用&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">pagehide</span></code><span leaf="">&nbsp;来代替&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">unload</span></code><span leaf="">。</span></p> <h3 data-line="142" style="box-sizing: border-box;margin-top: 1.2em;margin-bottom: 16px;font-weight: 500;line-height: 1.2;color: rgb(0, 0, 0);font-size: 1.331em;font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">最终建议</span></h3> <ol style="box-sizing: border-box;padding-left: 2rem;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">对于“可见性”判断</span></strong><span leaf="">:优先使用&nbsp;</span><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">Page Visibility API</span></strong><span leaf="">。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">对于“离开时上报数据”</span></strong><span leaf="">:使用&nbsp;</span><strong style="box-sizing: border-box;font-weight: bolder;"><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">navigator.sendBeacon()</span></code></strong><span leaf="">,并将其放在&nbsp;</span><strong style="box-sizing: border-box;font-weight: bolder;"><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">pagehide</span></code></strong><span leaf="">&nbsp;事件监听器中,以获得最佳的兼容性和可靠性。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">对于“防止数据丢失”</span></strong><span leaf="">:仅在必要时使用&nbsp;</span><strong style="box-sizing: border-box;font-weight: bolder;"><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">beforeunload</span></code></strong><span leaf="">,因为它会中断用户操作。</span></span></li> <li style="box-sizing: border-box;"><span style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: bolder;"><span leaf="">避免使用&nbsp;</span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, courier, monospace;font-size: 13.6px;color: rgb(214, 51, 132);overflow-wrap: break-word;padding: 0.2em 0.4em;margin: 0px;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;><span leaf="">unload</span></code></strong><span leaf="">:除非我们只需要执行一些非常简单的同步代码,否则尽量避免使用它,尤其不要在其中包含异步网络请求。</span></span></li> </ol> <p data-line="149" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;color: rgb(51, 51, 51);font-family: " helvetica neue, helvetica, segoe ui, arial, freesans, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">通过组合运用这些现代 API,我们不仅能准确地判断用户的行为,还能在不牺牲性能和可靠性的前提下,打造出更智能、更友好的用户体验。</span></p> <section class="mp_profile_iframe_wrp" nodeleaf=""> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-nickname="JavaScript" data-alias="FedJavaScript" data-from="0" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/btsCOHx9LAO55RFZ2rpHxp8JCdibf2zroiae9jOtwgicS0DIZM6II8CkDDY1icAQ2QakuFr6pkRJgIIdyicDM4FRic2w/0?wx_fmt=png" data-signature="为 JavaScript 爱好人员提供:Web 前端相关技术教程、JavaScript、Node.js、Deno、Vue.js、React、Angular、HTML5、CSS3 等一系列教程和经验分享" data-id="MzAwNjI5MTYyMw==" data-is_biz_ban="0" data-service_type="1" data-verify_status="0"></mp-common-profile> </section> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>

Go 隐身术:用 Garble 混淆你的代码

作者:微信小助手

<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 10px;padding-right: 10px;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;font-family: Optima, PingFangSC-regular, serif;font-size: 16px;color: rgb(0, 0, 0);line-height: 1.5em;word-spacing: 0em;letter-spacing: 0em;word-break: break-word;overflow-wrap: break-word;text-align: left;" data-pm-slice="0 0 []"> <section class="mp_profile_iframe_wrp" nodeleaf=""> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-nickname="令飞编程" data-alias="lingfeicode" data-from="0" data-headimg="http://mmbiz.qpic.cn/sz_mmbiz_png/icvNBbCQaw3lF8PebkLfZKGAIQ3wVDpefdaKdKibzK66gltnRYjLbVIuF5WOwuRNC7ribicZbaM2vWWEleicjDibGMRA/0?wx_fmt=png" data-signature="分享 Go、云原生、AI Infra 相关的技术栈及编程实战" data-id="Mzk0MTY1NDczMA==" data-is_biz_ban="0" data-service_type="1" data-verify_status="0"></mp-common-profile> </section> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">在项目开发中,经常会有需求:需要对外提供一个工具/服务,但我们不希望对方通过提供的文件,反推出实现源码。这时候,我们就需要对代码进行混淆。本文介绍如何使用 Garble 来混淆你的代码。</span></p> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span style="color: rgb(150, 84, 181);font-weight: bold;"><span leaf="">Garble</span></span><sup style="line-height: 0;color: rgb(150, 84, 181);font-weight: bold;"><span leaf="">[1]</span></sup><span leaf="">&nbsp;是由 burrowers 社区开发的开源工具,它封装了 Go 编译器,为生成高度混淆的 Go 二进制提供一站式方案。它在尽量保持二进制兼容性的同时,大幅提升源码还原和逆向的难度。</span></p> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">Garble 主要功能有:</span></p> <ul style="list-style-type: disc;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">标识符/包路径混淆:</span></strong><span leaf="">重命名函数、变量、结构体名,剔除大部分元数据;</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">字符串字面量加密:</span></strong><span leaf="">用&nbsp;</span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">-literals</span></code><span leaf="">&nbsp;标志让每个字符串运行时才被解密;</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">瘦身极小文件:</span></strong><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">-tiny</span></code><span leaf="">&nbsp;删除调试符号、文件名及行号,提高攻防门槛;</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">可重复构建:</span></strong><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">-seed</span></code><span leaf="">&nbsp;固定种子保证同一次混淆结果可复现;</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">栈追踪逆解析:</span></strong><span leaf="">搭配已知 seed 用&nbsp;</span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">garble reverse</span></code><span leaf="">&nbsp;还原混淆栈符号。</span> </section></li> </ul> <h2 data-tool="mdnice编辑器" style=" margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: center;line-height: 1.5em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: 100%;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;border-bottom-color: rgb(119, 48, 152);color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: 85%;height: auto;align-items: unset;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: block;font-weight: bold;flex-direction: unset;float: unset;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 10px;padding-left: 0px;padding-right: 0px; text-align: center;text-indent: 0em;text-shadow: none;transform: none;-webkit-box-reflect: unset; "><span leaf="">安装 Garble</span></span><span style="display: none;"></span></h2> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbr9zdqibmyz8myb8upib98yhowxk5gfbhmcyxg5mxydmh8wosompwvx5pc39pzbudujumw9fazdibgetpjppp7lbsg 640?wx_fmt="svg&amp;from=appmsg&quot;);&quot;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span leaf="">$ go install github.com/burrowers/garble@latest</span><br></code></pre> <h2 data-tool="mdnice编辑器" style=" margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: center;line-height: 1.5em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: 100%;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;border-bottom-color: rgb(119, 48, 152);color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: 85%;height: auto;align-items: unset;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: block;font-weight: bold;flex-direction: unset;float: unset;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 10px;padding-left: 0px;padding-right: 0px; text-align: center;text-indent: 0em;text-shadow: none;transform: none;-webkit-box-reflect: unset; "><span leaf="">混淆一个简单程序</span></span><span style="display: none;"></span></h2> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">下面是一个示例代码:</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbr9zdqibmyz8myb8upib98yhowxk5gfbhmcyxg5mxydmh8wosompwvx5pc39pzbudujumw9fazdibgetpjppp7lbsg 640?wx_fmt="svg&amp;from=appmsg&quot;);&quot;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 文件:main.go</span></span><br><span style="color: #c678dd;line-height: 26px;"><span leaf="">package</span></span><span leaf="">&nbsp;main</span><br><br><span style="color: #c678dd;line-height: 26px;"><span leaf="">import</span></span><span leaf="">&nbsp;</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"fmt"</span></span><br><br><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">func</span></span><span leaf="">&nbsp;</span><span style="color: #61aeee;line-height: 26px;"><span leaf="">main</span></span><span style="line-height: 26px;"><span leaf="">()</span></span></span><span leaf="">&nbsp;{</span><br><span leaf="">&nbsp; &nbsp; secret :=&nbsp;</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"Hello, Obfuscation!"</span></span><br><span leaf="">&nbsp; &nbsp; fmt.Println(process(secret))</span><br><span leaf="">}</span><br><br><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">func</span></span><span leaf="">&nbsp;</span><span style="color: #61aeee;line-height: 26px;"><span leaf="">process</span></span><span style="line-height: 26px;"><span leaf="">(s&nbsp;</span><span style="color: #c678dd;line-height: 26px;"><span leaf="">string</span></span><span leaf="">)</span></span><span leaf="">&nbsp;</span><span style="color: #61aeee;line-height: 26px;"><span leaf="">string</span></span></span><span leaf="">&nbsp;{</span><br><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="color: #c678dd;line-height: 26px;"><span leaf="">return</span></span><span leaf="">&nbsp;s +&nbsp;</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"-processed"</span></span><br><span leaf="">}</span><br></code></pre> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">正常构建:</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbr9zdqibmyz8myb8upib98yhowxk5gfbhmcyxg5mxydmh8wosompwvx5pc39pzbudujumw9fazdibgetpjppp7lbsg 640?wx_fmt="svg&amp;from=appmsg&quot;);&quot;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span leaf="">$ go build -o normal_app main.go</span><br><span leaf="">$ strings normal_app | grep process</span><br><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf=""># &gt;&gt; process</span></span><br></code></pre> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">现在使用 Garble 进行混淆:</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbr9zdqibmyz8myb8upib98yhowxk5gfbhmcyxg5mxydmh8wosompwvx5pc39pzbudujumw9fazdibgetpjppp7lbsg 640?wx_fmt="svg&amp;from=appmsg&quot;);&quot;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span leaf="">$ garble build -o garbled_app main.go</span><br><span leaf="">$ strings garbled_app | grep process</span><br><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf=""># &gt;&gt; no "process" found</span></span><br></code></pre> <h2 data-tool="mdnice编辑器" style=" margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: center;line-height: 1.5em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: 100%;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;border-bottom-color: rgb(119, 48, 152);color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: 85%;height: auto;align-items: unset;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: block;font-weight: bold;flex-direction: unset;float: unset;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 10px;padding-left: 0px;padding-right: 0px; text-align: center;text-indent: 0em;text-shadow: none;transform: none;-webkit-box-reflect: unset; "><span leaf="">字面量加密(字符串不可见)</span></span><span style="display: none;"></span></h2> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">加密每个字符串字面量:</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbr9zdqibmyz8myb8upib98yhowxk5gfbhmcyxg5mxydmh8wosompwvx5pc39pzbudujumw9fazdibgetpjppp7lbsg 640?wx_fmt="svg&amp;from=appmsg&quot;);&quot;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span leaf="">$ garble -literals build -o garbled_lit main.go</span><br><span leaf="">$ strings garbled_lit | grep Hello</span><br><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf=""># &gt;&gt; (nothing – strings scrambled at runtime)</span></span><br></code></pre> <h2 data-tool="mdnice编辑器" style=" margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: center;line-height: 1.5em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: 100%;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;border-bottom-color: rgb(119, 48, 152);color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: 85%;height: auto;align-items: unset;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: block;font-weight: bold;flex-direction: unset;float: unset;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 10px;padding-left: 0px;padding-right: 0px; text-align: center;text-indent: 0em;text-shadow: none;transform: none;-webkit-box-reflect: unset; "><span leaf="">确定性构建与逆向支持</span></span><span style="display: none;"></span></h2> <ol style="list-style-type: decimal;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">确定性混淆</span></strong> </section></li> </ol> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">修改 main.go 文件,内容如下:</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbr9zdqibmyz8myb8upib98yhowxk5gfbhmcyxg5mxydmh8wosompwvx5pc39pzbudujumw9fazdibgetpjppp7lbsg 640?wx_fmt="svg&amp;from=appmsg&quot;);&quot;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">package</span></span><span leaf="">&nbsp;main</span><br><br><span style="color: #c678dd;line-height: 26px;"><span leaf="">import</span></span><span leaf="">&nbsp;</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"fmt"</span></span><br><br><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">func</span></span><span leaf="">&nbsp;</span><span style="color: #61aeee;line-height: 26px;"><span leaf="">main</span></span><span style="line-height: 26px;"><span leaf="">()</span></span></span><span leaf="">&nbsp;{</span><br><span leaf="">&nbsp; &nbsp; secret :=&nbsp;</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"Hello, Obfuscation!"</span></span><br><span leaf="">&nbsp; &nbsp; fmt.Println(process(secret))</span><br><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">panic</span></span><span leaf="">(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"panic me"</span></span><span leaf="">)</span><br><span leaf="">}</span><br><br><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">func</span></span><span leaf="">&nbsp;</span><span style="color: #61aeee;line-height: 26px;"><span leaf="">process</span></span><span style="line-height: 26px;"><span leaf="">(s&nbsp;</span><span style="color: #c678dd;line-height: 26px;"><span leaf="">string</span></span><span leaf="">)</span></span><span leaf="">&nbsp;</span><span style="color: #61aeee;line-height: 26px;"><span leaf="">string</span></span></span><span leaf="">&nbsp;{</span><br><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="color: #c678dd;line-height: 26px;"><span leaf="">return</span></span><span leaf="">&nbsp;s +&nbsp;</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"-processed"</span></span><br><span leaf="">}</span><br></code></pre> <hr style="margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: solid;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(119, 48, 152);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: 1px;"> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">用固定 seed 得到唯一二进制(方便 bug 还原、定位):</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbr9zdqibmyz8myb8upib98yhowxk5gfbhmcyxg5mxydmh8wosompwvx5pc39pzbudujumw9fazdibgetpjppp7lbsg 640?wx_fmt="svg&amp;from=appmsg&quot;);&quot;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span leaf="">$ garble -seed=random build -o deterministic_app main.go</span><br><span leaf="">-seed chosen at random: 75MYDgjSJGFJT7ktvUROYw</span><br></code></pre> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><font style="color:rgba(6, 8, 31, 0.88);"></font></strong></p> <ol style="list-style-type: decimal;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><font style="color:rgba(6, 8, 31, 0.88);"><span leaf="">还原栈符号</span></font></strong> </section></li> </ol> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">程序崩溃需排查时,开发者可逆解析栈符号:</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbr9zdqibmyz8myb8upib98yhowxk5gfbhmcyxg5mxydmh8wosompwvx5pc39pzbudujumw9fazdibgetpjppp7lbsg 640?wx_fmt="svg&amp;from=appmsg&quot;);&quot;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span leaf="">$ ./deterministic_app &amp;&gt;panic-output.txt</span><br><span leaf="">$ garble -seed=75MYDgjSJGFJT7ktvUROYw reverse main.go panic-output.txt</span><br><span leaf="">Hello, Obfuscation!-processed</span><br><span leaf="">panic: panic me</span><br><br><span leaf="">goroutine 1 [running]:</span><br><span leaf="">main.main()</span><br><span leaf="">&nbsp;</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">command</span></span><span leaf="">-line-arguments/main.go:8 +0x7c</span><br></code></pre> <h2 data-tool="mdnice编辑器" style=" margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: center;line-height: 1.5em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: 100%;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;border-bottom-color: rgb(119, 48, 152);color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: 85%;height: auto;align-items: unset;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: block;font-weight: bold;flex-direction: unset;float: unset;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 10px;padding-left: 0px;padding-right: 0px; text-align: center;text-indent: 0em;text-shadow: none;transform: none;-webkit-box-reflect: unset; "><span leaf="">注意事项与实验特性</span></span><span style="display: none;"></span></h2> <ul style="list-style-type: disc;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">导出符号</span></strong><span leaf="">(用于反射/接口)不会被混淆,需知晓;</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <span leaf="">暂不支持 Go 插件;</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <span leaf="">控制流混淆可用实验变量开启:</span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">GARBLE_EXPERIMENTAL_CONTROLFLOW=1 garble build ...</span></code><span leaf="">;</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <span leaf="">源码信息已清理,但某些 Go runtime 字符串依然可见。</span> </section></li> </ul> <h2 data-tool="mdnice编辑器" style=" margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: center;line-height: 1.5em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: 100%;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;border-bottom-color: rgb(119, 48, 152);color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: 85%;height: auto;align-items: unset;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: block;font-weight: bold;flex-direction: unset;float: unset;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 10px;padding-left: 0px;padding-right: 0px; text-align: center;text-indent: 0em;text-shadow: none;transform: none;-webkit-box-reflect: unset; "><span leaf="">为什么推荐 Garble?</span></span><span style="display: none;"></span></h2> <ul style="list-style-type: disc;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <span leaf="">极大提升逆向和分析难度(难以还原函数名/算法/业务逻辑);</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <span leaf="">完美兼容 Go 的模块、缓存、堆栈追踪、自动化构建;</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <span leaf="">高性能:仅较&nbsp;</span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">go build</span></code><span leaf="">&nbsp;慢 1-2 倍。</span> </section></li> </ul> <h2 data-tool="mdnice编辑器" style=" margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: center;line-height: 1.5em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: 100%;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;border-bottom-color: rgb(119, 48, 152);color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: 85%;height: auto;align-items: unset;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: block;font-weight: bold;flex-direction: unset;float: unset;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 10px;padding-left: 0px;padding-right: 0px; text-align: center;text-indent: 0em;text-shadow: none;transform: none;-webkit-box-reflect: unset; "><span leaf="">实践建议</span></span><span style="display: none;"></span></h2> <ol style="list-style-type: decimal;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">CI 集成:</span></strong><span leaf="">自动/手动构建普通+混淆版;</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">**-tiny**</span></code><span leaf="">** 模式:**输出极小可执行文件;</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">安全增强:</span></strong><span leaf="">结合&nbsp;</span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">-ldflags="-s -w"</span></code><span leaf="">&nbsp;及&nbsp;</span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">-trimpath</span></code><span leaf="">&nbsp;清理符号表和绝对路径;</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">高安全需求:</span></strong><span leaf="">实验性开启控制流混淆。</span> </section></li> </ol> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: flex;"><span style="display: none;"></span><span style="font-size: 20px;color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;font-weight: bold;display: block;"><span leaf="">结语</span></span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">Garble 显著增加了反编译和还原成本。然而“混淆 ≠ 绝对安全”,存在如 GoStringUngarbler 工具对抗混淆字面量、或运行时调试绕过的可能。有意对手总有机会,但 Garble 是提升安全的重要一环,适合作为开发和发布流程的“最后一道保护线”。</span></p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <span leaf=""><img class="rich_pages wxw-img" data-imgfileid="100002327" src="/upload/48d34174cc0184a40dc059a554c3d2bd.png" data-type="png" style="display: block;margin-top: 0px;margin-right: auto;margin-bottom: 0px;margin-left: auto;max-width: 100%;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"></span> </figure> <section data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;"> <span style="display: block;color: rgb(0, 0, 0);font-size: 18px;line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: bold;"><span leaf="">参考资料</span></span> </section> <section data-tool="mdnice编辑器" style="margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;"> <span style="display: flex;font-size: 14px;line-height: 1.8em;letter-spacing: 0em;"><span style="line-height: 1.8em;letter-spacing: 0em;color: rgba(0, 0, 0, 0.6);display: inline;width: 10%;background-image: none;background-position-x: initial;background-position-y: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: initial;font-size: 80%;font-family: ptima-Regular, Optima, PingFangSC-light, PingFangTC-light, 'PingFang SC', Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;padding-top: 2px;"><span leaf="">[1]&nbsp;</span></span><p style="text-align: left;text-indent: 0em;color: rgb(0, 0, 0);font-weight: normal;display: inline;padding-top: 0px;padding-right: 0px;padding-bottom: 0px;padding-left: 0px;margin-top: 0px;margin-right: 0px;margin-bottom: 0px;margin-left: 0px;word-break: break-all;flex-basis: 0%;flex-grow: 1;font-size: 14px;line-height: 1.8em;letter-spacing: 0em;"><span leaf="">Garble:&nbsp;</span><em style="margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;color: rgb(0, 0, 0);font-weight: normal;font-style: italic;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">https://github.com/burrowers/garble</span></em></p></span> </section> </section> <section> <span leaf=""><br></span> </section> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>

前端限制用户打开浏览器控制台

作者:微信小助手

<section> <span leaf="">前端代码对于有技术能力的人来说,都是开放的。只要肯下功夫都能获取到业务逻辑代码。因此前端防护只能是增加反编译难度,例如代码混淆,或者防止打开浏览器控制台。今天讲一下目前已知的限制用户打开浏览器控制台。</span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">1、禁用F12和右键</span></span><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">(基础防护)</span></span> </section> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="javascript"><code><span leaf=""><span class="code-snippet__comment">// 禁用右键菜单</span></span></code><code><span leaf=""><span class="code-snippet__variable">document</span>.<span class="code-snippet__title">addEventListener</span>(<span class="code-snippet__string">'contextmenu'</span>,&nbsp;<span class="code-snippet__function"><span class="code-snippet__params">e</span></span><span class="code-snippet__function">&nbsp;=&gt;</span>&nbsp;e.<span class="code-snippet__title">preventDefault</span>());</span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__comment">// 禁用F12、Ctrl+Shift+I等快捷键</span></span></code><code><span leaf=""><span class="code-snippet__variable">document</span>.<span class="code-snippet__title">addEventListener</span>(<span class="code-snippet__string">'keydown'</span>,&nbsp;<span class="code-snippet__function"><span class="code-snippet__params">e</span></span><span class="code-snippet__function">&nbsp;=&gt;</span>&nbsp;{</span></code><code><span leaf="">&nbsp;&nbsp;<span class="code-snippet__keyword">if</span>&nbsp;(e.<span class="code-snippet__property">key</span>&nbsp;===&nbsp;<span class="code-snippet__string">'F12'</span>&nbsp;|| (e.<span class="code-snippet__property">ctrlKey</span>&nbsp;&amp;&amp; e.<span class="code-snippet__property">shiftKey</span>&nbsp;&amp;&amp; e.<span class="code-snippet__property">key</span>&nbsp;===&nbsp;<span class="code-snippet__string">'I'</span>)) {</span></code><code><span leaf="">&nbsp; &nbsp; e.<span class="code-snippet__title">preventDefault</span>();</span></code><code><span leaf="">&nbsp; }</span></code><code><span leaf="">});</span></code></pre> </section> <p style="margin-bottom: 24px;"><span leaf="">❌ 缺点:用户仍可通过浏览器菜单栏打开开发者工具。</span></p> <section data-pm-slice="2 2 []"> <span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">2、</span></span><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">检测窗口变化</span></span> </section> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="javascript"><code><span leaf=""><span class="code-snippet__comment">// 利用窗口大小变化检测DevTools</span></span></code><code><span leaf=""><span class="code-snippet__variable">window</span>.<span class="code-snippet__title">addEventListener</span>(<span class="code-snippet__string">'resize'</span>,&nbsp;<span class="code-snippet__function">() =&gt;</span>&nbsp;{</span></code><code><span leaf="">&nbsp;&nbsp;<span class="code-snippet__keyword">if</span>&nbsp;(<span class="code-snippet__variable">window</span>.<span class="code-snippet__property">outerWidth</span>&nbsp;-&nbsp;<span class="code-snippet__variable">window</span>.<span class="code-snippet__property">innerWidth</span>&nbsp;&gt;&nbsp;<span class="code-snippet__number">100</span>&nbsp;</span></code><code><span leaf="">&nbsp; ||&nbsp;<span class="code-snippet__variable">window</span>.<span class="code-snippet__property">outerHeight</span>&nbsp;-&nbsp;<span class="code-snippet__variable">window</span>.<span class="code-snippet__property">innerHeight</span>&nbsp;&gt;&nbsp;<span class="code-snippet__number">100</span>) {</span></code><code><span leaf="">&nbsp; &nbsp;&nbsp;<span class="code-snippet__title">alert</span>(<span class="code-snippet__string">"检测到开发者工具!"</span>);</span></code><code><span leaf="">&nbsp; &nbsp;&nbsp;<span class="code-snippet__variable">window</span>.<span class="code-snippet__title">close</span>();&nbsp;<span class="code-snippet__comment">// 尝试关闭窗口</span></span></code><code><span leaf="">&nbsp; }</span></code><code><span leaf="">});</span></code></pre> </section> <p node="[object Object]" dir="auto" style="margin-bottom: 0px;margin-top: 0px;" data-pm-slice="0 0 []"><span leaf="">❌&nbsp;</span><strong><span leaf="">缺点</span></strong><span leaf="">:</span></p> <ul style="list-style-type: disc;" class="list-paddingleft-1"> <li><p node="[object Object]" dir="auto" style="margin-bottom: 0px;" data-pm-slice="0 0 []"><span leaf="">全屏切换时的尺寸变化可能被误判;</span></p></li> <li><p node="[object Object]" dir="auto" style="margin-bottom: 24px;" data-pm-slice="0 0 []"><span leaf="">独立打开控制台页面时无法监听到;</span></p></li> </ul> <section data-pm-slice="2 2 []"> <span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">3、</span></span><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">无限Debugger</span></span><span leaf=""><br></span> </section> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="javascript"><code><span leaf=""><span class="code-snippet__built_in">setInterval</span>(<span class="code-snippet__function">() =&gt;</span>&nbsp;{</span></code><code><span leaf="">&nbsp; (<span class="code-snippet__keyword">function</span>&nbsp;(<span class="code-snippet__params">a</span>) {</span></code><code><span leaf="">&nbsp; &nbsp;&nbsp;<span class="code-snippet__keyword">return</span>&nbsp;(<span class="code-snippet__keyword">function</span>&nbsp;(<span class="code-snippet__params">a</span>) {</span></code><code><span leaf="">&nbsp; &nbsp; &nbsp;&nbsp;<span class="code-snippet__keyword">return</span>&nbsp;<span class="code-snippet__title">Function</span>(<span class="code-snippet__string">'Function(arguments[0]+"'</span>&nbsp;+ a +&nbsp;<span class="code-snippet__string">'")()'</span>);</span></code><code><span leaf="">&nbsp; &nbsp; })(a);</span></code><code><span leaf="">&nbsp; })(<span class="code-snippet__string">"bugger"</span>)(<span class="code-snippet__string">"de"</span>,&nbsp;<span class="code-snippet__number">0</span>,&nbsp;<span class="code-snippet__number">0</span>, (<span class="code-snippet__number">0</span>,&nbsp;<span class="code-snippet__number">0</span>));</span></code><code><span leaf="">},&nbsp;<span class="code-snippet__number">1000</span>);</span></code></pre> </section> <p node="[object Object]" dir="auto" style="margin-bottom: 24px;margin-top: 0px;" data-pm-slice="2 4 []"><span leaf="">❌&nbsp;</span><strong><span leaf="">缺点</span></strong><span leaf="">:用户可禁用断点(</span><code><span leaf="">Deactivate breakpoints</span></code><span leaf="">)绕过</span></p> <section data-pm-slice="2 2 []"> <section> <span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">4、检测控制台打开并跳转/弹窗</span></span> </section> </section> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="javascript"><code><span leaf=""><span class="code-snippet__comment">// 利用debugger检测控制台是否打开</span></span></code><code><span leaf=""><span class="code-snippet__built_in">setInterval</span>(<span class="code-snippet__function">() =&gt;</span>&nbsp;{</span></code><code><span leaf="">&nbsp;&nbsp;<span class="code-snippet__keyword">const</span>&nbsp;start =&nbsp;<span class="code-snippet__title">Date</span>.<span class="code-snippet__title">now</span>();</span></code><code><span leaf="">&nbsp;&nbsp;<span class="code-snippet__keyword">debugger</span>;</span></code><code><span leaf="">&nbsp;&nbsp;<span class="code-snippet__keyword">if</span>&nbsp;(<span class="code-snippet__title">Date</span>.<span class="code-snippet__title">now</span>() - start &gt;&nbsp;<span class="code-snippet__number">100</span>) {</span></code><code><span leaf="">&nbsp; &nbsp;&nbsp;<span class="code-snippet__title">alert</span>(<span class="code-snippet__string">"禁止调试!"</span>);</span></code><code><span leaf="">&nbsp; &nbsp;&nbsp;<span class="code-snippet__variable">window</span>.<span class="code-snippet__property">location</span>.<span class="code-snippet__property">href</span>&nbsp;=&nbsp;<span class="code-snippet__string">"about:blank"</span>;&nbsp;<span class="code-snippet__comment">// 跳转空白页</span></span></code><code><span leaf="">&nbsp; }</span></code><code><span leaf="">},&nbsp;<span class="code-snippet__number">1000</span>);</span></code></pre> </section> <p node="[object Object]" dir="auto" style="margin-bottom: 0px;margin-top: 0px;" data-pm-slice="2 2 []"><span leaf="">❌&nbsp;</span><strong><span leaf="">缺点</span></strong><span leaf="">:</span></p> <ul style="list-style-type: disc;" class="list-paddingleft-1"> <li> <section style="margin-bottom: 24px;"> <span leaf="">用户可禁用断点(</span><code><span leaf="">Deactivate breakpoints</span></code><span leaf="">)绕过。</span> </section></li> </ul> <p node="[object Object]" dir="auto" style="margin-bottom: 0px;margin-top: 0px;" data-pm-slice="2 4 []"><span leaf=""><span textstyle="" style="font-size: 18px;font-weight: bold;">优化</span></span></p> <p node="[object Object]" dir="auto" style="margin-bottom: 0px;margin-top: 0px;" data-pm-slice="2 4 []"><span leaf=""><br></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="javascript"><code><span leaf=""><span class="code-snippet__comment">// 利用console.table在控制台打开时耗费时间更长检测控制台是否打开</span></span></code><code><span leaf=""><span class="code-snippet__keyword">function</span>&nbsp;<span class="code-snippet__title">initData</span>() {</span></code><code><span leaf="">&nbsp;&nbsp;<span class="code-snippet__keyword">for</span>&nbsp;(</span></code><code><span leaf="">&nbsp; &nbsp;&nbsp;<span class="code-snippet__keyword">var</span>&nbsp;o = (<span class="code-snippet__keyword">function</span>&nbsp;() {</span></code><code><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span class="code-snippet__keyword">for</span>&nbsp;(<span class="code-snippet__keyword">var</span>&nbsp;w = {}, D =&nbsp;<span class="code-snippet__number">0</span>; D &lt;&nbsp;<span class="code-snippet__number">500</span>; D++) w[<span class="code-snippet__string">""</span>.<span class="code-snippet__title">concat</span>(D)] =&nbsp;<span class="code-snippet__string">""</span>.<span class="code-snippet__title">concat</span>(D);</span></code><code><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span class="code-snippet__keyword">return</span>&nbsp;w;</span></code><code><span leaf="">&nbsp; &nbsp; &nbsp; })(),i = [],c =&nbsp;<span class="code-snippet__number">0</span>;c &lt;&nbsp;<span class="code-snippet__number">50</span>;c++) i.<span class="code-snippet__title">push</span>(o);</span></code><code><span leaf="">&nbsp;&nbsp;<span class="code-snippet__keyword">return</span>&nbsp;i;</span></code><code><span leaf="">}</span></code><code><span leaf=""><span class="code-snippet__keyword">let</span>&nbsp;largeObjectArray =&nbsp;<span class="code-snippet__title">initData</span>()</span></code><code><span leaf=""><span class="code-snippet__built_in">setInterval</span>(<span class="code-snippet__function">() =&gt;</span>&nbsp;{</span></code><code><span leaf="">&nbsp;&nbsp;<span class="code-snippet__keyword">const</span>&nbsp;start =&nbsp;<span class="code-snippet__title">Date</span>.<span class="code-snippet__title">now</span>();</span></code><code><span leaf="">&nbsp;&nbsp;<span class="code-snippet__variable">console</span>.<span class="code-snippet__title">table</span>(largeObjectArray)</span></code><code><span leaf="">&nbsp;&nbsp;<span class="code-snippet__keyword">if</span>&nbsp;(<span class="code-snippet__title">Date</span>.<span class="code-snippet__title">now</span>() - start &gt;&nbsp;<span class="code-snippet__number">100</span>) {</span></code><code><span leaf="">&nbsp; &nbsp;&nbsp;<span class="code-snippet__variable">window</span>.<span class="code-snippet__property">location</span>.<span class="code-snippet__property">href</span>&nbsp;=&nbsp;<span class="code-snippet__string">"about:blank"</span>;&nbsp;<span class="code-snippet__comment">// 跳转空白页</span></span></code><code><span leaf="">&nbsp; }</span></code><code><span leaf="">},&nbsp;<span class="code-snippet__number">1000</span>);</span></code></pre> </section> <p node="[object Object]" dir="auto" style="margin-bottom: 0px;margin-top: 0px;" data-pm-slice="2 4 []"><span leaf="">❌&nbsp;</span><strong><span leaf="">缺点</span></strong><span leaf="">:</span></p> <ul style="list-style-type: disc;" class="list-paddingleft-1"> <li> <section style="margin-bottom: 24px;"> <span leaf="">用户可重写console.table方法跳过。</span> </section></li> </ul> <section style="margin-bottom:24px;"> <span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">结语</span></span> </section> <p><span leaf="">网站安全不能只依赖前端技术,前端只能“</span><span leaf="" data-pm-slice="1 1 [" para,{tagname:p,attributes:{},namespaceuri:http: www.w3.org 1999 xhtml}]>防君子不防小人</span><span leaf="">”。有一定技术能力的用户都可以绕过前端防护,并反编译前端代码。还是得靠后端服务来确保网站的安全。</span></p> <section class="mp_profile_iframe_wrp" nodeleaf=""> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-nickname="焚心小记" data-from="0" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/yrG4X0r4SEEcn9ByGFRD28YuQaNHS9cib0D8Ercia07LJNM67cKXVwBNtQiaum0VIROqK0Cf8UgbeDPCCdClQGmMw/0?wx_fmt=png" data-signature="人生无时不在焚心,无非是文火与武火的区别罢了。给生活留下点痕迹,给自己留下点回忆。" data-id="MzA5NDc4ODA2Mg==" data-is_biz_ban="0" data-service_type="1" data-verify_status="0"></mp-common-profile> </section> <p><span leaf="">关注公众号,获取更多前端技术问题。动动小手,点个赞吧</span></p> <section style="text-align: center;" nodeleaf=""> <img class="rich_pages wxw-img" data-imgfileid="100000531" data-ratio="1.0085836909871244" src="/upload/cbb0988170d4360edf577fc54e505285.png" data-type="gif" data-w="233" type="block"> </section> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>

再见 Cursor,从0到1用上Claude Code后,惊呼这才是生产力工具|保姆级教程

作者:微信小助手

<p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px; data-pm-slice="0 0 []"><span style="color: rgb(31, 35, 41);"><span leaf="">最近,为了给我的一个AI项目做功能升级,我算是把Cursor给“盘”明白了。但说实话,越用越觉得有点“不得劲”。</span></span></p> <section class="mp_profile_iframe_wrp" nodeleaf=""> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-nickname="饼干哥哥AGI" data-alias="BingGanGeGeData" data-from="0" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/RVqfiaDPokvtvAI83ogWKibFMKVghWkyKDyKyfribz2gvQwIz7Y9ibU207DLiaZU9WnBAXoUajibzMxeBviboLDhcVJvg/0?wx_fmt=png" data-signature="数据分析师,分享 AI在实际业务中落地的应用经验。" data-id="MjM5NDI4MTY3NA==" data-is_biz_ban="0" data-service_type="1" data-verify_status="0"></mp-common-profile> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">一个不是很复杂的功能,在Cursor里,这事儿就变得特别“拧巴”:我得手动@一堆相关文件,一遍遍地跟它解释上下文,结果AI还是经常“跑偏”,改出来的代码要么不符合项目原有的设计模式,要么就直接引入新bug。</span></span></p> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">折腾了两周,我感觉自己不是在用AI提效,而是在给AI“擦屁股”,效率没提上来,人先“红温”了。</span></span></p> <section style="text-align: center;" nodeleaf=""> <img src="/upload/1fc7388b2ae683d1bb59337b4265c32c.png" class="rich_pages wxw-img" data-ratio="1" data-s="300,640" data-type="png" data-w="1024" type="block" data-imgfileid="110009916"> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">这时我想起了 Claude Code,一直听说它是最强 AI 编程,但我一直没空去用。这次决定试下。</span></span></p> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span leaf=""><br></span></p> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">不试不知道,一试吓一跳!</span></span></p> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">先说结论,</span></span><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">Cursor和Claude Code,根本就是两种完全不同的开发哲学。</span></span></p> <ul style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;color: rgb(20, 86, 240);font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;line-height: 30px;padding-left: 20px; class="list-paddingleft-1"> <li style="text-align: left;"><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">Cursor是“辅助编码”</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">:你依然是主导者,AI是你手里的“锤子”,你需要精确地告诉它敲哪里。</span></span></li> <li style="text-align: left;"><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">Claude Code是“代理式开发”</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">:你更像个“项目经理”,提出目标后,AI会自己变成一个“开发团队”,自主完成规划和执行。</span></span></li> </ul> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span leaf=""><br></span></p> <section style="font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;border-left: 3px solid rgb(187, 191, 196);padding: 0px 4px 12px;margin-bottom: 12px;color: rgb(31, 35, 41); data-pm-slice="0 0 []"> <p data-author="dui!" style="font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">对了,很多人会对 CC 的昂贵吓退,别担心接下来会介绍如何<span textstyle="" style="color: rgb(217, 33, 66);font-weight: bold;text-decoration: underline;">白嫖 100 美金额度</span>,先让你免费用爽。</span></span></p> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">今天,我们就来彻底搞懂Claude Code。从</span></span><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">保姆级的安装配置教程</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">,到</span></span><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">核心功能的深度解析</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">,再到一个</span></span><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">完整的实战案例</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">,带你一步一步,搞懂这个当下最强的 AI 编程工具。</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/34a4c1403f189d0c232dcf3131ae6b24.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.42685185185185187" data-type="png" data-w="1080" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009884"> </section> <h2 style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span leaf="" style="color: rgb(31, 35, 41);"><br></span></h2> <h2 style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-weight: bold;color: rgb(31, 35, 41);font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;letter-spacing: 0.578px;margin-top: 0px;margin-bottom: 8px;font-size: 22px;padding-bottom: 12px;><span style="color: rgb(31, 35, 41);"><span leaf="">安装与配置:保姆级教程</span></span></h2> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">要使用 Claude Code,必须确保本地环境满足其运行要求,并完成必要的配置。以下是确保您顺利安装并运行的完整步骤。</span></span></p> <h3 style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-weight: bold;color: rgb(31, 35, 41);font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;letter-spacing: 0.578px;margin-top: 0px;margin-bottom: 8px;font-size: 20px;padding-bottom: 12px;><span style="color: rgb(31, 35, 41);"><span leaf="">第一步:环境准备 (Node.js)</span></span></h3> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">Claude Code 依赖于 Node.js 环境。请确保您的系统中已安装 Node.js 18 或更高版本。</span></span></p> <ol style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;list-style: none;color: rgb(20, 86, 240);font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;line-height: 30px;padding-left: 0px; class="list-paddingleft-1"> <li> <section> <span leaf="">1.&nbsp;</span><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">安装 Node.js</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">:</span></span> </section></li> </ol> <section> <span style="color: rgb(31, 35, 41);font-family: " pingfang sc, system-ui, -apple-system, system-ui, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; data-pm-slice="0 0 []"><span leaf="">访问Node.js 官方网站</span></span><span style="color: rgb(31, 35, 41);font-family: " pingfang sc, system-ui, -apple-system, system-ui, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;padding: 1px 2px;background-color: rgb(245, 246, 247);border: solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;><span leaf="">https://nodejs.org/en/download/current</span></span><span style="color: rgb(31, 35, 41);font-family: " pingfang sc, system-ui, -apple-system, system-ui, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">,下载并安装适用于您操作系统的 LTS (长期支持) 版本。</span></span> </section> <ol style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;list-style: none;color: rgb(20, 86, 240);font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;line-height: 30px;padding-left: 0px; class="list-paddingleft-1"> <li> <section> <span leaf="">2.&nbsp;</span><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">验证安装</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">:</span></span> </section></li> </ol> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">在终端中输入以下命令,如果能正确返回版本号,则表示安装成功。</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;padding-left: 25px;> <section style="margin-top: 12px;background-color: rgb(40, 44, 52);margin-bottom: 12px;border-radius: 5px;"> <section> <span style="display: block;height: 30px;background-color: rgb(40, 44, 52);border-top-left-radius: 5px;border-top-right-radius: 5px;margin: 0px;color: rgb(0, 0, 0);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;"><span data-cacheurl="" data-remoteid="" style="height: 30px;line-height: 30px;margin-left: 10px;display: block;background: none left center / auto 14px no-repeat;background-image: url(" https: mmbiz.qpic.cn sz_mmbiz_png rvqfiadpokvskibticsxxuktzi0gmviad0mgujlnrumqeicgdbiccuablyqgcwfibmntozxaleh4k57qicciapzpa0hcbfa 640?wx_fmt="png&amp;from=appmsg&quot;);&quot;"></span></span> </section> <pre style="margin: 0px;"><code style="color: rgb(171, 178, 191);background: rgb(40, 44, 52);padding: 4px 15px 15px;display: block;overflow-x: auto;border-bottom-left-radius: 5px;border-bottom-right-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;font-size: 14px;line-height: 1.5;"><span leaf="">node --version</span></code></pre> </section> </section> <section style="font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;border-left: 3px solid rgb(187, 191, 196);padding: 0px 4px 12px;margin-bottom: 12px;color: rgb(31, 35, 41);> <p data-author="dui!" style="font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">注意</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">:对于 Windows 用户,Claude Code 需要在 Windows Subsystem for Linux (WSL) 环境中运行。请先安装并配置好 WSL。</span></span></p> </section> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/90540a3f1901412ed36f99696000e4c4.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.275" data-type="png" data-w="1080" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009883"> </section> <h3 style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-weight: bold;color: rgb(31, 35, 41);font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;letter-spacing: 0.578px;margin-top: 0px;margin-bottom: 8px;font-size: 20px;padding-bottom: 12px;><span style="color: rgb(31, 35, 41);"><span leaf="">第二步:安装 Claude Code</span></span></h3> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">通过 npm (Node.js 包管理器) 全局安装 Claude Code。</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;margin-top: 12px;background-color: rgb(40, 44, 52);margin-bottom: 12px;border-radius: 5px;> <section> <span style="display: block;height: 30px;background-color: rgb(40, 44, 52);border-top-left-radius: 5px;border-top-right-radius: 5px;margin: 0px;color: rgb(0, 0, 0);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;"><span data-cacheurl="" data-remoteid="" style="height: 30px;line-height: 30px;margin-left: 10px;display: block;background: none left center / auto 14px no-repeat;background-image: url(" https: mmbiz.qpic.cn sz_mmbiz_png rvqfiadpokvskibticsxxuktzi0gmviad0mgujlnrumqeicgdbiccuablyqgcwfibmntozxaleh4k57qicciapzpa0hcbfa 640?wx_fmt="png&amp;from=appmsg&quot;);&quot;"></span></span> </section> <pre style="margin: 0px;"><code style="color: rgb(171, 178, 191);background: rgb(40, 44, 52);padding: 4px 15px 15px;display: block;overflow-x: auto;border-bottom-left-radius: 5px;border-bottom-right-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;font-size: 14px;line-height: 1.5;"><span leaf="">npm install -g @anthropic-ai/claude-code</span></code></pre> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">安装完成后,通过以下命令验证:</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;margin-top: 12px;background-color: rgb(40, 44, 52);margin-bottom: 12px;border-radius: 5px;> <section> <span style="display: block;height: 30px;background-color: rgb(40, 44, 52);border-top-left-radius: 5px;border-top-right-radius: 5px;margin: 0px;color: rgb(0, 0, 0);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;"><span data-cacheurl="" data-remoteid="" style="height: 30px;line-height: 30px;margin-left: 10px;display: block;background: none left center / auto 14px no-repeat;background-image: url(" https: mmbiz.qpic.cn sz_mmbiz_png rvqfiadpokvskibticsxxuktzi0gmviad0mgujlnrumqeicgdbiccuablyqgcwfibmntozxaleh4k57qicciapzpa0hcbfa 640?wx_fmt="png&amp;from=appmsg&quot;);&quot;"></span></span> </section> <pre style="margin: 0px;"><code style="color: rgb(171, 178, 191);background: rgb(40, 44, 52);padding: 4px 15px 15px;display: block;overflow-x: auto;border-bottom-left-radius: 5px;border-bottom-right-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;font-size: 14px;line-height: 1.5;"><span leaf="">claude --version</span></code></pre> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">成功安装将显示具体的版本号。</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/9e32ee2adb176c35afd8bae6b2f065ae.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.2518939393939394" data-type="png" data-w="1056" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009880"> </section> <h3 style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-weight: bold;color: rgb(31, 35, 41);font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;letter-spacing: 0.578px;margin-top: 0px;margin-bottom: 8px;font-size: 20px;padding-bottom: 12px;><span style="color: rgb(31, 35, 41);"><span leaf="">第三步:首次运行与账户配置</span></span></h3> <ol style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;list-style: none;color: rgb(20, 86, 240);font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;line-height: 30px;padding-left: 0px; class="list-paddingleft-1"> <li style="text-align: left;"> <section> <span leaf="">1.&nbsp;</span><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">启动 Claude Code</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">: 在您的项目目录或任意位置的终端中,输入&nbsp;</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">claude</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">&nbsp;命令。</span></span> </section></li> </ol> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: left;margin-top: 12px;background-color: rgb(40, 44, 52);margin-bottom: 12px;border-radius: 5px;> <section> <span style="display: block;height: 30px;background-color: rgb(40, 44, 52);border-top-left-radius: 5px;border-top-right-radius: 5px;margin: 0px;color: rgb(0, 0, 0);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;"><span data-cacheurl="" data-remoteid="" style="height: 30px;line-height: 30px;margin-left: 10px;display: block;background: none left center / auto 14px no-repeat;background-image: url(" https: mmbiz.qpic.cn sz_mmbiz_png rvqfiadpokvskibticsxxuktzi0gmviad0mgujlnrumqeicgdbiccuablyqgcwfibmntozxaleh4k57qicciapzpa0hcbfa 640?wx_fmt="png&amp;from=appmsg&quot;);&quot;"></span></span> </section> <pre style="margin: 0px;"><code style="color: rgb(171, 178, 191);background: rgb(40, 44, 52);padding: 4px 15px 15px;display: block;overflow-x: auto;border-bottom-left-radius: 5px;border-bottom-right-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;font-size: 14px;line-height: 1.5;"><span leaf="">claude</span></code></pre> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">首先会让你选择一个主题,下面</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">Preview</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">是主题的预览</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/431167d8e01dd2ed81608b5c5e4099c3.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.6518518518518519" data-type="png" data-w="1080" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009881"> </section> <ol style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;list-style: none;color: rgb(20, 86, 240);font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;line-height: 30px;padding-left: 0px; class="list-paddingleft-1"> <li style="text-align: left;"> <section> <span leaf="">2.&nbsp;</span><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">账户登录与授权</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">: 首次运行时,Claude Code 会引导您进行配置。它支持两种主要的登录方式:</span></span> </section></li> </ol> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/7d12534e55be0d405be8a87af9dc4bb0.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.3333333333333333" data-type="png" data-w="1080" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009882"> </section> <ul style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;color: rgb(20, 86, 240);font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;line-height: 30px;padding-left: 20px; class="list-paddingleft-1"> <li style="text-align: left;"><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">Claude account with subscription</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">: 使用您订阅了 Pro 或 Max 套餐的 Claude 网页端账户。这是性价比最高的方案,费用固定可预测。</span></span></li> <li style="text-align: left;"><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">Anthropic Console account</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">: 使用 Anthropic API 开发者账户,按 token 使用量计费。</span></span></li> </ul> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/991d8201b53ba32943c36d1769a90fb9.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.4666666666666667" data-type="png" data-w="1080" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009887"> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">选择后者,</span></span><span style="font-weight: bold;text-decoration: underline;color: rgb(216, 57, 49);"><span leaf="">后面介绍白嫖 100 美金额度的方法 ⬇️</span></span></p> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span leaf=""><br></span></p> <ol style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;list-style: none;color: rgb(20, 86, 240);font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;line-height: 30px;padding-left: 0px; class="list-paddingleft-1"> <li> <section> <span leaf="">3.&nbsp;</span><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">切换至项目路径</span></span> </section></li> </ol> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">因为我是直接打开 Terminal,claude 提醒我这是 home 文件夹,让我切换到项目文件夹下,这样比较好管理文件。</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/0ea39e8a14b71a716f59ada7cbd81040.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.4666666666666667" data-type="png" data-w="1080" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009885"> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">怎么做呢?用</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">cd</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">命令,这是切换当前路径的命令</span></span></p> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">重新打开 Terminal,输入&nbsp;</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">cd&nbsp;</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">注意后面有个空格,然后把新建好的文件夹拖进去</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/76c68da4e4ec6212d7ca57f68fd8de74.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.3490740740740741" data-type="png" data-w="1080" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009889"> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">如下图,就看到我们切换到了文件夹</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">claudecodetest</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">里了</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/65129d59c66624be2ec89b6c5c650c13.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.6509259259259259" data-type="png" data-w="1080" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009886"> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span leaf=""><br></span></p> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span leaf=""><br></span></p> <ol style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;list-style: none;color: rgb(20, 86, 240);font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;line-height: 30px;padding-left: 0px; class="list-paddingleft-1"> <li> <section> <span leaf="">4.&nbsp;</span><span style="font-weight: bold;color: rgb(216, 57, 49);"><span leaf="">白嫖 100 美金 API 额度</span></span> </section></li> </ol> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">国内API 中转站</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">Any Router</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">&nbsp;现在搞活动,新人注册就送100美金额度。</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/f88065d3ee927ea48f061e919ef4ebe3.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.9851851851851852" data-type="png" data-w="1080" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009888"> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">打开链接</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">https://anyrouter.top/register?aff=Wmh1</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">,用 github 登录就行。</span></span></p> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(216, 57, 49);"><span leaf="">注意一定要用我的这个邀请链接来注册才有额度赠送。</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/4869b10e16818952e85b5b03bf42e130.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.5161290322580645" data-type="png" data-w="1054" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009894"> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">注册完就能看到了。</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/a01e549d8237e751a6912422737b9d22.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.5022488755622189" data-type="png" data-w="667" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009890"> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span leaf=""><br></span></p> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">新建 Token</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/e1f503fe70c7c9e2c0b861da2f22fb6c.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.5108481262327417" data-type="png" data-w="1014" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009892"> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">建议设置成</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">无限额度</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/ea6a886556fe9e07bd39f9374a61c024.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.8296296296296296" data-type="png" data-w="1080" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009895"> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">配置好模型,可以只用 claude4,怕额度不够的就把 3.7 加上</span></span></p> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">毕竟我们要用到 Claude Code 的都是比较复杂的需求,尽量就不用 3.5 了</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/086e01acb9bf740852be0f6b2059caaf.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.48703703703703705" data-type="png" data-w="1080" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009893"> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span leaf=""><br></span></p> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">回到终端 Terminal,先退出Claude Code ,输入以下配置</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: left;margin-top: 12px;background-color: rgb(40, 44, 52);margin-bottom: 12px;border-radius: 5px;> <section> <span style="display: block;height: 30px;background-color: rgb(40, 44, 52);border-top-left-radius: 5px;border-top-right-radius: 5px;margin: 0px;color: rgb(0, 0, 0);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;"><span data-cacheurl="" data-remoteid="" style="height: 30px;line-height: 30px;margin-left: 10px;display: block;background: none left center / auto 14px no-repeat;background-image: url(" https: mmbiz.qpic.cn sz_mmbiz_png rvqfiadpokvskibticsxxuktzi0gmviad0mgujlnrumqeicgdbiccuablyqgcwfibmntozxaleh4k57qicciapzpa0hcbfa 640?wx_fmt="png&amp;from=appmsg&quot;);&quot;"></span></span> </section> <pre style="margin: 0px;"><code style="color: rgb(171, 178, 191);background: rgb(40, 44, 52);padding: 4px 15px 15px;display: block;overflow-x: auto;border-bottom-left-radius: 5px;border-bottom-right-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;font-size: 14px;line-height: 1.5;"><span leaf=""># 设置 API 密钥</span><span leaf=""><br></span><span leaf="">export ANTHROPIC_AUTH_TOKEN=sk-...【这里填你刚才新建的 Token】</span><span leaf=""><br></span><span leaf=""># 设置代理服务器地址</span><span leaf=""><br></span><span leaf="">export ANTHROPIC_BASE_URL=https://anyrouter.top</span><span leaf=""><br></span><span leaf=""># 重新启动 claude</span><span leaf=""><br></span><span leaf="">claude</span></code></pre> </section> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/21187bb4f5216cee784d30acaf0b7339.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.5009259259259259" data-type="png" data-w="1080" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009899"> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">看到这里显示我们自己设置的中转地址就证明成功了。</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/e81666d4e1cfb771c936a1faa6d31060.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.5851851851851851" data-type="png" data-w="1080" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009898"> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;text-align: left;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">为避免每次都需手动设置,可将&nbsp;</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">export</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">&nbsp;命令添加到您的终端配置文件中(如&nbsp;</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">.bashrc</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">&nbsp;或&nbsp;</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">.zshrc</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">)。</span></span></p> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">参考:</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;margin-top: 12px;background-color: rgb(40, 44, 52);margin-bottom: 12px;border-radius: 5px;> <section> <span style="display: block;height: 30px;background-color: rgb(40, 44, 52);border-top-left-radius: 5px;border-top-right-radius: 5px;margin: 0px;color: rgb(0, 0, 0);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;"><span data-cacheurl="" data-remoteid="" style="height: 30px;line-height: 30px;margin-left: 10px;display: block;background: none left center / auto 14px no-repeat;background-image: url(" https: mmbiz.qpic.cn sz_mmbiz_png rvqfiadpokvskibticsxxuktzi0gmviad0mgujlnrumqeicgdbiccuablyqgcwfibmntozxaleh4k57qicciapzpa0hcbfa 640?wx_fmt="png&amp;from=appmsg&quot;);&quot;"></span></span> </section> <pre style="margin: 0px;"><code style="color: rgb(171, 178, 191);background: rgb(40, 44, 52);padding: 4px 15px 15px;display: block;overflow-x: auto;border-bottom-left-radius: 5px;border-bottom-right-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;font-size: 14px;line-height: 1.5;"><span style="color: rgb(230, 192, 123);"><span leaf="">echo</span></span><span leaf="">&nbsp;-e&nbsp;</span><span style="color: rgb(152, 195, 121);"><span leaf="">'\n export ANTHROPIC_AUTH_TOKEN=sk-...'</span></span><span leaf="">&nbsp;&gt;&gt; ~/.bash_profile</span><span leaf=""><br></span><span style="color: rgb(230, 192, 123);"><span leaf="">echo</span></span><span leaf="">&nbsp;-e&nbsp;</span><span style="color: rgb(152, 195, 121);"><span leaf="">'\n export ANTHROPIC_BASE_URL=https://anyrouter.top'</span></span><span leaf="">&nbsp;&gt;&gt; ~/.bash_profile</span><span leaf=""><br></span><span style="color: rgb(230, 192, 123);"><span leaf="">echo</span></span><span leaf="">&nbsp;-e&nbsp;</span><span style="color: rgb(152, 195, 121);"><span leaf="">'\n export ANTHROPIC_AUTH_TOKEN=sk-...'</span></span><span leaf="">&nbsp;&gt;&gt; ~/.bashrc</span><span leaf=""><br></span><span style="color: rgb(230, 192, 123);"><span leaf="">echo</span></span><span leaf="">&nbsp;-e&nbsp;</span><span style="color: rgb(152, 195, 121);"><span leaf="">'\n export ANTHROPIC_BASE_URL=https://anyrouter.top'</span></span><span leaf="">&nbsp;&gt;&gt; ~/.bashrc</span><span leaf=""><br></span><span style="color: rgb(230, 192, 123);"><span leaf="">echo</span></span><span leaf="">&nbsp;-e&nbsp;</span><span style="color: rgb(152, 195, 121);"><span leaf="">'\n export ANTHROPIC_AUTH_TOKEN=sk-...'</span></span><span leaf="">&nbsp;&gt;&gt; ~/.zshrc</span><span leaf=""><br></span><span style="color: rgb(230, 192, 123);"><span leaf="">echo</span></span><span leaf="">&nbsp;-e&nbsp;</span><span style="color: rgb(152, 195, 121);"><span leaf="">'\n export ANTHROPIC_BASE_URL=https://anyrouter.top'</span></span><span leaf="">&nbsp;&gt;&gt; ~/.zshrc</span></code></pre> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span leaf=""><br></span></p> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">⚠️ 踩坑经验:</span></span></p> <ol style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;list-style: none;color: rgb(20, 86, 240);font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;line-height: 30px;padding-left: 0px; class="list-paddingleft-1"> <li> <section> <span leaf="">1.&nbsp;</span><span style="color: rgb(31, 35, 41);"><span leaf="">注意,据说 Any Router 会收集使用的数据,所以才这么低价;确保大家只是在做案例或者测试的时候使用,不要涉及个人信息</span></span> </section></li> <li> <section> <span leaf="">2.&nbsp;</span><span style="color: rgb(31, 35, 41);"><span leaf="">想用第三方 API 中转的话,需要提前先在 Claude Code 里退出登录</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">/log out</span></span> </section></li> </ol> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span leaf=""><br></span></p> <h3 style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-weight: bold;color: rgb(31, 35, 41);font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;letter-spacing: 0.578px;margin-top: 0px;margin-bottom: 8px;font-size: 20px;padding-bottom: 12px;><span style="color: rgb(31, 35, 41);"><span leaf="">第四步:IDE 集成与优化</span></span></h3> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">Claude Code 能与主流 IDE 无缝集成,实现终端与图形化界面的联动。</span></span></p> <ul style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;color: rgb(20, 86, 240);font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;line-height: 30px;padding-left: 20px; class="list-paddingleft-1"> <li style="text-align: left;"><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">VS Code &amp; JetBrains IDEs</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">: 在 IDE 内置的终端中首次运行&nbsp;</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">claude</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">,它会自动提示并安装相应的插件。安装后,您可以通过快捷键&nbsp;</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">Command + ESC</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">&nbsp;(macOS) 或&nbsp;</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">Ctrl + ESC</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">&nbsp;(Windows/Linux) 快速唤出 Claude Code 面板。</span></span></li> <li style="text-align: left;"><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">差异查看器</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">: 当 Claude Code 修改代码时,它能调用 IDE 的 diff 工具来可视化变更。通过&nbsp;</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">/config</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">&nbsp;命令将&nbsp;</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">diffTool</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">&nbsp;设置为&nbsp;</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">auto</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">&nbsp;即可启用此功能。</span></span></li> </ul> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span leaf=""><br></span></p> <h3 style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-weight: bold;color: rgb(31, 35, 41);font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;letter-spacing: 0.578px;margin-top: 0px;margin-bottom: 8px;font-size: 20px;padding-bottom: 12px;><span style="color: rgb(31, 35, 41);"><span leaf="">常用斜杠命令</span></span></h3> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">斜杠命令</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">/</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">是与 Claude Code 交互的主要方式</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/f23758f78863dcc5d848c81861b3b1d9.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.30092592592592593" data-type="png" data-w="1080" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009897"> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">以下是部分核心命令的摘要:</span></span></p> <section style="text-align: center;" nodeleaf=""> <img src="/upload/43d8144dfc3a5d55463f635215f8aa27.png" class="rich_pages wxw-img" data-ratio="0.4425925925925926" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="110009917"> </section> <h3 style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-weight: bold;color: rgb(31, 35, 41);font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;letter-spacing: 0.578px;margin-top: 0px;margin-bottom: 8px;font-size: 20px;padding-bottom: 12px;><span style="color: rgb(31, 35, 41);"><span leaf="">核心特性解析</span></span></h3> <ul style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;color: rgb(20, 86, 240);font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;line-height: 30px;padding-left: 20px; class="list-paddingleft-1"> <li style="text-align: left;"><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">上下文记忆 (</span></span><span style="color: rgb(31, 35, 41);font-weight: bold;padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">CLAUDE.md</span></span><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">)</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">: 这是一个特殊的 Markdown 文件,您可以在其中定义项目的高级规则、编码规范、技术栈偏好等。Claude Code 在每次对话开始时都会读取此文件,作为其行动的“最高指示”,这能显著提升其输出的准确性和一致性。</span></span></li> <li style="text-align: left;"><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">图像识别</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">: 对于前端开发或 UI 调试尤其有用。您可以直接将 UI 截图、设计稿或包含错误的界面截图粘贴到终端中(使用&nbsp;</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">Ctrl+V</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">),并向其提问,例如:“请用 HTML 和 CSS 实现这个设计”或“分析这个截图中的错误原因”。</span></span></li> <li style="text-align: left;"><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">深度思考模式</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">: 当面临复杂任务时,可以使用&nbsp;</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">think</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">、</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">think harder</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">&nbsp;或&nbsp;</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">ultrathink</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">&nbsp;等关键词来引导模型进行更深层次的规划和思考。</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">ultrathink</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">&nbsp;消耗的 token 最多,但规划也最为详尽。</span></span></li> <li style="text-align: left;"><span style="color: rgb(31, 35, 41);font-weight: bold;"><span leaf="">模型上下文协议 (MCP)</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">: MCP 是一种开放标准,允许 AI 代理调用外部工具。例如,通过安装&nbsp;</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">XcodeBuildMCP</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">&nbsp;可以让 Claude Code 更好地构建和测试 iOS/macOS 应用;安装&nbsp;</span></span><span style="color: rgb(31, 35, 41);padding: 1px 2px;background-color: rgb(245, 246, 247);border: 1px solid rgb(222, 224, 227);border-radius: 4px;margin: 0px 3px;"><span leaf="">browsermcp</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">&nbsp;则能增强其与浏览器交互以进行网站开发的能力。</span></span></li> </ul> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span leaf=""><br></span></p> <h2 style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-weight: bold;color: rgb(31, 35, 41);font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;letter-spacing: 0.578px;margin-top: 0px;margin-bottom: 8px;font-size: 22px;padding-bottom: 12px;><span style="color: rgb(31, 35, 41);"><span leaf="">实战演练:从 0到一添加新功能</span></span></h2> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">光说不练假把式,我们拿个简单项目来实操一下 Claude Code,并在此过程中应用多个核心命令。</span></span></p> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">正好前段时间用扣子空间做了一期从 0 到 1 打造出海 APP 原型的内容</span></span><span style="color: rgb(31, 35, 41);"> <svg style="top: 1px;margin-right:2px;" width="1em" height="1em" viewbox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" data-icon="FileLinkWordOutlined"> <path d="M4 3h12.595c.93 0 1.806.355 2.439.96A3.07 3.07 0 0 1 20 6.176V21H7.405a3.53 3.53 0 0 1-2.439-.96A3.068 3.068 0 0 1 4 17.823V3ZM3 1a1 1 0 0 0-1 1v15.823c0 1.373.57 2.69 1.583 3.66A5.529 5.529 0 0 0 7.405 23H21a1 1 0 0 0 1-1V6.176a5.07 5.07 0 0 0-1.583-3.66A5.53 5.53 0 0 0 16.595 1H3Z" fill="currentColor"></path><path d="M6.75 8a1 1 0 0 1 1-1h8.5a1 1 0 1 1 0 2h-8.5a1 1 0 0 1-1-1Zm0 4a1 1 0 0 1 1-1h8.5a1 1 0 1 1 0 2h-8.5a1 1 0 0 1-1-1Zm0 4a1 1 0 0 1 1-1h4.5a1 1 0 1 1 0 2h-4.5a1 1 0 0 1-1-1Z" fill="currentColor"></path> </svg><span leaf=""><a class="normal_text_link" target="_blank" style="" href="https://mp.weixin.qq.com/s?__biz=MjM5NDI4MTY3NA==&amp;mid=2257493311&amp;idx=1&amp;sn=86c6a0e703eba8d408d2eee33f2e9748&amp;scene=21#wechat_redirect" textvalue="从0到1,我如何用“扣子空间”攻克本土化难题,为我的智能猫砂盆打造出海APP原型" data-itemshowtype="11" linktype="text" data-linktype="2">从0到1,我如何用“扣子空间”攻克本土化难题,为我的智能猫砂盆打造出海APP原型</a>,为我的智能猫砂盆打造出海APP原型</span></span><span style="color: rgb(31, 35, 41);"><span leaf="">,但说实话效果不是很满意,刚好这会拿 CC 来跑跑看。</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/60d66d8e2ea9723991a3d30333fee706.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.812962962962963" data-type="png" data-w="1080" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009900"> </section> <h3 style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-weight: bold;color: rgb(31, 35, 41);font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;letter-spacing: 0.578px;margin-top: 0px;margin-bottom: 8px;font-size: 20px;padding-bottom: 12px;><span style="color: rgb(31, 35, 41);"><span leaf=""><br></span></span></h3> <h3 style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-weight: bold;color: rgb(31, 35, 41);font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;letter-spacing: 0.578px;margin-top: 0px;margin-bottom: 8px;font-size: 20px;padding-bottom: 12px;><span style="color: rgb(31, 35, 41);"><span leaf="">第一步:理解现有项目</span></span></h3> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px; data-pm-slice="3 1 []"><span style="color: rgb(31, 35, 41);"><span leaf="">先把产品开发需求文档扔到项目文件夹里</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/4bc7e9873b19a4071aef10e9af7eb5a1.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.5127701375245579" data-type="png" data-w="1018" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009896"> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">然后让它阅读文档,搞清楚我们现在要干嘛,同时也测一下 Claude Code 是否能跑通?</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;margin-top: 12px;background-color: rgb(40, 44, 52);margin-bottom: 12px;border-radius: 5px;> <section> <span style="display: block;height: 30px;background-color: rgb(40, 44, 52);border-top-left-radius: 5px;border-top-right-radius: 5px;margin: 0px;color: rgb(0, 0, 0);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;"><span data-cacheurl="" data-remoteid="" style="height: 30px;line-height: 30px;margin-left: 10px;display: block;background: none left center / auto 14px no-repeat;background-image: url(" https: mmbiz.qpic.cn sz_mmbiz_png rvqfiadpokvskibticsxxuktzi0gmviad0mgujlnrumqeicgdbiccuablyqgcwfibmntozxaleh4k57qicciapzpa0hcbfa 640?wx_fmt="png&amp;from=appmsg&quot;);&quot;"></span></span> </section> <pre style="margin: 0px;"><code style="color: rgb(171, 178, 191);background: rgb(40, 44, 52);padding: 4px 15px 15px;display: block;overflow-x: auto;border-bottom-left-radius: 5px;border-bottom-right-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;font-size: 14px;line-height: 1.5;"><span leaf="">阅读当前项目的产品开发需求文档,搞清楚需要开发什么样的 app 产品原型 html</span></code></pre> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">OK,跑起来了,可以看到 Claude Code调用了工具来做查找文档然后分析</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/d7e673bb18155e7cc4a42ebe7981bd3d.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.6129629629629629" data-type="png" data-w="1080" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009904"> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span leaf=""><br></span></p> <h3 style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-weight: bold;color: rgb(31, 35, 41);font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;letter-spacing: 0.578px;margin-top: 0px;margin-bottom: 8px;font-size: 20px;padding-bottom: 12px;><span style="color: rgb(31, 35, 41);"><span leaf="">第二步:直接跑</span></span></h3> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">直接把这段生成 APP 原型的提示词复制黏贴进去:</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;margin-top: 12px;background-color: rgb(40, 44, 52);margin-bottom: 12px;border-radius: 5px;> <section> <span style="display: block;height: 30px;background-color: rgb(40, 44, 52);border-top-left-radius: 5px;border-top-right-radius: 5px;margin: 0px;color: rgb(0, 0, 0);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;"><span data-cacheurl="" data-remoteid="" style="height: 30px;line-height: 30px;margin-left: 10px;display: block;background: none left center / auto 14px no-repeat;background-image: url(" https: mmbiz.qpic.cn sz_mmbiz_png rvqfiadpokvskibticsxxuktzi0gmviad0mgujlnrumqeicgdbiccuablyqgcwfibmntozxaleh4k57qicciapzpa0hcbfa 640?wx_fmt="png&amp;from=appmsg&quot;);&quot;"></span></span> </section> <pre style="margin: 0px;"><code style="color: rgb(171, 178, 191);background: rgb(40, 44, 52);padding: 4px 15px 15px;display: block;overflow-x: auto;border-bottom-left-radius: 5px;border-bottom-right-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;font-size: 14px;line-height: 1.5;"><span leaf="">接下来更进一步,请根据需求文档以及以下的要求,运用你全部的专业知识和创造力,创作一个单页HTML网页:展示一套功能完善、视觉出众的高保真交互原型。</span><span leaf=""><br></span><span leaf=""><br></span><span leaf="">直接输出完整HTML,不需要前后置引导语。</span><span leaf=""><br></span><span leaf=""><br></span><span leaf="">现在需要输出高保真的原型图,请通过以下方式帮我完成所有界面的原型设计,并确保这些原型界面可以直接用于开发:</span><span leaf=""><br></span><span leaf="">1、用户体验分析:先分析这个 App 的主要功能和用户需求,确定核心交互逻辑。</span><span leaf=""><br></span><span leaf="">2、产品界面规划:作为产品经理,定义关键界面,确保信息架构合理。</span><span leaf=""><br></span><span leaf="">3、高保真 UI 设计:作为 UI 设计师,设计贴近真实 iOS/Android 设计规范的界面,使用现代化的 UI 元素,使其具有良好的视觉体验。</span><span leaf=""><br></span><span leaf="">4、HTML 原型实现:使用 HTML + Tailwind CSS(或 Bootstrap)生成所有原型界面,并使用 FontAwesome(或其他开源 UI 组件)让界面更加精美、接近真实的 App 设计。</span><span leaf=""><br></span><span leaf="">拆分代码文件,保持结构清晰:</span><span leaf=""><br></span><span leaf="">5、每个界面应作为独立的 HTML 文件存放,例如 home.html、profile.html、settings.html 等。</span><span leaf=""><br></span><span leaf="">- index.html 作为主入口,不直接写入所有界面的 HTML 代码,而是使用 iframe 的方式嵌入这些 HTML 片段,并将所有页面直接平铺展示在 index 页面中,而不是跳转链接。</span><span leaf=""><br></span><span leaf="">- 真实感增强:</span><span leaf=""><br></span><span leaf="">&nbsp; - 界面尺寸应模拟 iPhone 15 Pro,并让界面圆角化,使其更像真实的手机界面。</span><span leaf=""><br></span><span leaf="">&nbsp; - 使用真实的 UI 图片,而非占位符图片(可从 Unsplash、Pexels、Apple 官方 UI 资源中选择)。</span><span leaf=""><br></span><span leaf="">&nbsp; - 添加顶部状态栏(模拟 iOS 状态栏),并包含 App 导航栏(类似 iOS 底部 Tab Bar)。</span><span leaf=""><br></span><span leaf="">请按照以上要求生成完整的 HTML 代码,并确保其可用于实际开发。</span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""><br></span><span leaf="">这个html页面要求同时展示APP的多个页面,也就是说有多个iphone 15 pro的界面平铺在页面中,以便用户能直观看到全部产品页面。</span></code></pre> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">可以看到 Claude 的规划能力在线的</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/539a4c3778de511b30f293805d0c7373.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.47314814814814815" data-type="png" data-w="1080" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009903"> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">Claude 的水平没毛病,生成了多个 html 文件</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/c779f1c94167e69812df4c7bfce24820.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.42962962962962964" data-type="png" data-w="1080" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009902"> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">最终效果长这样:</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/30e18d5c61cae1cee9c8a29e299a283a.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.5407407407407407" data-type="png" data-w="1080" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009905"> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span leaf=""><br></span></p> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">至此,我们完成了 Claude Code 从 0 到 1 的安装,并配上了第三方中转 API,最后通过一个小实践,真正踏上了 Claude Code 的提效之旅~</span></span></p> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">对了,刚才分析文档➕开发原型的需求,<span textstyle="" style="font-weight: bold;">总共跑了 37591Tokens,耗费 0.95🔪</span></span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/ac5e09860ec437e9db3cab2e94a5a9db.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.18888888888888888" data-type="png" data-w="1080" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009901"> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">跑的是 claude4,这成本你觉得还可以接受吗?</span></span></p> <section style="color: rgb(0, 0, 0);font-family: " pingfang sc;font-size: medium;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: center;margin-bottom: 12px; nodeleaf=""> <img src="/upload/9173669dd539ede8b46ca9bf41bd3363.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.45925925925925926" data-type="png" data-w="1080" style="display: inline-block;max-width: 100%;height: auto;border-radius: 12px;" data-imgfileid="110009910"> </section> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span leaf=""><br></span></p> <p data-author="dui!" style="font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;line-height: 2em;font-family: " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(31, 35, 41);margin: 0px 4px;word-break: break-all;min-height: 20px;><span style="color: rgb(31, 35, 41);"><span leaf="">关注我,下一期继续分享 Claude Code 的使用技巧。</span></span></p>

为什么 SpringBoot 宁可挨骂也要干掉 spring.factories?

作者:微信小助手

<p cid="n0" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 16px 0px 24px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial; data-pm-slice="0 0 []"><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;" data-mpa-action-id="md706cz91f8a"><span leaf="">兄弟们,今天咱们来聊一个 SpringBoot 社区里的 “劲爆” 话题 —— 为什么 SpringBoot 宁可被骂也要干掉 spring.factories?这个问题就像一颗投入平静湖面的石子,在开发者圈里掀起了不小的波澜。很多老司机可能会问:“spring.factories 用得好好的,干嘛要改?” 别急,咱们今天就来扒一扒这背后的 “恩怨情仇”。</span></span></p> <section mpa-from-tpl="t" data-mpa-action-id="md706n2lft8" data-pm-slice="0 0 []"> <span leaf=""><br></span> </section> <section data-mpa-template="t" mpa-data-temp-power-by="yiban.io" mpa-from-tpl="t" data-mpa-action-id="md706n2lunr"> <section data-mpa-template="t" mpa-from-tpl="t"> <h4 data-tool="mdnice编辑器" style="margin-bottom: 15px;font-weight: 400;font-size: 16px;text-align: justify;outline: 0px;color: rgb(34, 34, 34);letter-spacing: 0.544px;caret-color: rgb(51, 51, 51);line-height: 2em;"><span style="font-size: 20px;"><strong mpa-from-tpl="t" style="outline: 0px;"><span mpa-is-content="t" style="font-size: 20px;outline: 0px;color: rgb(0, 122, 170);"><span leaf="">一、spring.factories 的前世今生</span></span></strong></span></h4> </section> </section> <h3 cid="n3" mdtype="heading" style="box-sizing: border-box;break-after: avoid-page;break-inside: avoid;orphans: 2;font-size: 1.5em;margin-top: 24px;margin-bottom: 24px;font-weight: bold;line-height: 2em;cursor: text;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">(一)曾经的 “功臣”</span></span></h3> <p cid="n4" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">在 SpringBoot 的早期版本中,spring.factories 可是个 “大红人”。它就像一个神奇的 “配置管家”,允许第三方库通过 META-INF/spring.factories 文件注册自动配置类。比如说,你引入一个数据库驱动的依赖,它就能自动帮你配置好数据源,是不是很方便?</span></span></p> <p cid="n5" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">那它是怎么工作的呢?简单来说,SpringBoot 启动的时候,会扫描所有 JAR 包中的 META-INF/spring.factories 文件,然后根据里面的配置加载对应的自动配置类。这种 “约定优于配置” 的方式,大大减少了开发者的工作量,让我们可以快速搭建应用。</span></span></p> <h3 cid="n6" mdtype="heading" style="box-sizing: border-box;break-after: avoid-page;break-inside: avoid;orphans: 2;font-size: 1.5em;margin-top: 24px;margin-bottom: 24px;font-weight: bold;line-height: 2em;cursor: text;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">(二)暗藏的 “隐患”</span></span></h3> <p cid="n7" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">但是,随着时间的推移,spring.factories 的问题也逐渐暴露出来。就像一个看似完美的人,身上却隐藏着一些致命的缺点。</span></span></p> <ol style="box-sizing: border-box;margin: 0.8em 0px;padding-left: 30px;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;margin: 0px;"><p cid="n10" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;"><span md-inline="strong" style="box-sizing: border-box;font-size: 17px;"><strong style="box-sizing: border-box;"><span md-inline="plain" style="box-sizing: border-box;"><span leaf="">启动速度的 “噩梦”</span></span></strong></span></p></li> </ol> <p cid="n11" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">想象一下,当你的项目依赖了成百上千个 JAR 包时,SpringBoot 就像一个勤劳的 “扫街工”,要一个一个地扫描每个 JAR 包中的 spring.factories 文件。这得多慢啊!实测显示,某电商平台在依赖 300+ 个 JAR 包的情况下,仅配置加载阶段就消耗了 2.3 秒启动时间。这对于追求高性能的现代应用来说,简直是一场 “噩梦”。</span></span></p> <ol style="box-sizing: border-box;margin: 0.8em 0px;padding-left: 30px;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;margin: 0px;"><p cid="n14" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;"><span md-inline="strong" style="box-sizing: border-box;font-size: 17px;"><strong style="box-sizing: border-box;"><span md-inline="plain" style="box-sizing: border-box;"><span leaf="">维护的 “灾难现场”</span></span></strong></span></p></li> </ol> <p cid="n15" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">当项目越来越大,模块越来越多时,spring.factories 文件就像一个 “大杂烩”,里面的内容越来越多,维护起来简直就是一场 “灾难”。不同的模块可能会引入冲突的配置,让开发者们头疼不已。</span></span></p> <ol style="box-sizing: border-box;margin: 0.8em 0px;padding-left: 30px;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;margin: 0px;"><p cid="n18" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;"><span md-inline="strong" style="box-sizing: border-box;font-size: 17px;"><strong style="box-sizing: border-box;"><span md-inline="plain" style="box-sizing: border-box;"><span leaf="">模块化的 “绊脚石”</span></span></strong></span></p></li> </ol> <p cid="n19" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">随着 Java 9 引入模块系统(JPMS),spring.factories 的问题就更明显了。它基于类路径扫描的方式,与模块化设计理念格格不入,无法很好地支持 Java 模块系统。</span></span></p> <section mpa-from-tpl="t" data-mpa-action-id="md706tt91fvu" data-pm-slice="0 0 []"> <span leaf=""><br></span> </section> <section data-mpa-template="t" mpa-data-temp-power-by="yiban.io" mpa-from-tpl="t" data-mpa-action-id="md706tt984b"> <section data-mpa-template="t" mpa-from-tpl="t"> <h4 data-tool="mdnice编辑器" style="margin-bottom: 15px;font-weight: 400;font-size: 16px;text-align: justify;outline: 0px;color: rgb(34, 34, 34);letter-spacing: 0.544px;caret-color: rgb(51, 51, 51);line-height: 2em;"><span style="font-size: 20px;"><strong mpa-from-tpl="t" style="outline: 0px;"><span mpa-is-content="t" style="font-size: 20px;outline: 0px;color: rgb(0, 122, 170);"><span leaf="">二、SpringBoot 的 “忍无可忍”</span></span></strong></span></h4> </section> </section> <h3 cid="n21" mdtype="heading" style="box-sizing: border-box;break-after: avoid-page;break-inside: avoid;orphans: 2;font-size: 1.5em;margin-top: 24px;margin-bottom: 24px;font-weight: bold;line-height: 2em;cursor: text;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">(一)性能的 “生死时速”</span></span></h3> <p cid="n22" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">在这个 “速度为王” 的时代,SpringBoot 团队显然也意识到了启动速度的重要性。为了提升性能,他们决定对 spring.factories 下手。毕竟,谁也不想自己的应用启动得像 “蜗牛爬” 一样慢。</span></span></p> <h3 cid="n23" mdtype="heading" style="box-sizing: border-box;break-after: avoid-page;break-inside: avoid;orphans: 2;font-size: 1.5em;margin-top: 24px;margin-bottom: 24px;font-weight: bold;line-height: 2em;cursor: text;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">(二)模块化的 “大势所趋”</span></span></h3> <p cid="n24" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">Java 模块系统的出现,标志着 Java 生态向模块化发展的趋势。SpringBoot 作为 Java 生态的重要一员,自然不能落后。而 spring.factories 这种基于类路径扫描的方式,显然已经跟不上时代的步伐了。</span></span></p> <h3 cid="n25" mdtype="heading" style="box-sizing: border-box;break-after: avoid-page;break-inside: avoid;orphans: 2;font-size: 1.5em;margin-top: 24px;margin-bottom: 24px;font-weight: bold;line-height: 2em;cursor: text;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">(三)GraalVM 的 “临门一脚”</span></span></h3> <p cid="n26" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">近年来,GraalVM 原生镜像技术越来越火。它可以将 Java 应用编译成原生可执行文件,大大提升性能和启动速度。但是,spring.factories 基于运行时类路径扫描的机制,与 GraalVM 的提前编译(AOT)模型存在根本性冲突。为了更好地支持 GraalVM,SpringBoot 必须做出改变。</span></span></p> <section mpa-from-tpl="t" data-mpa-action-id="md706yh1wgv" data-pm-slice="0 0 []"> <span leaf=""><br></span> </section> <section data-mpa-template="t" mpa-data-temp-power-by="yiban.io" mpa-from-tpl="t" data-mpa-action-id="md706yh11rrc"> <section data-mpa-template="t" mpa-from-tpl="t"> <h4 data-tool="mdnice编辑器" style="margin-bottom: 15px;font-weight: 400;font-size: 16px;text-align: justify;outline: 0px;color: rgb(34, 34, 34);letter-spacing: 0.544px;caret-color: rgb(51, 51, 51);line-height: 2em;"><span style="font-size: 20px;"><strong mpa-from-tpl="t" style="outline: 0px;"><span mpa-is-content="t" style="font-size: 20px;outline: 0px;color: rgb(0, 122, 170);"><span leaf="">三、新贵登场:AutoConfiguration.imports</span></span></strong></span></h4> </section> </section> <h3 cid="n28" mdtype="heading" style="box-sizing: border-box;break-after: avoid-page;break-inside: avoid;orphans: 2;font-size: 1.5em;margin-top: 24px;margin-bottom: 24px;font-weight: bold;line-height: 2em;cursor: text;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">(一)“新管家” 的闪亮登场</span></span></h3> <p cid="n29" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">为了解决 spring.factories 的问题,SpringBoot 3.0 引入了一个新的配置文件 ——META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports。这个文件就像一个 “新管家”,取代了 spring.factories 的位置。</span></span></p> <p cid="n30" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;" data-mpa-action-id="md706cz9qhh"><span leaf="">它的使用方式非常简单,只需要在文件中列出需要自动配置的类的全限定名,每行一个。例如:</span></span></p> <pre spellcheck="false" lang="plain" cid="n31" mdtype="fences" style="box-sizing: border-box;overflow: visible;font-family: var(--monospace);font-size: 0.9em;display: block;break-inside: avoid;text-align: left;white-space: normal;background-image: inherit;background-position: inherit;background-size: inherit;background-repeat: inherit;background-attachment: inherit;background-origin: inherit;background-clip: inherit;background-color: rgb(248, 248, 248);border: 1px solid rgb(231, 234, 237);border-radius: 3px;padding: 8px 4px 6px;margin-bottom: 15px;margin-top: 15px;width: inherit;color: rgb(51, 51, 51);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;"><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">com.example.MyAutoConfiguration</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">com.example.AnotherAutoConfiguration</span></span></pre> <p cid="n32" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;" data-mpa-action-id="md70799bc6a"><span leaf="">这种方式不仅提高了配置的可读性和可维护性,还支持模块化管理。不同的模块可以有自己的 AutoConfiguration.imports 文件,独立维护自己的自动配置列表。</span></span></p> <h3 cid="n33" mdtype="heading" style="box-sizing: border-box;break-after: avoid-page;break-inside: avoid;orphans: 2;font-size: 1.5em;margin-top: 24px;margin-bottom: 24px;font-weight: bold;line-height: 2em;cursor: text;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">(二)性能的 “质的飞跃”</span></span></h3> <p cid="n34" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">新的配置方式在性能上有了显著提升。首先,它减少了不必要的类扫描,因为每个扩展点类型使用单独的文件,避免了加载不需要的配置。其次,它与 Java 模块系统兼容,不再是模块化的 “绊脚石”。实测数据显示,使用新方案后,类加载时间减少了 30%,类加载量减少了 29%。</span></span></p> <h3 cid="n35" mdtype="heading" style="box-sizing: border-box;break-after: avoid-page;break-inside: avoid;orphans: 2;font-size: 1.5em;margin-top: 24px;margin-bottom: 24px;font-weight: bold;line-height: 2em;cursor: text;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">(三)功能的 “全面升级”</span></span></h3> <p cid="n36" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;" data-mpa-action-id="md70799bovj"><span leaf="">除了性能提升,新方案在功能上也有了全面升级。它支持条件化配置,开发者可以使用 @Conditional 注解来动态决定是否加载某个配置类。例如:</span></span></p> <pre spellcheck="false" lang="plain" cid="n37" mdtype="fences" style="box-sizing: border-box;overflow: visible;font-family: var(--monospace);font-size: 0.9em;display: block;break-inside: avoid;text-align: left;white-space: normal;background-image: inherit;background-position: inherit;background-size: inherit;background-repeat: inherit;background-attachment: inherit;background-origin: inherit;background-clip: inherit;background-color: rgb(248, 248, 248);border: 1px solid rgb(231, 234, 237);border-radius: 3px;padding: 8px 4px 6px;margin-bottom: 15px;margin-top: 15px;width: inherit;color: rgb(51, 51, 51);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;"><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">@AutoConfiguration</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">@ConditionalOnClass(name = "com.example.ExternalService")</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">public class MyAutoConfiguration {</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">&nbsp; &nbsp; // 配置类的内容</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">}</span></span></pre> <p cid="n38" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;" data-mpa-action-id="md707o01135d"><span leaf="">这样,只有当类路径下存在 ExternalService 类时,这个配置类才会生效。这种灵活的配置方式,让开发者可以更好地控制应用的行为。</span></span></p> <section mpa-from-tpl="t" data-mpa-action-id="md707xo71sun" data-pm-slice="0 0 []"> <span leaf=""><br></span> </section> <section data-mpa-template="t" mpa-data-temp-power-by="yiban.io" mpa-from-tpl="t" data-mpa-action-id="md707xo71fju"> <section data-mpa-template="t" mpa-from-tpl="t"> <h4 data-tool="mdnice编辑器" style="margin-bottom: 15px;font-weight: 400;font-size: 16px;text-align: justify;outline: 0px;color: rgb(34, 34, 34);letter-spacing: 0.544px;caret-color: rgb(51, 51, 51);line-height: 2em;"><span style="font-size: 20px;"><strong mpa-from-tpl="t" style="outline: 0px;"><span mpa-is-content="t" style="font-size: 20px;outline: 0px;color: rgb(0, 122, 170);"><span leaf="">四、社区的 “爱恨情仇”</span></span></strong></span></h4> </section> </section> <h3 cid="n40" mdtype="heading" style="box-sizing: border-box;break-after: avoid-page;break-inside: avoid;orphans: 2;font-size: 1.5em;margin-top: 24px;margin-bottom: 24px;font-weight: bold;line-height: 2em;cursor: text;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">(一)开发者的 “吐槽大会”</span></span></h3> <p cid="n41" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">任何重大的变更都会引起社区的讨论,这次也不例外。一些习惯了 spring.factories 的开发者开始 “吐槽”:“为什么要改?我用得好好的!”“迁移成本太高了,我不想改!” 甚至有人在社交媒体上发起了 “抗议”。</span></span></p> <h3 cid="n42" mdtype="heading" style="box-sizing: border-box;break-after: avoid-page;break-inside: avoid;orphans: 2;font-size: 1.5em;margin-top: 24px;margin-bottom: 24px;font-weight: bold;line-height: 2em;cursor: text;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">(二)Spring 团队的 “良苦用心”</span></span></h3> <p cid="n43" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">面对社区的质疑,Spring 团队也给出了自己的解释。他们表示,虽然这次变更会给一些开发者带来不便,但从长远来看,这是为了提升 SpringBoot 的整体性能和可维护性。他们希望通过这次变更,让 SpringBoot 更好地适应现代 Java 生态的发展,为开发者提供更高效、更灵活的配置方式。</span></span></p> <h3 cid="n44" mdtype="heading" style="box-sizing: border-box;break-after: avoid-page;break-inside: avoid;orphans: 2;font-size: 1.5em;margin-top: 24px;margin-bottom: 24px;font-weight: bold;line-height: 2em;cursor: text;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">(三)迁移的 “最佳实践”</span></span></h3> <p cid="n45" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;" data-mpa-action-id="md707o01r7d"><span leaf="">为了帮助开发者顺利迁移,Spring 团队提供了详细的迁移指南。首先,开发者需要识别 spring.factories 中的配置,然后将其转换为 AutoConfiguration.imports 文件。例如,将 spring.factories 中的:</span></span></p> <pre spellcheck="false" lang="plain" cid="n46" mdtype="fences" style="box-sizing: border-box;overflow: visible;font-family: var(--monospace);font-size: 0.9em;display: block;break-inside: avoid;text-align: left;white-space: normal;background-image: inherit;background-position: inherit;background-size: inherit;background-repeat: inherit;background-attachment: inherit;background-origin: inherit;background-clip: inherit;background-color: rgb(248, 248, 248);border: 1px solid rgb(231, 234, 237);border-radius: 3px;padding: 8px 4px 6px;margin-bottom: 15px;margin-top: 15px;width: inherit;color: rgb(51, 51, 51);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;"><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">org.springframework.boot.autoconfigure.EnableAutoConfiguration=\</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">com.example.MyAutoConfiguration,\</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">com.example.AnotherAutoConfiguration</span></span></pre> <p cid="n47" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain"><span leaf="" style="box-sizing: border-box;font-size: 17px;">转换为 AutoConfiguration.imports 文件中的:</span></span></p> <pre spellcheck="false" lang="plain" cid="n48" mdtype="fences" style="box-sizing: border-box;overflow: visible;font-family: var(--monospace);font-size: 0.9em;display: block;break-inside: avoid;text-align: left;white-space: normal;background-image: inherit;background-position: inherit;background-size: inherit;background-repeat: inherit;background-attachment: inherit;background-origin: inherit;background-clip: inherit;background-color: rgb(248, 248, 248);border: 1px solid rgb(231, 234, 237);border-radius: 3px;padding: 8px 4px 6px;margin-bottom: 15px;margin-top: 15px;width: inherit;color: rgb(51, 51, 51);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;"><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">com.example.MyAutoConfiguration</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">com.example.AnotherAutoConfiguration</span></span></pre> <p cid="n49" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;" data-mpa-action-id="md70bvbb5fx"><span leaf="">此外,开发者还可以使用 spring-boot-autoconfigure-processor 工具来优化自动配置加载,减少手动管理的负担。</span></span></p> <section mpa-from-tpl="t" data-mpa-action-id="md70c4l816g1" data-pm-slice="0 0 []"> <span leaf=""><br></span> </section> <section data-mpa-template="t" mpa-data-temp-power-by="yiban.io" mpa-from-tpl="t" data-mpa-action-id="md70c4l81x0i"> <section data-mpa-template="t" mpa-from-tpl="t"> <h4 data-tool="mdnice编辑器" style="margin-bottom: 15px;font-weight: 400;font-size: 16px;text-align: justify;outline: 0px;color: rgb(34, 34, 34);letter-spacing: 0.544px;caret-color: rgb(51, 51, 51);line-height: 2em;"><span style="font-size: 20px;"><strong mpa-from-tpl="t" style="outline: 0px;"><span mpa-is-content="t" style="font-size: 20px;outline: 0px;color: rgb(0, 122, 170);"><span leaf="">五、实战案例:从 spring.factories 到 AutoConfiguration.imports</span></span></strong></span></h4> </section> </section> <h3 cid="n51" mdtype="heading" style="box-sizing: border-box;break-after: avoid-page;break-inside: avoid;orphans: 2;font-size: 1.5em;margin-top: 24px;margin-bottom: 24px;font-weight: bold;line-height: 2em;cursor: text;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">(一)创建自定义自动配置</span></span></h3> <p cid="n52" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">假设我们要创建一个自定义的自动配置类 MyAutoConfiguration,它需要根据配置文件中的属性来决定是否生效。我们可以按照以下步骤进行:</span></span></p> <ol style="box-sizing: border-box;margin: 0.8em 0px;padding-left: 30px;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;margin: 0px;"><p cid="n55" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;"><span md-inline="strong" style="box-sizing: border-box;font-size: 17px;" data-mpa-action-id="md70bvbb1kut"><strong style="box-sizing: border-box;"><span md-inline="plain" style="box-sizing: border-box;"><span leaf="">创建配置属性类</span></span></strong></span></p></li> </ol> <pre spellcheck="false" lang="plain" cid="n56" mdtype="fences" style="box-sizing: border-box;overflow: visible;font-family: var(--monospace);font-size: 0.9em;display: block;break-inside: avoid;text-align: left;white-space: normal;background-image: inherit;background-position: inherit;background-size: inherit;background-repeat: inherit;background-attachment: inherit;background-origin: inherit;background-clip: inherit;background-color: rgb(248, 248, 248);border: 1px solid rgb(231, 234, 237);border-radius: 3px;padding: 8px 4px 6px;margin-bottom: 15px;margin-top: 15px;width: inherit;color: rgb(51, 51, 51);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;"><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">@ConfigurationProperties(prefix = "myapp")</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">public class MyProperties {</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">&nbsp; &nbsp; private boolean enabled = true;</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">&nbsp; &nbsp; private String name = "default";</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">&nbsp; &nbsp; // getter 和 setter 方法</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">}</span></span></pre> <ol style="box-sizing: border-box;margin: 0.8em 0px;padding-left: 30px;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li><p cid="n59" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;"><span md-inline="strong"><strong><span md-inline="plain"><span leaf="" style="font-size: 17px;font-weight: bold;box-sizing: border-box;">创建自动配置类</span></span></strong></span></p></li> </ol> <pre spellcheck="false" lang="plain" cid="n60" mdtype="fences" style="box-sizing: border-box;overflow: visible;font-family: var(--monospace);font-size: 0.9em;display: block;break-inside: avoid;text-align: left;white-space: normal;background-image: inherit;background-position: inherit;background-size: inherit;background-repeat: inherit;background-attachment: inherit;background-origin: inherit;background-clip: inherit;background-color: rgb(248, 248, 248);border: 1px solid rgb(231, 234, 237);border-radius: 3px;padding: 8px 4px 6px;margin-bottom: 15px;margin-top: 15px;width: inherit;color: rgb(51, 51, 51);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;"><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">@AutoConfiguration</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">@EnableConfigurationProperties(MyProperties.class)</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">@ConditionalOnProperty(prefix = "myapp", name = "enabled", havingValue = "true", matchIfMissing = true)</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">public class MyAutoConfiguration {</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">&nbsp; &nbsp; private final MyProperties properties;</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">&nbsp; &nbsp; public MyAutoConfiguration(MyProperties properties) {</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; this.properties = properties;</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">&nbsp; &nbsp; }</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">&nbsp; &nbsp; @Bean</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">&nbsp; &nbsp; @ConditionalOnMissingBean</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">&nbsp; &nbsp; public MyService myService() {</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; return new MyServiceImpl(properties.getName());</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">&nbsp; &nbsp; }</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">}</span></span></pre> <ol style="box-sizing: border-box;margin: 0.8em 0px;padding-left: 30px;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="box-sizing: border-box;margin: 0px;"><p cid="n63" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;"><span md-inline="strong" style="box-sizing: border-box;font-size: 17px;" data-mpa-action-id="md70cf0x95w"><strong style="box-sizing: border-box;"><span md-inline="plain" style="box-sizing: border-box;"><span leaf="">注册自动配置</span></span></strong></span></p></li> </ol> <p cid="n64" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;" data-mpa-action-id="md70cf0x1p5i"><span leaf="">在 META-INF/spring/ 目录下创建 org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件,并添加以下内容:</span></span></p> <pre spellcheck="false" lang="plain" cid="n65" mdtype="fences" style="box-sizing: border-box;overflow: visible;font-family: var(--monospace);font-size: 0.9em;display: block;break-inside: avoid;text-align: left;white-space: normal;background-image: inherit;background-position: inherit;background-size: inherit;background-repeat: inherit;background-attachment: inherit;background-origin: inherit;background-clip: inherit;background-color: rgb(248, 248, 248);border: 1px solid rgb(231, 234, 237);border-radius: 3px;padding: 8px 4px 6px;margin-bottom: 15px;margin-top: 15px;width: inherit;color: rgb(51, 51, 51);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;"><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">com.example.MyAutoConfiguration</span></span></pre> <h3 cid="n66" mdtype="heading" style="box-sizing: border-box;break-after: avoid-page;break-inside: avoid;orphans: 2;font-size: 1.5em;margin-top: 24px;margin-bottom: 24px;font-weight: bold;line-height: 2em;cursor: text;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;" data-mpa-action-id="md70csxj1h35"><span leaf="">(二)迁移已有的配置</span></span></h3> <p cid="n67" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;" data-mpa-action-id="md70csxj1fwz"><span leaf="">如果你的项目中已经使用了 spring.factories,迁移到新方案也很简单。首先,找出 META-INF/spring.factories 中的 EnableAutoConfiguration 配置项,然后将其中的自动配置类列表迁移到 AutoConfiguration.imports 文件中。例如,将:</span></span></p> <pre spellcheck="false" lang="plain" cid="n68" mdtype="fences" style="box-sizing: border-box;overflow: visible;font-family: var(--monospace);font-size: 0.9em;display: block;break-inside: avoid;text-align: left;white-space: normal;background-image: inherit;background-position: inherit;background-size: inherit;background-repeat: inherit;background-attachment: inherit;background-origin: inherit;background-clip: inherit;background-color: rgb(248, 248, 248);border: 1px solid rgb(231, 234, 237);border-radius: 3px;padding: 8px 4px 6px;margin-bottom: 15px;margin-top: 15px;width: inherit;color: rgb(51, 51, 51);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;"><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">org.springframework.boot.autoconfigure.EnableAutoConfiguration=\</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">com.example.MyAutoConfiguration,\</span></span><span leaf=""><br></span><span role="presentation" style="box-sizing: border-box;padding-right: 0.1px;"><span leaf="">com.example.AnotherAutoConfiguration</span></span></pre> <p cid="n69" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain"><span leaf="" style="box-sizing: border-box;font-size: 17px;">迁移为:</span></span></p> <pre spellcheck="false" lang="plain" cid="n70" mdtype="fences" style="box-sizing: border-box;overflow: visible;font-family: var(--monospace);font-size: 0.9em;display: block;break-inside: avoid;text-align: left;white-space: pre-wrap;background-image: inherit;background-position: inherit;background-size: inherit;background-repeat: inherit;background-attachment: inherit;background-origin: inherit;background-clip: inherit;background-color: rgb(248, 248, 248);border: 1px solid rgb(231, 234, 237);border-radius: 3px;padding: 8px 4px 6px;margin-bottom: 15px;margin-top: 15px;width: inherit;color: rgb(51, 51, 51);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;"><span leaf="">com.example.MyAutoConfiguration com.example.AnotherAutoConfiguration</span></pre> <p cid="n71" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;" data-mpa-action-id="md705sva17jz"><span leaf="">最后,检查项目是否依赖了 spring-boot-autoconfigure-processor,并进行优化。</span></span></p> <section mpa-from-tpl="t" data-mpa-action-id="md70d9ij1liv" data-pm-slice="0 0 []"> <span leaf=""><br></span> </section> <section data-mpa-template="t" mpa-data-temp-power-by="yiban.io" mpa-from-tpl="t" data-mpa-action-id="md70d9ij1rdn"> <section data-mpa-template="t" mpa-from-tpl="t"> <h4 data-tool="mdnice编辑器" style="margin-bottom: 15px;font-weight: 400;font-size: 16px;text-align: justify;outline: 0px;color: rgb(34, 34, 34);letter-spacing: 0.544px;caret-color: rgb(51, 51, 51);line-height: 2em;"><span style="font-size: 20px;"><strong mpa-from-tpl="t" style="outline: 0px;"><span mpa-is-content="t" style="font-size: 20px;outline: 0px;color: rgb(0, 122, 170);"><span leaf="">六、总结:拥抱变化,走向未来</span></span></strong></span></h4> </section> </section> <p cid="n73" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;"><span leaf="">SpringBoot 干掉 spring.factories 的决定,虽然在短期内引起了一些争议,但从长远来看,这是一次必要的 “革命”。新的配置方式不仅提升了性能,还增强了灵活性和可维护性,更好地适应了现代 Java 生态的发展。</span></span></p> <p cid="n74" mdtype="paragraph" style="box-sizing: border-box;line-height: 2em;orphans: 4;margin: 24px 0px;white-space: pre-wrap;color: rgb(51, 51, 51);font-family: " open sans, clear helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-style: initial;text-decoration-color: initial;><span md-inline="plain" style="box-sizing: border-box;font-size: 17px;" data-mpa-action-id="md705sva1h0w"><span leaf="">对于开发者来说,虽然迁移过程可能会遇到一些困难,但这也是一个学习和成长的机会。我们应该拥抱变化,积极学习新的配置方式,让自己的技术栈跟上时代的步伐。毕竟,在技术的世界里,停滞不前就意味着落后。</span></span></p> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>

企业AI知识库的文件解析痛点-Word格式解析优化(准确率95%)-100%开源

作者:微信小助手

<p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 0px;color: rgb(10, 10, 10);font-family: ui-sans-serif, system-ui, sans-serif, " apple color emoji, segoe ui symbol, noto emoji;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 0px;line-height: 0; data-pm-slice="0 0 []"><span leaf="">&nbsp;</span></p> <section style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(10, 10, 10);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;> <h2 data-heading="true" style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-size: 20.8px;font-weight: bold;margin: 0px auto 2em;text-align: center;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;display: table;padding: 0.3em 1em;color: rgb(255, 255, 255);background: rgb(59, 53, 53);border-radius: 8px;box-shadow: rgba(0, 0, 0.1) 0px 4px 6px;><span leaf="">一、前言</span></h2> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">在大模型和RAG(检索增强生成)技术飞速发展的今天,</span><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">企业AI知识库</span></strong><span leaf="">建设已成为AI落地的核心战场。而文件解析是所有参与做企业AI知识库开发者所避免不了的难题。</span></p> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">本文将结合我在开发TorchV AIS</span><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">企业级AI知识库</span></strong><span leaf="">产品中碰到的解析Word的问题,将Word文档(</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">.doc</span></code><span leaf="">及</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">.docx</span></code><span leaf="">)高效、准确地转换为Web友好格式(Markdown/HTML)优化目标的方案进行分享。结合目前的实际解决方案(依靠Apache Tika/POI),详细阐述一种创新的、具备行业领先水平的解决方案。通过实现一套</span><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">完全基于表格结构、无需硬编码的通用算法</span></strong><span leaf="">,完美解决了</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">.doc</span></code><span leaf="">和</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">.docx</span></code><span leaf="">格式中的复杂表格解析问题,确保转换后的HTML与源文件在视觉和结构上高度一致。</span></p> <h2 data-heading="true" style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-size: 20.8px;font-weight: bold;margin: 4em auto 2em;text-align: center;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;display: table;padding: 0.3em 1em;color: rgb(255, 255, 255);background: rgb(59, 53, 53);border-radius: 8px;box-shadow: rgba(0, 0, 0.1) 0px 4px 6px;><span leaf="">二、Word文档解析:企业AI知识库的隐形瓶颈?</span></h2> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">据我们的调研和实践经验:</span></p> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">1、两种文件格式,两种世界</span></strong></p> <ul style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);list-style: none;margin: 0px;padding: 0px 0px 0px 1.5em;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;color: rgb(63, 63, 63); class="list-paddingleft-1"> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">•&nbsp;</span><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">.docx</span></code><span leaf="">格式</span></strong><span leaf="">:基于Office Open XML (OOXML) 标准,本质是一个ZIP压缩包,内部包含描述文档结构的XML文件。表格的合并信息(如</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">gridSpan</span></code><span leaf="">、</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">vMerge</span></code><span leaf="">)在XML中有明确定义,解析相对</span><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">规范</span></strong><span leaf="">。</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">•&nbsp;</span><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">.doc</span></code><span leaf="">格式</span></strong><span leaf="">:是微软私有的二进制格式,内部结构复杂、缺乏公开的完整文档。通过POI的</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">HWPFDocument</span></code><span leaf="">模块进行解析时,获取到的表格信息非常原始,</span><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">几乎不直接提供合并单元格的完整信息</span></strong><span leaf="">。</span> </section></li> </ul> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">2、传统工具的局限</span></strong></p> <ul style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);list-style: none;margin: 0px;padding: 0px 0px 0px 1.5em;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;color: rgb(63, 63, 63); class="list-paddingleft-1"> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• 大多数转换工具在处理</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">.doc</span></code><span leaf="">格式时,无法准确还原</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">rowspan</span></code><span leaf="">和</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">colspan</span></code> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• 它们通常会把合并单元格下的空单元格渲染成独立的</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf=""></span></code><span leaf="">,导致表格"散架"</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• 为了绕过难题,一些方案采取"扁平化"策略,即复制合并单元格的内容来填充所有被合并的单元格,但这破坏了表格的原始结构</span> </section></li> </ul> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">3、企业现状</span></strong></p> <ul style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);list-style: none;margin: 0px;padding: 0px 0px 0px 1.5em;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;color: rgb(63, 63, 63); class="list-paddingleft-1"> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• 90%的企业仍然有大量的Word格式需要导入企业AI知识库,特别是金融、政府领域的客户对于doc老文件格式的诉求。</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">•&nbsp;</span><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">传统解析方案的表格准确率</span></strong><span leaf="">普遍较低,特别是在处理合并单元格时</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">•&nbsp;</span><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">表格信息的丢失或错误</span></strong><span leaf="">直接导致企业AI知识库系统对业务关键信息的理解偏差,导致大模型回答准确度大大降低</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">•&nbsp;</span><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">现有开源工具</span></strong><span leaf="">要么功能简陋,要么商业化程度高,开发者缺乏可控的解决方案</span> </section></li> </ul> <h2 data-heading="true" style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-size: 20.8px;font-weight: bold;margin: 4em auto 2em;text-align: center;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;display: table;padding: 0.3em 1em;color: rgb(255, 255, 255);background: rgb(59, 53, 53);border-radius: 8px;box-shadow: rgba(0, 0, 0.1) 0px 4px 6px;><span leaf="">三、企业AI知识库的诉求</span></h2> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">对于做企业AI知识库的服务商而言,Word的解析是一个全面综合去考虑分析的一个问题。对于我们而言,我们考虑的主要方向包括:</span></p> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">1、解析格式需要支持doc\docx两种格式</span></strong></p> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">我知道现有的很多开源工具、商业产品在处理Word格式上,对于解析doc格式都倍感恼火。感觉这么一个上世纪微软留下的产物,让开发者恨的牙痒痒,不亚于10年前开发者去解决IE6的各种兼容性问题。然而在我们的客户里面,特别是金融、政府领域的客户,依然存在着大量的老的doc的格式文件,这些文件依然是企业的数字资产,在AI时代,都需要坐上这趟高速列车,把数据装载进入企业AI知识库里面,发挥知识的价值。</span></p> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">2、Word文档能够解析提取成Markdown格式,提取的元素包括:(文档Header、表格、图片)</span></strong></p> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">企业AI知识库最关心的是“知识的结构化”。解析文档的目标不只是转换文本,更是为了“识别并提取有价值的知识结构”。因此:</span></p> <ul style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);list-style: none;margin: 0px;padding: 0px 0px 0px 1.5em;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;color: rgb(63, 63, 63); class="list-paddingleft-1"> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• 文档头信息(如标题、章节、层级结构)需准确提取并转化为 Markdown 标题(</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">#</span></code><span leaf="">、</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">##</span></code><span leaf="">&nbsp;等);</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• 段落、列表、加粗/斜体等格式也应保留,确保语义清晰、上下文连贯;</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• 引用和脚注等内容建议标准化处理,支持企业在QA和文档搜索场景中进行深度挖掘。</span> </section></li> </ul> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">3、表格的内容需要用Html呈现,解决合并(rowspan/colspan)单元格的问题</span></strong></p> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">Markdown 表格天生不支持合并单元格(</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">rowspan/colspan</span></code><span leaf="">),而这正是企业文档中极为常见的复杂表格结构(如绩效考核表、组织结构、流程图表等):</span></p> <ul style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);list-style: none;margin: 0px;padding: 0px 0px 0px 1.5em;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;color: rgb(63, 63, 63); class="list-paddingleft-1"> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• 采用 HTML 格式解析表格内容,能完整保留表格的合并信息;</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• 这样在知识回显、检索结果展示以及大模型上下文学习时,能确保原貌还原;</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• 可为后续编辑器的“所见即所得”功能打下良好基础。</span> </section></li> </ul> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">TorchV AIS企业AI知识库,提供了强大的富文本编辑器,对于Word的格式内容,对于表格内容就需要解析成标准的Html格式进行展现,丰富企业的知识二次加工创作。</span></strong></p> </section> <section style="text-align: center;" nodeleaf=""> <img src="/upload/e0232604032cfcca75ac133b97eeb607.png" class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.49166666666666664" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="100000935"> </section> <section style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(10, 10, 10);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;> <figure style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;color: rgb(63, 63, 63);> <span leaf=""><br></span> <figcaption style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: center;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 0.8em;color: rgb(136, 136, 136);> <span leaf="">image-20250721011115470</span> </figcaption> </figure> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">4、图片正确提取,并且图片的和文档内容上下位置正确。</span></strong></p> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">Word 中的图文混排结构(例如图解流程、插图说明等)是许多专业知识文档的重要组成:</span></p> <ul style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);list-style: none;margin: 0px;padding: 0px 0px 0px 1.5em;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;color: rgb(63, 63, 63); class="list-paddingleft-1"> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• 图片应&nbsp;</span><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">以URL链接</span></strong><span leaf="">&nbsp;保留,确保知识库中可以复现图文内容;</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• 同时还要&nbsp;</span><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">保持图片在文档中的原始顺序和上下文位置</span></strong><span leaf="">,不能打乱段落与图片的对应关系;</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• 若有 Alt 文本或说明文字,也需提取出来作为附加语义数据。</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• 必要情况下可以灵活利用外部工具(OCR/多模态等)对图片进行深度理解,能够扩展当前的图片语义,提升问答精准度</span> </section></li> </ul> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">5、性能以及成本考虑</span></strong></p> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">不同企业对解析能力的投入存在差异,因此服务端需提供灵活选择:</span></p> <ul style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);list-style: none;margin: 0px;padding: 0px 0px 0px 1.5em;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;color: rgb(63, 63, 63); class="list-paddingleft-1"> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• GPU/CPU的双重选择,有钱的可以无脑上GPU模型版本,驱动解析Word文档。</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• 解析的性能效率,高效转换以及向量嵌入的转化。在不同的成本下的考虑以及解析的效果综合评估</span> </section></li> </ul> <h2 data-heading="true" style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-size: 20.8px;font-weight: bold;margin: 4em auto 2em;text-align: center;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;display: table;padding: 0.3em 1em;color: rgb(255, 255, 255);background: rgb(59, 53, 53);border-radius: 8px;box-shadow: rgba(0, 0, 0.1) 0px 4px 6px;><span leaf="">四、TorchV技术实现路径:"预处理+注入"策略</span></h2> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">TorchV目前采用</span><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">Java</span></strong><span leaf="">语言开发,在底层技术栈上,对于Word的解析,目前恰好有2个非常好的开源软件可以利用:</span></p> <ul style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);list-style: none;margin: 0px;padding: 0px 0px 0px 1.5em;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;color: rgb(63, 63, 63); class="list-paddingleft-1"> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• Apache Tika:提供了多种文档解析的统一封装,开发者无需关心底层的细节,只需要统一调用就可以。</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• Apache POI:能够处理Office套件的文件解析,包括doc、docx格式的解析。</span> </section></li> </ul> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">虽然在底层技术支持上,这2个组件已经可以做的非常好了,但是对于上面我们第二点(企业AI知识库)的诉求,我们还是需要手工干预一下,才能解析得到我们想要的结果。</span></p> <blockquote style="box-sizing: border-box;border-width: 0px 0px 0px 4px;border-style: solid;border-color: rgb(229, 229, 229) rgb(229, 229, 229) rgb(229, 229, 229) rgb(59, 53, 53);margin: 0px 0px 1em;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;font-style: italic;padding: 1em 2em;border-radius: 6px;color: rgba(0, 0, 0.6);background: rgb(247, 247, 247);box-shadow: 0.05) 0px 4px 6px;> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 0px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 1em;display: block;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">1、这2个工具在表格的处理、图片的处理提取上面,</span><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">默认的策略</span></strong><span leaf="">都不太能满足我们的诉求,因此需要做更深层次的定制改动。</span></p> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 0px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 1em;display: block;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">2、我们依赖上面这两个组件做优化,这2个组件在CPU环境下能够快速的解析处理,所依赖的服务资源非常少的</span></p> </blockquote> <h3 data-heading="true" style="box-sizing: border-box;border-width: 0px 0px 1px 4px;border-style: solid solid dashed;border-color: rgb(229, 229, 229) rgb(229, 229, 229) rgb(59, 53, 53) rgb(59, 53, 53);font-size: 19.2px;font-weight: bold;margin: 2em 8px 0.75em 0px;text-align: left;line-height: 1.2;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;padding-left: 12px;color: rgb(63, 63, 63);><span leaf="">1. FileMagic:差异化处理策略</span></h3> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">对于doc/docx,我们需要从底层做差异处理,两种格式是完全不一样的解析策略,</span><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">针对不同格式采用不同的解析方案</span></strong><span leaf="">:</span></p> <pre style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;margin: 10px 8px;color: rgb(201, 209, 217);background: rgb(13, 17, 23);text-align: left;line-height: 1.5;overflow-x: auto;border-radius: 8px;box-shadow: rgba(0, 0, 0.05) 0px inset;padding: !important;><span hidden style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);display: flex;padding: 10px 14px 0px;"> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" width="45px" height="13px" viewbox="0 0 450 130"> <ellipse cx="50" cy="65" rx="50" ry="52" stroke="rgb(220,60,54)" stroke-width="2" fill="rgb(237,108,96)"></ellipse><ellipse cx="225" cy="65" rx="50" ry="52" stroke="rgb(218,151,33)" stroke-width="2" fill="rgb(247,193,81)"></ellipse><ellipse cx="400" cy="65" rx="50" ry="52" stroke="rgb(27,161,37)" stroke-width="2" fill="rgb(100,200,86)"></ellipse> </svg></span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: " fira code, menlo, operator mono, consolas, monaco, monospace;font-feature-settings: normal;font-variation-settings: normal;font-size: 12.96px;display: -webkit-box;padding: 0.5em 1em 1em;overflow-x: auto;text-indent: 0px;text-align: left;line-height: 1.75;margin: 0px;white-space: nowrap;><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// 检测文件格式</span></span><span leaf=""><br></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">FileMagic</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">fileMagic</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">=</span></span><span leaf="">&nbsp;FileMagicUtils.checkMagic(wordFile);</span><span leaf=""><br></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">if</span></span><span leaf="">&nbsp;(fileMagic == FileMagic.UNKNOWN) {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">String</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">suffix</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">=</span></span><span leaf="">&nbsp;FileUtil.getSuffix(wordFile.getName());</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">if</span></span><span leaf="">&nbsp;(StrUtil.equalsIgnoreCase(suffix,&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(165, 214, 255);"><span leaf="">"docx"</span></span><span leaf="">)) {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; fileMagic = FileMagic.OOXML;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; }&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">else</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">if</span></span><span leaf="">&nbsp;(StrUtil.equalsIgnoreCase(suffix,&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(165, 214, 255);"><span leaf="">"doc"</span></span><span leaf="">)) {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; fileMagic = FileMagic.OLE2;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; }</span><span leaf=""><br></span><span leaf="">}</span><span leaf=""><br></span><span leaf=""><br></span><span leaf="">log.info(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(165, 214, 255);"><span leaf="">"检测到文件格式: {}, 文件: {}"</span></span><span leaf="">, fileMagic, wordFile.getAbsolutePath());</span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// 根据文件格式选择不同的处理方式</span></span><span leaf=""><br></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">switch</span></span><span leaf="">&nbsp;(fileMagic) {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">case</span></span><span leaf="">&nbsp;OOXML -&gt; {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// DOCX 格式 - 使用自定义表格解析器</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; log.info(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(165, 214, 255);"><span leaf="">"DOCX格式使用自定义表格解析器"</span></span><span leaf="">);</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; transfer = processDocxWithHtmlTable(wordFile, target);</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; }</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">case</span></span><span leaf="">&nbsp;OLE2 -&gt; {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// DOC 格式 - 使用新的HTML表格支持</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; transfer = processDocWithHtmlTable(wordFile, target);</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; }</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">default</span></span><span leaf="">&nbsp;-&gt; {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; log.warn(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(165, 214, 255);"><span leaf="">"不支持的文件格式: {}, 使用默认处理方式"</span></span><span leaf="">, fileMagic);</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// 回退到原始转换</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; target = toMarkdown(wordFile, pictures);</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; transfer =&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">true</span></span><span leaf="">;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; }</span><span leaf=""><br></span><span leaf="">}</span></code></pre> <h3 data-heading="true" style="box-sizing: border-box;border-width: 0px 0px 1px 4px;border-style: solid solid dashed;border-color: rgb(229, 229, 229) rgb(229, 229, 229) rgb(59, 53, 53) rgb(59, 53, 53);font-size: 19.2px;font-weight: bold;margin: 2em 8px 0.75em 0px;text-align: left;line-height: 1.2;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;padding-left: 12px;color: rgb(63, 63, 63);><span leaf="">2. DOCX格式处理策略</span></h3> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">核心思路</span></strong><span leaf="">:利用DOCX格式的标准化特性,采用"预处理+替换"模式</span></p> <blockquote style="box-sizing: border-box;border-width: 0px 0px 0px 4px;border-style: solid;border-color: rgb(229, 229, 229) rgb(229, 229, 229) rgb(229, 229, 229) rgb(59, 53, 53);margin: 0px 0px 1em;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;font-style: italic;padding: 1em 2em;border-radius: 6px;color: rgba(0, 0, 0.6);background: rgb(247, 247, 247);box-shadow: 0.05) 0px 4px 6px;> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 0px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 1em;display: block;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">利用WordTableParser类,单独精准解析docx格式中的所有表格。然后在Tika处理完的Content内容上,做replace替换。</span></p> </blockquote> <pre style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;margin: 10px 8px;color: rgb(201, 209, 217);background: rgb(13, 17, 23);text-align: left;line-height: 1.5;overflow-x: auto;border-radius: 8px;box-shadow: rgba(0, 0, 0.05) 0px inset;padding: !important;><span hidden style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);display: flex;padding: 10px 14px 0px;"> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" width="45px" height="13px" viewbox="0 0 450 130"> <ellipse cx="50" cy="65" rx="50" ry="52" stroke="rgb(220,60,54)" stroke-width="2" fill="rgb(237,108,96)"></ellipse><ellipse cx="225" cy="65" rx="50" ry="52" stroke="rgb(218,151,33)" stroke-width="2" fill="rgb(247,193,81)"></ellipse><ellipse cx="400" cy="65" rx="50" ry="52" stroke="rgb(27,161,37)" stroke-width="2" fill="rgb(100,200,86)"></ellipse> </svg></span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: " fira code, menlo, operator mono, consolas, monaco, monospace;font-feature-settings: normal;font-variation-settings: normal;font-size: 12.96px;display: -webkit-box;padding: 0.5em 1em 1em;overflow-x: auto;text-indent: 0px;text-align: left;line-height: 1.75;margin: 0px;white-space: nowrap;><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">private</span></span><span leaf="">&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">static</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">boolean</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(210, 168, 255);"><span leaf="">processDocxWithHtmlTable</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);"><span leaf="">(File docxFile, File target)</span></span><span leaf="">&nbsp;{</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// 1. 预处理阶段:使用WordTableParser精准解析表格</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">XWPFDocument</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">document</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">=</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">new</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(210, 168, 255);"><span leaf="">XWPFDocument</span></span><span leaf="">(inputStream);</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">WordTableParser</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">wordTableParser</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">=</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">new</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(210, 168, 255);"><span leaf="">WordTableParser</span></span><span leaf="">();</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; List <string> customTablesHtmlList = wordTableParser.parseToHtmlList(document); </string></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// 2. 常规解析:使用Tika进行流式解析</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">AutoDetectParser</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">parser</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">=</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">new</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(210, 168, 255);"><span leaf="">AutoDetectParser</span></span><span leaf="">();</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; parser.parse(parseStream, textHandler, metadata, parseContext);</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// 3. 智能替换:用精准的表格HTML替换Tika的粗糙输出</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">String</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">finalContent</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">=</span></span><span leaf="">&nbsp;replaceTablesWithCustomHtmlList(tikaContent, customTablesHtmlList);</span><span leaf=""><br></span><span leaf="">}</span></code></pre> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">因为docx格式是相对标准的格式,POI在底层上给我们封装了非常强大的上层API供开发者调用,能够拿到docx中的所有table元素对象,这样让我们在处理表格合并时更方便。</span></p> <pre style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;margin: 10px 8px;color: rgb(201, 209, 217);background: rgb(13, 17, 23);text-align: left;line-height: 1.5;overflow-x: auto;border-radius: 8px;box-shadow: rgba(0, 0, 0.05) 0px inset;padding: !important;><span hidden style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);display: flex;padding: 10px 14px 0px;"> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" width="45px" height="13px" viewbox="0 0 450 130"> <ellipse cx="50" cy="65" rx="50" ry="52" stroke="rgb(220,60,54)" stroke-width="2" fill="rgb(237,108,96)"></ellipse><ellipse cx="225" cy="65" rx="50" ry="52" stroke="rgb(218,151,33)" stroke-width="2" fill="rgb(247,193,81)"></ellipse><ellipse cx="400" cy="65" rx="50" ry="52" stroke="rgb(27,161,37)" stroke-width="2" fill="rgb(100,200,86)"></ellipse> </svg></span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: " fira code, menlo, operator mono, consolas, monaco, monospace;font-feature-settings: normal;font-variation-settings: normal;font-size: 12.96px;display: -webkit-box;padding: 0.5em 1em 1em;overflow-x: auto;text-indent: 0px;text-align: left;line-height: 1.75;margin: 0px;white-space: nowrap;><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">public</span></span><span leaf="">&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">class</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(210, 168, 255);"><span leaf="">WordTableParser</span></span><span leaf="">&nbsp;{</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">private</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">final</span></span><span leaf="">&nbsp;CellMergeAnalyzer cellMergeAnalyzer;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">private</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">final</span></span><span leaf="">&nbsp;HtmlTableBuilder htmlTableBuilder;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">public</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(210, 168, 255);"><span leaf="">WordTableParser</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);"><span leaf="">()</span></span><span leaf="">&nbsp;{</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 166, 87);"><span leaf="">this</span></span><span leaf="">.cellMergeAnalyzer =&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">new</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(210, 168, 255);"><span leaf="">CellMergeAnalyzer</span></span><span leaf="">();</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 166, 87);"><span leaf="">this</span></span><span leaf="">.htmlTableBuilder =&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">new</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(210, 168, 255);"><span leaf="">HtmlTableBuilder</span></span><span leaf="">();</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; }</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">public</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(210, 168, 255);"><span leaf="">WordTableParser</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);"><span leaf="">(CellMergeAnalyzer cellMergeAnalyzer, HtmlTableBuilder htmlTableBuilder)</span></span><span leaf="">&nbsp;{</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 166, 87);"><span leaf="">this</span></span><span leaf="">.cellMergeAnalyzer = cellMergeAnalyzer;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 166, 87);"><span leaf="">this</span></span><span leaf="">.htmlTableBuilder = htmlTableBuilder;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; }</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">/**</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp;* 解析 Word 文档中的所有表格为 HTML</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp;*/</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">public</span></span><span leaf="">&nbsp;String&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(210, 168, 255);"><span leaf="">parseToHtml</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);"><span leaf="">(XWPFDocument document)</span></span><span leaf="">&nbsp;{</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// 拿到所有table</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; List <xwpftable> tables = document.getTables(); </xwpftable></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; log.info(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(165, 214, 255);"><span leaf="">"开始解析Word表格,共 {} 个表格"</span></span><span leaf="">, tables.size());</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">StringBuilder</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">html</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">=</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">new</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(210, 168, 255);"><span leaf="">StringBuilder</span></span><span leaf="">();</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">for</span></span><span leaf="">&nbsp;(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">int</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">i</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">=</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">0</span></span><span leaf="">; i &lt; tables.size(); i++) {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">XWPFTable</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">table</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">=</span></span><span leaf="">&nbsp;tables.get(i);</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.info(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(165, 214, 255);"><span leaf="">"解析第 {} 个表格,包含 {} 行"</span></span><span leaf="">, i +&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">1</span></span><span leaf="">, table.getRows().size());</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; html.append(parseTableToHtml(table));</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">if</span></span><span leaf="">&nbsp;(i &lt; tables.size() -&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">1</span></span><span leaf="">) {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; html.append(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(165, 214, 255);"><span leaf="">"<br><br>\n"</span></span><span leaf="">);</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; }</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">return</span></span><span leaf="">&nbsp;html.toString();</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; }</span><span leaf=""><br></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// more.... &nbsp;&nbsp;</span></span><span leaf=""><br></span><span leaf="">}</span></code></pre> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">我们在处理docx格式时,抽象一个CellMergeAnalyzer的来处理表格合并的情况。</span></p> <h3 data-heading="true" style="box-sizing: border-box;border-width: 0px 0px 1px 4px;border-style: solid solid dashed;border-color: rgb(229, 229, 229) rgb(229, 229, 229) rgb(59, 53, 53) rgb(59, 53, 53);font-size: 19.2px;font-weight: bold;margin: 2em 8px 0.75em 0px;text-align: left;line-height: 1.2;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;padding-left: 12px;color: rgb(63, 63, 63);><span leaf="">3. DOC格式处理策略</span></h3> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">核心思路</span></strong><span leaf="">:直接在解析过程中注入我们的表格处理逻辑</span></p> <blockquote style="box-sizing: border-box;border-width: 0px 0px 0px 4px;border-style: solid;border-color: rgb(229, 229, 229) rgb(229, 229, 229) rgb(229, 229, 229) rgb(59, 53, 53);margin: 0px 0px 1em;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;font-style: italic;padding: 1em 2em;border-radius: 6px;color: rgba(0, 0, 0.6);background: rgb(247, 247, 247);box-shadow: 0.05) 0px 4px 6px;> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 0px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 1em;display: block;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">扩写Tika下的Handler模块,单独处理doc格式的文件。</span></p> </blockquote> <pre style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;margin: 10px 8px;color: rgb(201, 209, 217);background: rgb(13, 17, 23);text-align: left;line-height: 1.5;overflow-x: auto;border-radius: 8px;box-shadow: rgba(0, 0, 0.05) 0px inset;padding: !important;><span hidden style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);display: flex;padding: 10px 14px 0px;"> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" width="45px" height="13px" viewbox="0 0 450 130"> <ellipse cx="50" cy="65" rx="50" ry="52" stroke="rgb(220,60,54)" stroke-width="2" fill="rgb(237,108,96)"></ellipse><ellipse cx="225" cy="65" rx="50" ry="52" stroke="rgb(218,151,33)" stroke-width="2" fill="rgb(247,193,81)"></ellipse><ellipse cx="400" cy="65" rx="50" ry="52" stroke="rgb(27,161,37)" stroke-width="2" fill="rgb(100,200,86)"></ellipse> </svg></span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: " fira code, menlo, operator mono, consolas, monaco, monospace;font-feature-settings: normal;font-variation-settings: normal;font-size: 12.96px;display: -webkit-box;padding: 0.5em 1em 1em;overflow-x: auto;text-indent: 0px;text-align: left;line-height: 1.75;margin: 0px;white-space: nowrap;><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">private</span></span><span leaf="">&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">static</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">boolean</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(210, 168, 255);"><span leaf="">processDocWithHtmlTable</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);"><span leaf="">(File docFile, File target)</span></span><span leaf="">&nbsp;{</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// 使用专门的DOC内容处理器</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">DocMarkdownWithHtmlTableContentHandler</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">handler</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">=</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">new</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(210, 168, 255);"><span leaf="">DocMarkdownWithHtmlTableContentHandler</span></span><span leaf="">();</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; handler.setCurrentDocument(document);</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// 在解析过程中实时应用我们的表格算法</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">DocXMarkdownWithHtmlTableContentHandler</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">textHandler</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">=</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">new</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(210, 168, 255);"><span leaf="">DocXMarkdownWithHtmlTableContentHandler</span></span><span leaf="">(handler, metadata);</span><span leaf=""><br></span><span leaf="">}</span></code></pre> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">doc格式和docx天然差异,可以算是一个新文件类型也不为过,对于表格的解析合并内容,会有明显的不同。</span></p> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">主要体现在提取的Table元素,并不能很好的获取单元格合并信息,需要有一套</span><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">通用的合并单元格识别算法</span></strong></p> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">我们的在</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">DocumentTableParser</span></code><span leaf="">实现了</span><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">完全基于表格结构特征的通用算法</span></strong><span leaf="">,不依赖任何具体内容:</span></p> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">1. 数据结构构建</span></strong></p> <pre style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;margin: 10px 8px;color: rgb(201, 209, 217);background: rgb(13, 17, 23);text-align: left;line-height: 1.5;overflow-x: auto;border-radius: 8px;box-shadow: rgba(0, 0, 0.05) 0px inset;padding: !important;><span hidden style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);display: flex;padding: 10px 14px 0px;"> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" width="45px" height="13px" viewbox="0 0 450 130"> <ellipse cx="50" cy="65" rx="50" ry="52" stroke="rgb(220,60,54)" stroke-width="2" fill="rgb(237,108,96)"></ellipse><ellipse cx="225" cy="65" rx="50" ry="52" stroke="rgb(218,151,33)" stroke-width="2" fill="rgb(247,193,81)"></ellipse><ellipse cx="400" cy="65" rx="50" ry="52" stroke="rgb(27,161,37)" stroke-width="2" fill="rgb(100,200,86)"></ellipse> </svg></span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: " fira code, menlo, operator mono, consolas, monaco, monospace;font-feature-settings: normal;font-variation-settings: normal;font-size: 12.96px;display: -webkit-box;padding: 0.5em 1em 1em;overflow-x: auto;text-indent: 0px;text-align: left;line-height: 1.75;margin: 0px;white-space: nowrap;><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// 构建表格数据矩阵</span></span><span leaf=""><br></span><span leaf="">String[][] cellContents =&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">new</span></span><span leaf="">&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(210, 168, 255);"><span leaf="">String</span></span><span leaf="">[numRows][];</span><span leaf=""><br></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">int</span></span><span leaf="">[] rowCellCounts =&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">new</span></span><span leaf="">&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(210, 168, 255);"><span leaf="">int</span></span><span leaf="">[numRows];</span></code></pre> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">2. 列合并检测算法</span></strong></p> <pre style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;margin: 10px 8px;color: rgb(201, 209, 217);background: rgb(13, 17, 23);text-align: left;line-height: 1.5;overflow-x: auto;border-radius: 8px;box-shadow: rgba(0, 0, 0.05) 0px inset;padding: !important;><span hidden style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);display: flex;padding: 10px 14px 0px;"> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" width="45px" height="13px" viewbox="0 0 450 130"> <ellipse cx="50" cy="65" rx="50" ry="52" stroke="rgb(220,60,54)" stroke-width="2" fill="rgb(237,108,96)"></ellipse><ellipse cx="225" cy="65" rx="50" ry="52" stroke="rgb(218,151,33)" stroke-width="2" fill="rgb(247,193,81)"></ellipse><ellipse cx="400" cy="65" rx="50" ry="52" stroke="rgb(27,161,37)" stroke-width="2" fill="rgb(100,200,86)"></ellipse> </svg></span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: " fira code, menlo, operator mono, consolas, monaco, monospace;font-feature-settings: normal;font-variation-settings: normal;font-size: 12.96px;display: -webkit-box;padding: 0.5em 1em 1em;overflow-x: auto;text-indent: 0px;text-align: left;line-height: 1.75;margin: 0px;white-space: nowrap;><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">private</span></span><span leaf="">&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">static</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">int</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(210, 168, 255);"><span leaf="">detectColspanByStructure</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);"><span leaf="">(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">int</span></span><span leaf="">&nbsp;rowIndex,&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">int</span></span><span leaf="">&nbsp;cellIndex,&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; String[][] cellContents,&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">int</span></span><span leaf="">[] rowCellCounts,&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">int</span></span><span leaf="">&nbsp;maxCols)</span></span><span leaf="">&nbsp;{</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">int</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">currentRowCells</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">=</span></span><span leaf="">&nbsp;rowCellCounts[rowIndex];</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// 如果当前行只有1个单元格,占满整行</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">if</span></span><span leaf="">&nbsp;(currentRowCells ==&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">1</span></span><span leaf="">) {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">return</span></span><span leaf="">&nbsp;maxCols;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; }</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// 智能分配列数</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">int</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">averageColspan</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">=</span></span><span leaf="">&nbsp;maxCols / currentRowCells;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">int</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">remainingCols</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">=</span></span><span leaf="">&nbsp;maxCols % currentRowCells;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// 最后一个单元格处理剩余空间</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">if</span></span><span leaf="">&nbsp;(cellIndex == currentRowCells -&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">1</span></span><span leaf="">&nbsp;&amp;&amp; remainingCols &gt;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">0</span></span><span leaf="">) {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">return</span></span><span leaf="">&nbsp;averageColspan + remainingCols;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; }</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">return</span></span><span leaf="">&nbsp;averageColspan &gt;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">0</span></span><span leaf="">&nbsp;? averageColspan :&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">1</span></span><span leaf="">;</span><span leaf=""><br></span><span leaf="">}</span></code></pre> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">3. 行合并检测算法</span></strong></p> <pre style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;margin: 10px 8px;color: rgb(201, 209, 217);background: rgb(13, 17, 23);text-align: left;line-height: 1.5;overflow-x: auto;border-radius: 8px;box-shadow: rgba(0, 0, 0.05) 0px inset;padding: !important;><span hidden style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);display: flex;padding: 10px 14px 0px;"> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" width="45px" height="13px" viewbox="0 0 450 130"> <ellipse cx="50" cy="65" rx="50" ry="52" stroke="rgb(220,60,54)" stroke-width="2" fill="rgb(237,108,96)"></ellipse><ellipse cx="225" cy="65" rx="50" ry="52" stroke="rgb(218,151,33)" stroke-width="2" fill="rgb(247,193,81)"></ellipse><ellipse cx="400" cy="65" rx="50" ry="52" stroke="rgb(27,161,37)" stroke-width="2" fill="rgb(100,200,86)"></ellipse> </svg></span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: " fira code, menlo, operator mono, consolas, monaco, monospace;font-feature-settings: normal;font-variation-settings: normal;font-size: 12.96px;display: -webkit-box;padding: 0.5em 1em 1em;overflow-x: auto;text-indent: 0px;text-align: left;line-height: 1.75;margin: 0px;white-space: nowrap;><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">private</span></span><span leaf="">&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">static</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">int</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(210, 168, 255);"><span leaf="">detectRowspanByStructure</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);"><span leaf="">(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">int</span></span><span leaf="">&nbsp;rowIndex,&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">int</span></span><span leaf="">&nbsp;cellIndex,&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; String cellText, String[][] cellContents,&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">int</span></span><span leaf="">[] rowCellCounts)</span></span><span leaf="">&nbsp;{</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// 检查向下相邻行的对应位置</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">int</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">rowspan</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">=</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">1</span></span><span leaf="">;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">for</span></span><span leaf="">&nbsp;(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">int</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">nextRow</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">=</span></span><span leaf="">&nbsp;rowIndex +&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">1</span></span><span leaf="">; nextRow &lt; cellContents.length; nextRow++) {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">String</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">nextCellText</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">=</span></span><span leaf="">&nbsp;cellContents[nextRow][cellIndex];</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">if</span></span><span leaf="">&nbsp;(nextCellText.trim().isEmpty()) {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// 进一步验证:检查该行是否有其他内容</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">boolean</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">hasContentInRow</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">=</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">false</span></span><span leaf="">;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">for</span></span><span leaf="">&nbsp;(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">int</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">i</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">=</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">0</span></span><span leaf="">; i &lt; rowCellCounts[nextRow]; i++) {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">if</span></span><span leaf="">&nbsp;(!cellContents[nextRow][i].trim().isEmpty()) {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hasContentInRow =&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">true</span></span><span leaf="">;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">break</span></span><span leaf="">;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">if</span></span><span leaf="">&nbsp;(hasContentInRow) {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rowspan++;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">else</span></span><span leaf="">&nbsp;{</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">break</span></span><span leaf="">;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// 整行为空,不是rowspan</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">else</span></span><span leaf="">&nbsp;{</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">break</span></span><span leaf="">;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// 遇到非空单元格,rowspan结束</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; }</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; }</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">return</span></span><span leaf="">&nbsp;rowspan;</span><span leaf=""><br></span><span leaf="">}</span></code></pre> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">4. 智能跳过算法</span></strong></p> <pre style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;margin: 10px 8px;color: rgb(201, 209, 217);background: rgb(13, 17, 23);text-align: left;line-height: 1.5;overflow-x: auto;border-radius: 8px;box-shadow: rgba(0, 0, 0.05) 0px inset;padding: !important;><span hidden style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);display: flex;padding: 10px 14px 0px;"> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" width="45px" height="13px" viewbox="0 0 450 130"> <ellipse cx="50" cy="65" rx="50" ry="52" stroke="rgb(220,60,54)" stroke-width="2" fill="rgb(237,108,96)"></ellipse><ellipse cx="225" cy="65" rx="50" ry="52" stroke="rgb(218,151,33)" stroke-width="2" fill="rgb(247,193,81)"></ellipse><ellipse cx="400" cy="65" rx="50" ry="52" stroke="rgb(27,161,37)" stroke-width="2" fill="rgb(100,200,86)"></ellipse> </svg></span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: " fira code, menlo, operator mono, consolas, monaco, monospace;font-feature-settings: normal;font-variation-settings: normal;font-size: 12.96px;display: -webkit-box;padding: 0.5em 1em 1em;overflow-x: auto;text-indent: 0px;text-align: left;line-height: 1.75;margin: 0px;white-space: nowrap;><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">private</span></span><span leaf="">&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">static</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">boolean</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(210, 168, 255);"><span leaf="">shouldSkipCellByStructure</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);"><span leaf="">(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">int</span></span><span leaf="">&nbsp;rowIndex,&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">int</span></span><span leaf="">&nbsp;cellIndex,&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; String cellText, String[][] cellContents,&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">int</span></span><span leaf="">[] rowCellCounts)</span></span><span leaf="">&nbsp;{</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// 向上查找可能的rowspan源</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">for</span></span><span leaf="">&nbsp;(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">int</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">prevRow</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">=</span></span><span leaf="">&nbsp;rowIndex -&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">1</span></span><span leaf="">; prevRow &gt;=&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">0</span></span><span leaf="">; prevRow--) {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">if</span></span><span leaf="">&nbsp;(cellIndex &lt; rowCellCounts[prevRow]) {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">String</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">prevCellText</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">=</span></span><span leaf="">&nbsp;cellContents[prevRow][cellIndex];</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">if</span></span><span leaf="">&nbsp;(!prevCellText.trim().isEmpty()) {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// 重新计算该单元格的rowspan</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">int</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">calculatedRowspan</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">=</span></span><span leaf="">&nbsp;calculateRowspanFromPosition(</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; prevRow, cellIndex, cellContents, rowCellCounts);</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// 判断是否覆盖到当前行</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">if</span></span><span leaf="">&nbsp;(prevRow + calculatedRowspan &gt; rowIndex) {</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">return</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">true</span></span><span leaf="">;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(139, 148, 158);"><span leaf="">// 跳过被占用的单元格</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; }</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; }</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(255, 123, 114);"><span leaf="">return</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(121, 192, 255);"><span leaf="">false</span></span><span leaf="">;</span><span leaf=""><br></span><span leaf="">}</span></code></pre> <h2 data-heading="true" style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-size: 20.8px;font-weight: bold;margin: 4em auto 2em;text-align: center;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;display: table;padding: 0.3em 1em;color: rgb(255, 255, 255);background: rgb(59, 53, 53);border-radius: 8px;box-shadow: rgba(0, 0, 0.1) 0px 4px 6px;><span leaf="">五、解析效果验证</span></h2> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">我让大语言模型帮我创建了30种不同格式的复杂表格类型,包括上下单元格合并、跨页表格、左右单元格合并等多种复杂的情况,验证了doc/docx两种格式。主要表现如下:</span></p> <ul style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);list-style: none;margin: 0px;padding: 0px 0px 0px 1.5em;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;color: rgb(63, 63, 63); class="list-paddingleft-1"> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• ✅ 完美识别</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">rowspan</span></code><span leaf="">和</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">colspan</span></code><span leaf="">合并单元格</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• ✅ 准确保留所有表格内容,无丢失现象</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• ✅ 正确处理跨页表格和复杂嵌套结构</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• ✅ 支持任意语言和字符集的表格内容</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• ✅ 在.doc和.docx格式上表现一致(目前doc格式无法提取markdown的header标题)</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• ✅ 正确提取图片以及图片位置正确</span> </section></li> </ul> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">在31个复杂表格情况下,对于表格的合并情况:</span></p> <ul style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);list-style: none;margin: 0px;padding: 0px 0px 0px 1.5em;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;color: rgb(63, 63, 63); class="list-paddingleft-1"> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• ✅ 数据无错误,表格内容没错误的情况比例:30/31=96.8%</span> <blockquote style="box-sizing: border-box;border-width: 0px 0px 0px 4px;border-style: solid;border-color: rgb(229, 229, 229) rgb(229, 229, 229) rgb(229, 229, 229) rgb(59, 53, 53);margin: 0px 0px 1em;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;font-style: italic;padding: 1em 2em;border-radius: 6px;color: rgba(0, 0, 0.6);background: rgb(247, 247, 247);box-shadow: 0.05) 0px 4px 6px;> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 0px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 1em;display: block;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">包含数据完全正确,目前出现6个表格会出现数据没异常的情况,但是表格在纵向合并的情况并没有表现一致的情况</span></p> </blockquote> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• ✅ 数据解析异常,错误比率:1/31=3.23%</span> <blockquote style="box-sizing: border-box;border-width: 0px 0px 0px 4px;border-style: solid;border-color: rgb(229, 229, 229) rgb(229, 229, 229) rgb(229, 229, 229) rgb(59, 53, 53);margin: 0px 0px 1em;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;font-style: italic;padding: 1em 2em;border-radius: 6px;color: rgba(0, 0, 0.6);background: rgb(247, 247, 247);box-shadow: 0.05) 0px 4px 6px;> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 0px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 1em;display: block;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">在31个复杂表格数据的情况下,出现了解析还原错误的情况,表格数据错位了的情况,这种情况在做知识库场景下送给大模型时,会导致数据异常、回答幻觉的情况发生</span></p> </blockquote> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• ✅ 表格完全正确,colspan/rowspan完全无错误的情况:25/31=80.6%</span> <blockquote style="box-sizing: border-box;border-width: 0px 0px 0px 4px;border-style: solid;border-color: rgb(229, 229, 229) rgb(229, 229, 229) rgb(229, 229, 229) rgb(59, 53, 53);margin: 0px 0px 1em;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;font-style: italic;padding: 1em 2em;border-radius: 6px;color: rgba(0, 0, 0.6);background: rgb(247, 247, 247);box-shadow: 0.05) 0px 4px 6px;> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 0px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 1em;display: block;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">数据完全一致、表格完全一致,100%还原出来的比例。</span></p> </blockquote> </section></li> </ul> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">1、简单的上下合并情况</span></p> </section> <section style="text-align: center;" nodeleaf=""> <img src="/upload/0244f3927c61aaccb6bc6d284a8c2d79.png" class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.4351851851851852" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="100000930"> </section> <section style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(10, 10, 10);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;> <figure style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;color: rgb(63, 63, 63);> <span leaf=""><br></span> <figcaption style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: center;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 0.8em;color: rgb(136, 136, 136);> <span leaf="">图1-</span><span leaf="" data-pm-slice="1 1 [" para,{tagname:section,attributes:{style:box-sizing: border-box; border-width: 0px; border-style: solid; border-color: rgb(229, 229, 229); color: rgb(10, 10, 10); font-style: normal; font-variant-ligatures: font-variant-caps: font-weight: 400; letter-spacing: orphans: 2; text-indent: text-transform: none; widows: word-spacing: -webkit-text-stroke-width: white-space: background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: text-decoration-color: text-align: left; line-height: 1.75; font-family: optima-regular, optima, pingfangsc-light, pingfangtc-light, \pingfang sc\, cambria, cochin, georgia, times, \times new roman\, serif; font-size: 16px;},namespaceuri:http: www.w3.org 1999 xhtml},para,{tagname:p,attributes:{style:box-sizing: margin: 1.5em 8px; 16px; 2em; 0.1em; rgb(63, 63, 63);},namespaceuri:http: xhtml}]>简单的上下合并情况</span> </figcaption> </figure> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">2、跨页上下单元格合并单元格的情况</span></p> </section> <section style="text-align: center;" nodeleaf=""> <img src="/upload/42e875233f67d1272cb81c5bebb0004d.png" class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.5675925925925925" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="100000931"> </section> <section style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(10, 10, 10);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;> <figure style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;color: rgb(63, 63, 63);> <span leaf=""><br></span> <figcaption style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: center;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 0.8em;color: rgb(136, 136, 136);> <span leaf="">图2-</span><span leaf="" data-pm-slice="1 1 [" para,{tagname:section,attributes:{style:box-sizing: border-box; border-width: 0px; border-style: solid; border-color: rgb(229, 229, 229); color: rgb(10, 10, 10); font-style: normal; font-variant-ligatures: font-variant-caps: font-weight: 400; letter-spacing: orphans: 2; text-indent: text-transform: none; widows: word-spacing: -webkit-text-stroke-width: white-space: background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: text-decoration-color: text-align: left; line-height: 1.75; font-family: optima-regular, optima, pingfangsc-light, pingfangtc-light, \pingfang sc\, cambria, cochin, georgia, times, \times new roman\, serif; font-size: 16px;},namespaceuri:http: www.w3.org 1999 xhtml},para,{tagname:p,attributes:{style:box-sizing: margin: 1.5em 8px; 16px; 2em; 0.1em; rgb(63, 63, 63);},namespaceuri:http: xhtml}]>跨页上下单元格合并单元格的情况</span> </figcaption> </figure> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">3、上下左右单元格合并的情况</span></p> </section> <section style="text-align: center;" nodeleaf=""> <img src="/upload/dafbbce47593de166bd03e4b5c2a0d99.png" class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.34814814814814815" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="100000932"> </section> <section style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(10, 10, 10);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;> <figure style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;color: rgb(63, 63, 63);> <span leaf=""><br></span> <figcaption style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: center;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 0.8em;color: rgb(136, 136, 136);> <span leaf="">图3-上下左右单元格合并的情况</span> </figcaption> </figure> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">4、翻页单元格上下左右合并的情况</span></p> <figure style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;color: rgb(63, 63, 63);> <span leaf=""><br></span> </figure> </section> <section style="text-align: center;" nodeleaf=""> <img src="/upload/c3f2d1abab64ad85d60e66f7589273f0.png" class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.47962962962962963" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="100000933"> </section> <section style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(10, 10, 10);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;> <figure style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;color: rgb(63, 63, 63);> <span leaf=""><br></span> <figcaption style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: center;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 0.8em;color: rgb(136, 136, 136);> <span leaf="">图4-翻页单元格上下左右合并的情况</span> </figcaption> </figure> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">5、更复杂的纵向横向表格合并情况</span></p> </section> <section style="text-align: center;" nodeleaf=""> <img src="/upload/c55583d4984e279d822f0443abd18ae5.png" class="rich_pages wxw-img js_insertlocalimg" data-ratio="0.37222222222222223" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="100000934"> </section> <section style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(10, 10, 10);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;> <figure style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;color: rgb(63, 63, 63);> <span leaf=""><br></span> <figcaption style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);text-align: center;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 0.8em;color: rgb(136, 136, 136);> <span leaf="">图5-更复杂的纵向横向表格合并情况</span> </figcaption> </figure> <h2 data-heading="true" style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-size: 20.8px;font-weight: bold;margin: 4em auto 2em;text-align: center;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;display: table;padding: 0.3em 1em;color: rgb(255, 255, 255);background: rgb(59, 53, 53);border-radius: 8px;box-shadow: rgba(0, 0, 0.1) 0px 4px 6px;><span leaf="">六、100%开源</span></h2> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">TorchV 的企业级 AI 知识库系统,是在开源生态的基础上构建而成的。从创业初期开始,我们便充分受益于业界开源的各种大语言模型、Embedding 模型、Reranker 模型、开源组件/中间件等,这些技术的开放极大地推动了行业的发展。我们深知开源的价值,也始终秉持开放、共享、共建的理念。</span></p> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">在构建开发产品的过程中,特别是在 Word 文档解析这一关键环节,我们团队进行了深入的研究和持续的优化,并在实践中取得了一些突破。尽管当前的解析组件仍存在一些待完善之处,或在测试覆盖面上尚有不足,通过开源的形式开放出来,希望借此与更多开发者携手,共同完善这一能力模块,推动行业工具链的进步。</span></p> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">我们诚挚欢迎社区开发者参与共建,一起打磨这项通用而关键的能力。</span></p> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">GitHub:https://github.com/torchv/torchv-unstructured</span></strong></p> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-weight: bold;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: inherit;color: rgb(59, 53, 53);><span leaf="">Gitee: https://gitee.com/torchv/torchv-unstructured</span></strong></p> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 1.5em 8px;text-align: left;line-height: 1.75;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-size: 16px;text-indent: 2em;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">该仓库是一个Java项目,1.0.0版本已经推送Maven中央仓库,坐标地址:</span></p> <pre style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14.4px;margin: 10px 8px;color: rgb(201, 209, 217);background: rgb(13, 17, 23);text-align: left;line-height: 1.5;overflow-x: auto;border-radius: 8px;box-shadow: rgba(0, 0, 0.05) 0px inset;padding: !important;><span hidden style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);display: flex;padding: 10px 14px 0px;"> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" width="45px" height="13px" viewbox="0 0 450 130"> <ellipse cx="50" cy="65" rx="50" ry="52" stroke="rgb(220,60,54)" stroke-width="2" fill="rgb(237,108,96)"></ellipse><ellipse cx="225" cy="65" rx="50" ry="52" stroke="rgb(218,151,33)" stroke-width="2" fill="rgb(247,193,81)"></ellipse><ellipse cx="400" cy="65" rx="50" ry="52" stroke="rgb(27,161,37)" stroke-width="2" fill="rgb(100,200,86)"></ellipse> </svg></span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);font-family: " fira code, menlo, operator mono, consolas, monaco, monospace;font-feature-settings: normal;font-variation-settings: normal;font-size: 12.96px;display: -webkit-box;padding: 0.5em 1em 1em;overflow-x: auto;text-indent: 0px;text-align: left;line-height: 1.75;margin: 0px;white-space: nowrap;><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);"><span leaf="">&lt;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(126, 231, 135);"><span leaf="">dependency</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);"><span leaf="">&lt;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(126, 231, 135);"><span leaf="">groupId</span></span><span leaf="">&gt;</span></span><span leaf="">com.torchv.infra</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);"><span leaf=""><!--/</span--><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(126, 231, 135);"><span leaf="">groupId</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);"><span leaf="">&lt;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(126, 231, 135);"><span leaf="">artifactId</span></span><span leaf="">&gt;</span></span><span leaf="">torchv-unstructured</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);"><span leaf=""><!--/</span--><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(126, 231, 135);"><span leaf="">artifactId</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp;&nbsp;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);"><span leaf="">&lt;</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(126, 231, 135);"><span leaf="">version</span></span><span leaf="">&gt;</span></span><span leaf="">1.0.0</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);"><span leaf=""><!--/</span--><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(126, 231, 135);"><span leaf="">version</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);"><span leaf=""><!--/</span--><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);color: rgb(126, 231, 135);"><span leaf="">dependency</span></span><span leaf="">&gt;</span></span></span></span></span></span></code></pre> </section> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: rgb(229, 229, 229);margin: 0px;color: rgb(10, 10, 10);font-family: ui-sans-serif, system-ui, sans-serif, " apple color emoji, segoe ui symbol, noto emoji;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 0px;line-height: 0;><span leaf="">&nbsp;</span></p> <section> <span leaf=""><br></span> </section> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>

看完 Cursor 记忆系统提示词,我收获满满!

作者:微信小助手

<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;font-family: 'SF Pro SC', 'HanHei SC', 'SF Pro Text', 'Myriad Set Pro', 'SF Pro Icons', 'Apple Legacy Chevron', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, sans-serif;font-size: 16px;color: rgb(0, 0, 0);line-height: 1.5em;word-spacing: 0em;letter-spacing: 0em;word-break: break-word;overflow-wrap: break-word;text-align: left;padding-top: 10px;padding-right: 10px;padding-bottom: 10px;padding-left: 10px;" data-pm-slice="0 0 []"> <p data-tool="mdnice编辑器" style="color: rgba(0, 0, 0, 0.85);font-size: 16px;line-height: 1.75;letter-spacing: 0.1em;text-align: left;text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;margin-top: 5px;margin-right: 0px;margin-bottom: 5px;margin-left: 0px;word-spacing: 0.1em;"><span leaf="">前不久看了&nbsp;</span><code style="line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);color: rgb(231, 142, 52);font-size: 15px;overflow-wrap: break-word;padding-top: 2px;padding-right: 4px;padding-bottom: 2px;padding-left: 4px;border-top-left-radius: 3px;border-top-right-radius: 3px;border-bottom-right-radius: 3px;border-bottom-left-radius: 3px;margin-top: 0px;margin-right: 2px;margin-bottom: 0px;margin-left: 2px;background-color: rgb(255, 246, 237);font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools</span></code><span leaf="">&nbsp;这个项目里逆向解析的&nbsp;</span><code style="line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);color: rgb(231, 142, 52);font-size: 15px;overflow-wrap: break-word;padding-top: 2px;padding-right: 4px;padding-bottom: 2px;padding-left: 4px;border-top-left-radius: 3px;border-top-right-radius: 3px;border-bottom-right-radius: 3px;border-bottom-left-radius: 3px;margin-top: 0px;margin-right: 2px;margin-bottom: 0px;margin-left: 2px;background-color: rgb(255, 246, 237);font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Cursor</span></code><span leaf="">&nbsp;记忆系统提示词。从中既能学习到提示词的搭建技巧,又能一窥记忆系统的运作原理,读下来收获满满,值得好好琢磨借鉴。</span></p> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: block;text-align: center;background-position-x: center;background-position-y: center;background-repeat: no-repeat;background-attachment: initial;background-origin: initial;background-clip: initial;background-size: 46px;"><span data-cacheurl="" data-remoteid="" style="display: inline-block;background-size: 100% 100%;background-repeat: no-repeat;width: 28px;height: 28px;margin-bottom: -6px;margin-right: 0px;background-image: url(" https: mmbiz.qpic.cn mmbiz_gif hb9x3yucnoy9gwwicpgqoleqvpgtzgfibjfiopqagld8pecjgic5mnvsjlnl0ckrfric77e0d7oibirafzonoljatvw 640?wx_fmt="gif&amp;from=appmsg&quot;);&quot;"></span><span style="display: none;"></span><span style="font-size: 18px;color: rgb(231, 142, 52);line-height: 60px;letter-spacing: 0em;text-align: center;font-weight: bold;display: inline-block;height: 46px;background-position-x: left;background-position-y: center;background-repeat: no-repeat;background-attachment: initial;background-origin: initial;background-clip: initial;"><span leaf="">使用体验</span></span><span style="display: none;"></span></h2> <p data-tool="mdnice编辑器" style="color: rgba(0, 0, 0, 0.85);font-size: 16px;line-height: 1.75;letter-spacing: 0.1em;text-align: left;text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;margin-top: 5px;margin-right: 0px;margin-bottom: 5px;margin-left: 0px;word-spacing: 0.1em;"><span leaf="">首先我们先直观的体验一下Cursor记忆系统的效果。</span></p> <section nodeleaf=""> <iframe class="video_iframe rich_pages" src="https://mp.weixin.qq.com/mp/readtemplate?t=pages/video_player_tmpl&amp;action=mpvideo&amp;auto=0&amp;vid=wxv_4073662523180990469" data-mpvid="wxv_4073662523180990469" data-vidtype="2" data-cover="http%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2Fhb9x3YucNoY9gWwicPgQoleQVPGTZgfibjwslZmb0DxCe84yLkmnvEbicWLRoWwtvX3v6HlgaJWZBoYcB3Y2Vw7ibw%2F0%3Fwx_fmt%3Djpeg" data-ratio="1.7259259259259259" data-w="1864"></iframe> </section> <p data-tool="mdnice编辑器" style="color: rgba(0, 0, 0, 0.85);font-size: 16px;line-height: 1.75;letter-spacing: 0.1em;text-align: left;text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;margin-top: 5px;margin-right: 0px;margin-bottom: 5px;margin-left: 0px;word-spacing: 0.1em;"><span leaf="">可以看到 Cursor 会自动存储记忆点,并支持人工管理。</span></p> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: block;text-align: center;background-position-x: center;background-position-y: center;background-repeat: no-repeat;background-attachment: initial;background-origin: initial;background-clip: initial;background-size: 46px;"><span data-cacheurl="" data-remoteid="" style="display: inline-block;background-size: 100% 100%;background-repeat: no-repeat;width: 28px;height: 28px;margin-bottom: -6px;margin-right: 0px;background-image: url(" https: mmbiz.qpic.cn mmbiz_gif hb9x3yucnoy9gwwicpgqoleqvpgtzgfibjfiopqagld8pecjgic5mnvsjlnl0ckrfric77e0d7oibirafzonoljatvw 640?wx_fmt="gif&amp;from=appmsg&quot;);&quot;"></span><span style="display: none;"></span><span style="font-size: 18px;color: rgb(231, 142, 52);line-height: 60px;letter-spacing: 0em;text-align: center;font-weight: bold;display: inline-block;height: 46px;background-position-x: left;background-position-y: center;background-repeat: no-repeat;background-attachment: initial;background-origin: initial;background-clip: initial;"><span leaf="">记忆系统的组成</span></span><span style="display: none;"></span></h2> <p data-tool="mdnice编辑器" style="color: rgba(0, 0, 0, 0.85);font-size: 16px;line-height: 1.75;letter-spacing: 0.1em;text-align: left;text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;margin-top: 5px;margin-right: 0px;margin-bottom: 5px;margin-left: 0px;word-spacing: 0.1em;"><code style="line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);color: rgb(231, 142, 52);font-size: 15px;overflow-wrap: break-word;padding-top: 2px;padding-right: 4px;padding-bottom: 2px;padding-left: 4px;border-top-left-radius: 3px;border-top-right-radius: 3px;border-bottom-right-radius: 3px;border-bottom-left-radius: 3px;margin-top: 0px;margin-right: 2px;margin-bottom: 0px;margin-left: 2px;background-color: rgb(255, 246, 237);font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Cursor</span></code><span leaf="">&nbsp;的记忆系统由&nbsp;</span><strong style="color: rgba(0, 0, 0, 0.85);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><code style="line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);color: rgb(231, 142, 52);font-size: 15px;overflow-wrap: break-word;padding-top: 2px;padding-right: 4px;padding-bottom: 2px;padding-left: 4px;border-top-left-radius: 3px;border-top-right-radius: 3px;border-bottom-right-radius: 3px;border-bottom-left-radius: 3px;margin-top: 0px;margin-right: 2px;margin-bottom: 0px;margin-left: 2px;background-color: rgb(255, 246, 237);font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">记忆提取</span></code></strong><span leaf="">&nbsp;和&nbsp;</span><strong style="color: rgba(0, 0, 0, 0.85);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><code style="line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);color: rgb(231, 142, 52);font-size: 15px;overflow-wrap: break-word;padding-top: 2px;padding-right: 4px;padding-bottom: 2px;padding-left: 4px;border-top-left-radius: 3px;border-top-right-radius: 3px;border-bottom-right-radius: 3px;border-bottom-left-radius: 3px;margin-top: 0px;margin-right: 2px;margin-bottom: 0px;margin-left: 2px;background-color: rgb(255, 246, 237);font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">记忆评估</span></code></strong><span leaf="">&nbsp;模块组成。接下来我会描述其中的核心要点,并提供翻译后的完整内容。</span></p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 5px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: block;text-align: left;"><span style="display: none;"></span><span style="font-size: 16px;color: rgb(231, 142, 52);line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: bold;display: inline-block;"><span leaf="">记忆提取</span></span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="color: rgba(0, 0, 0, 0.85);font-size: 16px;line-height: 1.75;letter-spacing: 0.1em;text-align: left;text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;margin-top: 5px;margin-right: 0px;margin-bottom: 5px;margin-left: 0px;word-spacing: 0.1em;"><span leaf="">核心目的是从用户与助手的对话中主动识别值得记住的信息,生成符合标准的记忆条目。</span></p> <p data-tool="mdnice编辑器" style="color: rgba(0, 0, 0, 0.85);font-size: 16px;line-height: 1.75;letter-spacing: 0.1em;text-align: left;text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;margin-top: 5px;margin-right: 0px;margin-bottom: 5px;margin-left: 0px;word-spacing: 0.1em;"><span leaf="">其中的核心是告诉大模型哪些记忆应该提取,防止错误、模糊的记忆影响对话效果,比如:</span><strong style="color: rgba(0, 0, 0, 0.85);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">只提取明确的用户偏好信息(比如:优先用xx框架),避免提取模糊或显而易见且不可操作的偏好(比如: 一次性任务细节、临时上下文、模糊表述、基础软件工程原则(如 DRY、KISS)。</span></strong></p> <blockquote style="margin-top: 20px;margin-bottom: 20px;margin-left: 0px;margin-right: 0px;border-top-style: none;border-bottom-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;display: block;overflow-x: auto;overflow-y: auto;background-color: rgb(255, 249, 243);border-top-left-radius: 5px;border-top-right-radius: 5px;border-bottom-right-radius: 5px;border-bottom-left-radius: 5px;border-left-width: 5px;border-left-style: solid;border-left-color: rgb(231, 142, 52);padding-top: 18px;padding-right: 21px;padding-bottom: 18px;padding-left: 21px;"> <span style="display: none;color: rgb(0, 0, 0);font-size: 16px;line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: normal;"></span> <p style="text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;word-spacing: 0.1em;color: rgb(0, 0, 0);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;margin-top: 0px;margin-right: 0px;margin-bottom: 0px;margin-left: 0px;"><span leaf="">记忆提取 Prompt 由&nbsp;</span><code style="line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);color: rgb(231, 142, 52);font-size: 15px;overflow-wrap: break-word;padding-top: 2px;padding-right: 4px;padding-bottom: 2px;padding-left: 4px;border-top-left-radius: 3px;border-top-right-radius: 3px;border-bottom-right-radius: 3px;border-bottom-left-radius: 3px;margin-top: 0px;margin-right: 2px;margin-bottom: 0px;margin-left: 2px;background-color: rgb(255, 246, 237);font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">目标(task|target)、内容要求&amp;限制(requirements)、少样本案例(example)、输出格式要求(output)</span></code><span leaf="">&nbsp;几部分组成,是很经典的提示词组成结构,我们可以参考学习。</span></p> </blockquote> <p data-tool="mdnice编辑器" style="color: rgba(0, 0, 0, 0.85);font-size: 16px;line-height: 1.75;letter-spacing: 0.1em;text-align: left;text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;margin-top: 5px;margin-right: 0px;margin-bottom: 5px;margin-left: 0px;word-spacing: 0.1em;"><span leaf="">完整翻译内容如下:</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg 1chhx9yq4nhaomcbrvmaplx67nrccwjbhaefibyvmcxtmkllfxo7f5zgeia4uijsg3dnibfaop1cj6syw71yommolafks9fw9yh 640?wx_fmt="svg&amp;from=appmsg&quot;);&quot;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="line-height: 26px;"><span leaf="">&lt;</span><span style="color: #e06c75;line-height: 26px;"><span leaf="">目标</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf="">给定一段用户与助手的对话,你需要确定哪些信息可能对未来的对话有帮助,值得记住。</span><span leaf=""><br></span><span style="line-height: 26px;"><span leaf=""><!--/</span--><span style="color: #e06c75;line-height: 26px;"><span leaf="">目标</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="line-height: 26px;"><span leaf="">&lt;</span><span style="color: #e06c75;line-height: 26px;"><span leaf="">正面标准</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf="">值得记住的信息应包括:</span><span leaf=""><br></span><span leaf="">- 用户工作方式的高层级偏好(必须具体且可操作)</span><span leaf=""><br></span><span leaf="">- 用户偏爱的通用模式或方法(必须包含明确指导)</span><span leaf=""><br></span><span leaf="">- 具体的技术偏好(例如,确切的编码风格规则、框架选择)</span><span leaf=""><br></span><span leaf="">- 需要避免的常见痛点或用户不满点(必须足够具体以便采取行动)</span><span leaf=""><br></span><span leaf="">- 工作流程偏好或要求(必须包含具体步骤或规则)</span><span leaf=""><br></span><span leaf="">- 用户请求中的任何重复主题(必须足够具体以指导未来回应)</span><span leaf=""><br></span><span leaf="">- 用户明确要求记住的任何内容</span><span leaf=""><br></span><span leaf="">- 用户表达的任何强烈观点(必须足够具体以便采取行动)</span><span leaf=""><br></span><span style="line-height: 26px;"><span leaf=""><!--/</span--><span style="color: #e06c75;line-height: 26px;"><span leaf="">正面标准</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="line-height: 26px;"><span leaf="">&lt;</span><span style="color: #e06c75;line-height: 26px;"><span leaf="">负面标准</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf="">不应包含以下内容:</span><span leaf=""><br></span><span leaf="">- 无法通用化的一次性任务细节</span><span leaf=""><br></span><span leaf="">- 不会重复使用的实现细节</span><span leaf=""><br></span><span leaf="">- 未来不再相关的临时上下文</span><span leaf=""><br></span><span leaf="">- 纯粹来自助手对话而非用户对话的信息</span><span leaf=""><br></span><span leaf="">- 仅适用于当前对话中讨论的特定文件、函数或代码片段且不具有广泛适用性的信息</span><span leaf=""><br></span><span leaf="">- 模糊或显而易见且不可操作的偏好</span><span leaf=""><br></span><span leaf="">- 任何用户都会期望的关于良好编程实践的一般性陈述</span><span leaf=""><br></span><span leaf="">- 基本的软件工程原则,如关注点分离、DRY(避免重复)、SOLID(面向对象设计原则)、YAGNI(无需过度设计)、KISS(保持简单)等</span><span leaf=""><br></span><span style="line-height: 26px;"><span leaf=""><!--/</span--><span style="color: #e06c75;line-height: 26px;"><span leaf="">负面标准</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="line-height: 26px;"><span leaf="">&lt;</span><span style="color: #e06c75;line-height: 26px;"><span leaf="">不应记住的示例</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf="">不应被记住的记忆示例:</span><span leaf=""><br></span><span leaf=""><br></span><span leaf="">refactor-target: utils.ts 中的 calculateTotal 函数需要重构。(特定于当前任务)</span><span leaf=""><br></span><span leaf="">variable-name-choice: 在这个特定函数中,将API调用的结果命名为“userData”。(实现细节)</span><span leaf=""><br></span><span leaf="">api-endpoint-used: 该组件的数据来自 /api/v2/items。(特定于当前代码的上下文)</span><span leaf=""><br></span><span leaf="">css-class-fix: 需要在这个视图的“.card-title”元素中添加“margin-top: 10px”。(高度具体的细节)</span><span leaf=""><br></span><span leaf="">navigate-conversation-history: 用户经常需要实现导航对话历史的逻辑(过于模糊)</span><span leaf=""><br></span><span leaf="">code-organization: 用户喜欢条理清晰的代码(过于明显且模糊)</span><span leaf=""><br></span><span leaf="">testing-important: 测试对用户很重要(过于明显)</span><span leaf=""><br></span><span leaf="">error-handling: 用户希望有良好的错误处理(不可操作)</span><span leaf=""><br></span><span leaf="">debugging-strategy: 倾向于将复杂问题分解为更小的部分,找出有问题的变更,系统地回滚后再尝试其他解决方案。(描述了一种常见、略显明显的调试方法)</span><span leaf=""><br></span><span leaf="">basic-software-engineering-principles: 基本的软件工程原则,如关注点分离、DRY、SOLID、YAGNI、KISS等。(过于明显且模糊)</span><span leaf=""><br></span><span leaf=""><br></span><span leaf="">- **不要从用户消息无需记忆的对话中生成记忆:**</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; * &nbsp; **示例场景:** 用户询问某个特定实现细节是否正确,助手确认并解释原因。</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; * &nbsp; **示例对话:**</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; 用户:我只希望这些功能在 side_model 为设置时生效,这个实现看起来合理吗?</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; 助手:是的,这个实现看起来是正确的。1. `shouldRunOnBeforeSubmitChat` 和 `shouldRunOnComposerDone` 方法根据 `memorySystem` 设置正确控制了 `onBeforeSubmitChat` 和 `onComposerDone` 的执行。2. 此外,`onBeforeSubmitChat` 和 `onComposerDone` 调用的 `checkForMemories` 在开头都有明确检查,如果 `memorySystem` 不是 `side-model` 就提前返回。这种双重检查确保核心逻辑只在设置配置为 `side-model` 时运行。</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; * &nbsp; **建议的记忆:** settings-gating-pattern: 通过专用的控制方法(例如 `shouldRun...`)和核心逻辑函数内的明确检查来根据设置控制功能。</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; * &nbsp; **为何这是不良记忆:** 这种交互无需记忆。用户的消息只是对当前任务中特定实现细节(`side-model` 检查)的简单验证请求。虽然助手提供了详细解释,但用户并未表达对未来交互有价值的通用偏好、规则、模式、强烈观点或不满。记忆应源于重要的用户输入或交互模式,而非助手对简单查询的详细回应。</span><span leaf=""><br></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; * &nbsp; **示例场景:** 用户就正在进行的重构询问非常具体的技术问题,助手提供针对性回答。</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; * &nbsp; **示例对话:**</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; 用户:我正在重构 `processUserInput` 函数,将验证逻辑拆分出来。我应该把 `sanitizeInput` 调用放在新的 `validateInput` 函数之前还是之后?</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; 助手:最好在调用 `validateInput` 之前调用 `sanitizeInput`,这样在执行任何验证检查之前输入就已被清理。这确保验证操作的是安全、标准化的数据。</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; * &nbsp; **建议的记忆:** refactor-ordering: 在 `processUserInput` 函数中,始终先调用 `sanitizeInput` 再调用 `validateInput`。</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; * &nbsp; **为何这是不良记忆:** 这是关于特定重构中函数调用顺序的一次性、任务特定细节。用户并非在表达通用偏好或工作流程,只是在为特定实现寻求建议。这不应该作为未来对话的通用规则被记住。</span><span leaf=""><br></span><span leaf=""><br></span><span style="line-height: 26px;"><span leaf=""><!--/</span--><span style="color: #e06c75;line-height: 26px;"><span leaf="">不应记住的示例</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="line-height: 26px;"><span leaf="">&lt;</span><span style="color: #e06c75;line-height: 26px;"><span leaf="">应记住的示例</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf="">应被记住的记忆示例:</span><span leaf=""><br></span><span leaf="">function-size-preference: 将函数控制在50行以内以保持可读性(具体且可操作)</span><span leaf=""><br></span><span leaf="">prefer-async-await: 使用 async/await 风格而非 Promise 链式调用(影响代码的明确偏好)</span><span leaf=""><br></span><span leaf="">typescript-strict-mode: 在 TypeScript 项目中始终启用 strictNullChecks 和 noImplicitAny(具体配置)</span><span leaf=""><br></span><span leaf="">test-driven-development: 在实现新功能前先编写测试(明确的工作流程偏好)</span><span leaf=""><br></span><span leaf="">prefer-svelte: 新的 UI 工作优先使用 Svelte 而非 React(明确的技术选择)</span><span leaf=""><br></span><span leaf="">run-npm-install: 运行终端命令前先执行“npm install”安装依赖(具体的工作流程步骤)</span><span leaf=""><br></span><span leaf="">frontend-layout: 代码库的前端使用 Tailwind CSS(具体的技术选择)</span><span leaf=""><br></span><span style="line-height: 26px;"><span leaf=""><!--/</span--><span style="color: #e06c75;line-height: 26px;"><span leaf="">应记住的示例</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="line-height: 26px;"><span leaf="">&lt;</span><span style="color: #e06c75;line-height: 26px;"><span leaf="">标注说明</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf="">标签应描述所捕捉的通用概念。</span><span leaf=""><br></span><span leaf="">标签将用作文件名,只能包含字母和连字符。</span><span leaf=""><br></span><span style="line-height: 26px;"><span leaf=""><!--/</span--><span style="color: #e06c75;line-height: 26px;"><span leaf="">标注说明</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="line-height: 26px;"><span leaf="">&lt;</span><span style="color: #e06c75;line-height: 26px;"><span leaf="">格式说明</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf="">请以以下 JSON 格式返回你的回应:</span><span leaf=""><br></span><span leaf="">{</span><span leaf=""><br></span><span leaf="">&nbsp;"explanation": "在此解释,对于每个负面示例,为何下方的记忆没有违反任何负面标准。具体说明它避免了哪些负面标准。",</span><span leaf=""><br></span><span leaf="">&nbsp;"memory": "preference-name: 要记住的通用偏好或方法。不要包含当前对话中的具体细节。保持简短,最多3句话。不要使用涉及对话的示例。"</span><span leaf=""><br></span><span leaf="">}</span><span leaf=""><br></span><span leaf=""><br></span><span leaf="">如果无需记忆,请准确返回:"no_memory_needed"</span><span leaf=""><br></span><span style="line-height: 26px;"><span leaf=""><!--/</span--><span style="color: #e06c75;line-height: 26px;"><span leaf="">格式说明</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span></span></span></span></span></span></span></span></code></pre> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 5px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: block;text-align: left;"><span style="display: none;"></span><span style="font-size: 16px;color: rgb(231, 142, 52);line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: bold;display: inline-block;"><span leaf="">记忆评估</span></span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="color: rgba(0, 0, 0, 0.85);font-size: 16px;line-height: 1.75;letter-spacing: 0.1em;text-align: left;text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;margin-top: 5px;margin-right: 0px;margin-bottom: 5px;margin-left: 0px;word-spacing: 0.1em;"><span leaf="">根据上一步提取出来的记忆点进行打分评估,判断其是否值得被 AI 记住以优化未来交互。</span></p> <p data-tool="mdnice编辑器" style="color: rgba(0, 0, 0, 0.85);font-size: 16px;line-height: 1.75;letter-spacing: 0.1em;text-align: left;text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;margin-top: 5px;margin-right: 0px;margin-bottom: 5px;margin-left: 0px;word-spacing: 0.1em;"><span leaf="">其中最关键评估标准如下:</span></p> <ul style="list-style-type: disc;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 20px;padding-right: 0px;color: rgb(231, 142, 52);font-size: 15px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;word-spacing: 0.1em;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">正向标准:与编程 / 软件工程相关、通用可复用、具体可操作、代表通用偏好 / 规则、非特定任务 / 实现细节、非仅绑定当前代码上下文。</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;word-spacing: 0.1em;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">负面标准:排除特定文件 / 代码细节(如 “某函数需重构”)、模糊空泛表述(如 “用户喜欢好代码”)、一次性任务需求、基础常识性原则(如 “测试很重要”)。</span> </section></li> </ul> <p data-tool="mdnice编辑器" style="color: rgba(0, 0, 0, 0.85);font-size: 16px;line-height: 1.75;letter-spacing: 0.1em;text-align: left;text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;margin-top: 5px;margin-right: 0px;margin-bottom: 5px;margin-left: 0px;word-spacing: 0.1em;"><span leaf="">提供了一套完整的评分逻辑:</span><strong style="color: rgba(0, 0, 0, 0.85);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">倾向低分</span></strong><span leaf="">,仅对 “具体可操作的通用规则、用户明确要求记住、用户不满 / 纠正” 等内容评高分(4-5 分),模糊 / 特定内容评 1-3 分。</span></p> <p data-tool="mdnice编辑器" style="color: rgba(0, 0, 0, 0.85);font-size: 16px;line-height: 1.75;letter-spacing: 0.1em;text-align: left;text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;margin-top: 5px;margin-right: 0px;margin-bottom: 5px;margin-left: 0px;word-spacing: 0.1em;"><strong style="color: rgba(0, 0, 0, 0.85);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">完整的翻译内容如下:</span></strong></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg 1chhx9yq4nhaomcbrvmaplx67nrccwjbhaefibyvmcxtmkllfxo7f5zgeia4uijsg3dnibfaop1cj6syw71yommolafks9fw9yh 640?wx_fmt="svg&amp;from=appmsg&quot;);&quot;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span leaf="">你是一名知识极其渊博的软件工程师AI助手,负责判断某些记忆是否值得记住。</span><span leaf=""><br></span><span leaf="">如果一段记忆被记住,意味着在未来AI程序员与人类程序员的对话中,AI程序员能够运用这段记忆做出更优的回应。</span><span leaf=""><br></span><span leaf=""><br></span><span leaf="">以下是引发记忆建议的对话:</span><span leaf=""><br></span><span style="line-height: 26px;"><span leaf="">&lt;</span><span style="color: #e06c75;line-height: 26px;"><span leaf="">conversation_context</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf="">${l}</span><span leaf=""><br></span><span style="line-height: 26px;"><span leaf=""><!--/</span--><span style="color: #e06c75;line-height: 26px;"><span leaf="">conversation_context</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf="">以下是从上述对话中提取的记忆:</span><span leaf=""><br></span><span leaf="">"${a.memory}"</span><span leaf=""><br></span><span leaf=""><br></span><span leaf="">请评估这一事实,并判定其值得记忆的程度,给出1到5的评分。</span><span leaf=""><br></span><span leaf=""><br></span><span leaf="">${c}</span><span leaf=""><br></span><span leaf=""><br></span><span leaf="">一段记忆值得被记住,需满足以下条件:</span><span leaf=""><br></span><span leaf="">- 与编程和软件工程领域相关</span><span leaf=""><br></span><span leaf="">- 具有通用性且适用于未来的交互</span><span leaf=""><br></span><span leaf="">- 具体且可操作——模糊的偏好或观察应给予低分(评分:1-2)</span><span leaf=""><br></span><span leaf="">- 不是特定的任务细节、一次性请求或实现细节(评分:1)</span><span leaf=""><br></span><span leaf="">- 至关重要的是,它绝不能仅与当前对话中讨论的特定文件或代码片段相关。它必须代表一种通用偏好或规则。</span><span leaf=""><br></span><span leaf=""><br></span><span leaf="">如果用户表达了不满或纠正了助手,这类内容尤其值得记录。</span><span leaf=""><br></span><span leaf=""><br></span><span style="line-height: 26px;"><span leaf="">&lt;</span><span style="color: #e06c75;line-height: 26px;"><span leaf="">examples_rated_negatively</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf="">不应被记住的记忆示例(评分:1——通常因为它们与对话中的特定代码相关,或是一次性细节):</span><span leaf=""><br></span><span leaf="">refactor-target: utils.ts 中的 calculateTotal 函数需要重构。(特定于当前任务)</span><span leaf=""><br></span><span leaf="">variable-name-choice: 在这个特定函数中,将API调用的结果命名为“userData”。(实现细节)</span><span leaf=""><br></span><span leaf="">api-endpoint-used: 该组件的数据来自 /api/v2/items。(特定于当前代码的上下文)</span><span leaf=""><br></span><span leaf="">css-class-fix: 需要在这个视图的“.card-title”元素中添加“margin-top: 10px”。(高度具体的细节)</span><span leaf=""><br></span><span leaf=""><br></span><span leaf="">模糊或显而易见的记忆示例(评分:2-3):</span><span leaf=""><br></span><span leaf="">navigate-conversation-history: 用户经常需要实现导航对话历史的逻辑。(过于模糊,不可操作——评分1)</span><span leaf=""><br></span><span leaf="">code-organization: 用户喜欢条理清晰的代码。(过于明显且模糊——评分1)</span><span leaf=""><br></span><span leaf="">testing-important: 测试对用户很重要。(过于明显且模糊——评分1)</span><span leaf=""><br></span><span leaf="">error-handling: 用户希望有良好的错误处理。(过于明显且模糊——评分1)</span><span leaf=""><br></span><span leaf="">debugging-strategy: 倾向于将复杂问题分解为更小的部分,找出有问题的变更,系统地回滚后再尝试其他解决方案。(描述了一种常见、略显明显的调试方法——评分2)</span><span leaf=""><br></span><span leaf="">separation-of-concerns: 喜欢通过将关注点分离为更小、更易管理的单元来重构复杂系统。(描述了一种常见、略显明显的软件工程原则——评分2)</span><span leaf=""><br></span><span style="line-height: 26px;"><span leaf=""><!--/</span--><span style="color: #e06c75;line-height: 26px;"><span leaf="">examples_rated_negatively</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""><br></span><span style="line-height: 26px;"><span leaf="">&lt;</span><span style="color: #e06c75;line-height: 26px;"><span leaf="">examples_rated_neutral</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf="">中等评分的记忆示例(评分:3):</span><span leaf=""><br></span><span leaf="">focus-on-cursor-and-openaiproxy: 用户经常请求有关代码库或ReactJS代码库的帮助。(特定代码库,但未明确所需帮助类型)</span><span leaf=""><br></span><span leaf="">project-structure: 前端代码应放在“components”目录,后端代码放在“services”目录。(特定于项目的组织方式,有一定帮助但非关键)</span><span leaf=""><br></span><span style="line-height: 26px;"><span leaf=""><!--/</span--><span style="color: #e06c75;line-height: 26px;"><span leaf="">examples_rated_neutral</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""><br></span><span style="line-height: 26px;"><span leaf="">&lt;</span><span style="color: #e06c75;line-height: 26px;"><span leaf="">examples_rated_positively</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf="">应被记住的记忆示例(评分:4-5):</span><span leaf=""><br></span><span leaf="">function-size-preference: 将函数控制在50行以内以保持可读性。(具体且可操作——评分4)</span><span leaf=""><br></span><span leaf="">prefer-async-await: 使用异步/等待风格而非Promise链式调用。(影响代码的明确偏好——评分4)</span><span leaf=""><br></span><span leaf="">typescript-strict-mode: 在TypeScript项目中始终启用严格空值检查(strictNullChecks)和禁止隐式any类型(noImplicitAny)。(具体配置——评分4)</span><span leaf=""><br></span><span leaf="">test-driven-development: 在实现新功能前先编写测试。(明确的工作流程偏好——评分5)</span><span leaf=""><br></span><span leaf="">prefer-svelte: 新的UI工作优先使用Svelte而非React。(明确的技术选择——评分5)</span><span leaf=""><br></span><span leaf="">run-npm-install: 运行终端命令前先执行“npm install”安装依赖。(具体的工作流程步骤——评分5)</span><span leaf=""><br></span><span leaf="">frontend-layout: 代码库的前端使用Tailwind CSS。(具体的技术选择——评分4)</span><span leaf=""><br></span><span style="line-height: 26px;"><span leaf=""><!--/</span--><span style="color: #e06c75;line-height: 26px;"><span leaf="">examples_rated_positively</span></span><span leaf="">&gt;</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""><br></span><span leaf="">倾向于给较低的评分,当记忆被评得过高时,用户会非常恼火。</span><span leaf=""><br></span><span leaf="">尤其要注意将模糊或显而易见的记忆评为1或2分。这类记忆最容易出现评分不当的情况。</span><span leaf=""><br></span><span leaf="">若不确定或记忆处于边缘状态,评3分。只有当记忆明显有价值、具体且可操作时,才评4或5分。</span><span leaf=""><br></span><span leaf="">如果记忆仅适用于当前对话中讨论的特定代码/文件,且不代表通用规则,评1或2分。</span><span leaf=""><br></span><span leaf="">然而,若用户明确要求记住某件事,则无论内容如何,都评5分。</span><span leaf=""><br></span><span leaf="">此外,若遇到类似“no_memory_needed”(无需记忆)或“no_memory_suggested”(未建议记忆)的内容,必须评1分。</span><span leaf=""><br></span><span leaf=""><br></span><span leaf="">请基于该记忆为何不属于99%应评1、2或3分的记忆进行说明,尤其要重点阐述它与负面示例的区别,以此作为评分理由。</span><span leaf=""><br></span><span leaf="">然后在下一行以“评分:[分数]”的格式返回分数,其中[分数]为1到5之间的整数。&nbsp;</span><span leaf=""><br></span></span></span></span></span></code></pre> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: block;text-align: center;background-position-x: center;background-position-y: center;background-repeat: no-repeat;background-attachment: initial;background-origin: initial;background-clip: initial;background-size: 46px;"><span data-cacheurl="" data-remoteid="" style="display: inline-block;background-size: 100% 100%;background-repeat: no-repeat;width: 28px;height: 28px;margin-bottom: -6px;margin-right: 0px;background-image: url(" https: mmbiz.qpic.cn mmbiz_gif hb9x3yucnoy9gwwicpgqoleqvpgtzgfibjfiopqagld8pecjgic5mnvsjlnl0ckrfric77e0d7oibirafzonoljatvw 640?wx_fmt="gif&amp;from=appmsg&quot;);&quot;"></span><span style="display: none;"></span><span style="font-size: 18px;color: rgb(231, 142, 52);line-height: 60px;letter-spacing: 0em;text-align: center;font-weight: bold;display: inline-block;height: 46px;background-position-x: left;background-position-y: center;background-repeat: no-repeat;background-attachment: initial;background-origin: initial;background-clip: initial;"><span leaf="">Q&amp;A</span></span><span style="display: none;"></span></h2> <p data-tool="mdnice编辑器" style="color: rgba(0, 0, 0, 0.85);font-size: 16px;line-height: 1.75;letter-spacing: 0.1em;text-align: left;text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;margin-top: 5px;margin-right: 0px;margin-bottom: 5px;margin-left: 0px;word-spacing: 0.1em;"><span leaf="">大部分刚接触这一块的小伙伴可能会疑惑为什么不把&nbsp;</span><code style="line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);color: rgb(231, 142, 52);font-size: 15px;overflow-wrap: break-word;padding-top: 2px;padding-right: 4px;padding-bottom: 2px;padding-left: 4px;border-top-left-radius: 3px;border-top-right-radius: 3px;border-bottom-right-radius: 3px;border-bottom-left-radius: 3px;margin-top: 0px;margin-right: 2px;margin-bottom: 0px;margin-left: 2px;background-color: rgb(255, 246, 237);font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">提取 + 评估</span></code><span leaf="">&nbsp;合并到一起执行呢,效果会有什么区别吗?</span></p> <p data-tool="mdnice编辑器" style="color: rgba(0, 0, 0, 0.85);font-size: 16px;line-height: 1.75;letter-spacing: 0.1em;text-align: left;text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;margin-top: 5px;margin-right: 0px;margin-bottom: 5px;margin-left: 0px;word-spacing: 0.1em;"><strong style="color: rgba(0, 0, 0, 0.85);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">拆分步骤的主要的原因如下</span></strong><span leaf="">:</span></p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 5px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: block;text-align: left;"><span style="display: none;"></span><span style="font-size: 16px;color: rgb(231, 142, 52);line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: bold;display: inline-block;"><span leaf="">降低任务复杂度,避免 “顾此失彼”</span></span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="color: rgba(0, 0, 0, 0.85);font-size: 16px;line-height: 1.75;letter-spacing: 0.1em;text-align: left;text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;margin-top: 5px;margin-right: 0px;margin-bottom: 5px;margin-left: 0px;word-spacing: 0.1em;"><span leaf="">大模型处理任务的能力有限,尤其是在需要精准区分细节的场景中。如果让模型同时完成 “从对话中筛选潜在记忆点” 和 “判断这些记忆点是否符合标准”,可能会导致两种结果:要么提取时遗漏关键信息(因为注意力被评估规则分散),要么评估时标准松动(因为需要先 “凑够” 提取内容)。拆分后,每一步可以专注单一目标,提取阶段只聚焦 “哪些信息可能有价值”,评估阶段只严格对照规则判断 “是否该保留”,精度更高。</span></p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 5px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: block;text-align: left;"><span style="display: none;"></span><span style="font-size: 16px;color: rgb(231, 142, 52);line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: bold;display: inline-block;"><span leaf="">减少 “自我干扰”,提升一致性</span></span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="color: rgba(0, 0, 0, 0.85);font-size: 16px;line-height: 1.75;letter-spacing: 0.1em;text-align: left;text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;margin-top: 5px;margin-right: 0px;margin-bottom: 5px;margin-left: 0px;word-spacing: 0.1em;"><span leaf="">大模型在复杂任务中容易出现 “自我说服” 偏差:如果自己提取的信息需要自己评估,可能会潜意识里放宽标准(比如对自己提取的内容更宽容),导致评估结果偏向主观。拆分后,相当于引入 “二次校验” 机制,评估阶段可以更客观地用规则审视提取结果,减少这种内生偏差,让最终保留的记忆更符合预设标准,一致性更强。</span></p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 5px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: block;text-align: left;"><span style="display: none;"></span><span style="font-size: 16px;color: rgb(231, 142, 52);line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: bold;display: inline-block;"><span leaf="">技术架构更加灵活</span></span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="color: rgba(0, 0, 0, 0.85);font-size: 16px;line-height: 1.75;letter-spacing: 0.1em;text-align: left;text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;margin-top: 5px;margin-right: 0px;margin-bottom: 5px;margin-left: 0px;word-spacing: 0.1em;"><span leaf="">可以分别控制两个阶段的资源、模型...,从技术角度来说更加合理。</span></p> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: block;text-align: center;background-position-x: center;background-position-y: center;background-repeat: no-repeat;background-attachment: initial;background-origin: initial;background-clip: initial;background-size: 46px;"><span data-cacheurl="" data-remoteid="" style="display: inline-block;background-size: 100% 100%;background-repeat: no-repeat;width: 28px;height: 28px;margin-bottom: -6px;margin-right: 0px;background-image: url(" https: mmbiz.qpic.cn mmbiz_gif hb9x3yucnoy9gwwicpgqoleqvpgtzgfibjfiopqagld8pecjgic5mnvsjlnl0ckrfric77e0d7oibirafzonoljatvw 640?wx_fmt="gif&amp;from=appmsg&quot;);&quot;"></span><span style="display: none;"></span><span style="font-size: 18px;color: rgb(231, 142, 52);line-height: 60px;letter-spacing: 0em;text-align: center;font-weight: bold;display: inline-block;height: 46px;background-position-x: left;background-position-y: center;background-repeat: no-repeat;background-attachment: initial;background-origin: initial;background-clip: initial;"><span leaf="">总结</span></span><span style="display: none;"></span></h2> <p data-tool="mdnice编辑器" style="color: rgba(0, 0, 0, 0.85);font-size: 16px;line-height: 1.75;letter-spacing: 0.1em;text-align: left;text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;margin-top: 5px;margin-right: 0px;margin-bottom: 5px;margin-left: 0px;word-spacing: 0.1em;"><code style="line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);color: rgb(231, 142, 52);font-size: 15px;overflow-wrap: break-word;padding-top: 2px;padding-right: 4px;padding-bottom: 2px;padding-left: 4px;border-top-left-radius: 3px;border-top-right-radius: 3px;border-bottom-right-radius: 3px;border-bottom-left-radius: 3px;margin-top: 0px;margin-right: 2px;margin-bottom: 0px;margin-left: 2px;background-color: rgb(255, 246, 237);font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Cursor</span></code><span leaf="">&nbsp;通过&nbsp;</span><code style="line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);color: rgb(231, 142, 52);font-size: 15px;overflow-wrap: break-word;padding-top: 2px;padding-right: 4px;padding-bottom: 2px;padding-left: 4px;border-top-left-radius: 3px;border-top-right-radius: 3px;border-bottom-right-radius: 3px;border-bottom-left-radius: 3px;margin-top: 0px;margin-right: 2px;margin-bottom: 0px;margin-left: 2px;background-color: rgb(255, 246, 237);font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">提取 + 评估</span></code><span leaf="">&nbsp;的流程搭建记忆系统,有效保障了记忆的高价值。通过严格&nbsp;</span><strong style="color: rgba(0, 0, 0, 0.85);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">筛选规则</span></strong><span leaf="">&nbsp;排除特殊化、模糊化的低质记忆,避免其干扰大模型的回复质量。</span></p> <p data-tool="mdnice编辑器" style="color: rgba(0, 0, 0, 0.85);font-size: 16px;line-height: 1.75;letter-spacing: 0.1em;text-align: left;text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;margin-top: 5px;margin-right: 0px;margin-bottom: 5px;margin-left: 0px;word-spacing: 0.1em;"><span leaf="">从提示词设计我们可以看出,它的其整体思路&nbsp;</span><strong style="color: rgba(0, 0, 0, 0.85);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">偏保守</span></strong><span leaf="">&nbsp;,评分逻辑中低分概率远高于高分,实际使用时被保留的记忆数量较少(当然这是一个高性价比的做法)。若能在现有严格标准基础上,进一步精准捕捉不同场景的非通用偏好或规则,那对用户将会更有价值。</span></p> </section> <section> <span leaf=""><br></span> </section> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>

花费1.03元微调豆包大模型解决了业务问题,分享一下经验

作者:微信小助手

<section> <span leaf="">先看下花费:1.03元</span> </section> <section style="text-align: center;" nodeleaf=""> <img src="/upload/4f4df9c2f4cf2b6fb4a60d7b81a19d76.png" class="rich_pages wxw-img" data-ratio="0.14444444444444443" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="304706599"> </section> <section> <span leaf="">花费不多。那为什么要微调模型呢?没有别的办法了吗?最后效果怎样?</span> </section> <section> <span leaf="">在回答这些问题前,先看看业务的需求:</span> </section> <section style="text-align: center;" nodeleaf=""> <img src="/upload/31f56ba34ba52d7397907088e360c8e4.png" class="rich_pages wxw-img" data-ratio="0.7185185185185186" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="304706591"> </section> <section style="text-align: center;" nodeleaf=""> <img src="/upload/3f85993955ec33bb6026a64c30ee66e4.png" class="rich_pages wxw-img" data-ratio="0.4361111111111111" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="304706592"> </section> <section style="text-align: left;"> <span leaf="">这是个体验类的需求。</span> </section> <section style="text-align: left;"> <span leaf="">输出的型号中间有空格,直接copy这个型号作为关键词去其它系统中可能就会查不到。</span> </section> <section> <span leaf="">因为,传统的系统中要么是精确匹配,要么是基于RDB的like,这是无法支持关键词中间加空格的查询。</span> </section> <section class="mp_profile_iframe_wrp" nodeleaf=""> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-nickname="的数字化之路" data-alias="dduspace" data-from="0" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/G3Ggb8COicY23iaIwxpVSOQRzD7yxS52bLnD9Kfrmm9ZrRj2kf9ELu8ZJoEvRAIedBqdnmicsW4lo5ibibGy5WNagaQ/0?wx_fmt=png" data-signature="格物致知 知行合一 记录开悟时的小欢喜 也希望能通过这种方式正向反馈社区" data-id="MzA3OTc4MTQ5NQ==" data-is_biz_ban="0" data-service_type="1" data-verify_status="1"></mp-common-profile> </section> <section> <h2 data-tool="mdnice编辑器" data-pm-slice="0 0 []" style="-webkit-tap-highlight-color: transparent;margin: 20px 10px 0px 0px;padding: 0px;outline: 0px;font-weight: bold;font-size: 22px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;background-color: rgb(255, 255, 255);color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;letter-spacing: normal;text-align: left;visibility: visible;><span style="-webkit-tap-highlight-color: transparent;margin: 0px;padding: 0px 0px 0px 10px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: STHeitiSC-Light;color: rgb(14, 136, 235);font-weight: bolder;display: inline-block;border-left: 5px solid rgb(14, 136, 235);visibility: visible;letter-spacing: 0.578px;"><span leaf="" style="-webkit-tap-highlight-color: transparent;margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible;" data-pm-slice="1 1 [" para,{tagname:h2,attributes:{data-tool:mdnice编辑器,data-pm-slice:0 0 [],style:-webkit-tap-highlight-color: transparent;margin: 20px 10px 0px 0px;padding: 0px;outline: 0px;font-weight: bold;font-size: 22px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;background-color: rgb(255, 255, 255);color: rgb(0, 0, 0);font-family: optima-regular, optima, pingfangsc-light, pingfangtc-light, \pingfang sc\, cambria, cochin, georgia, times, \times new roman\, serif;letter-spacing: normal;text-align: left;visibility: visible;},namespaceuri:http: www.w3.org 1999 xhtml},node,{tagname:span,attributes:{style:-webkit-tap-highlight-color: 10px;outline: 0px;max-width: !important;font-family: stheitisc-light;color: rgb(14, 136, 235);font-weight: bolder;display: inline-block;border-left: 5px solid 235);visibility: visible;letter-spacing: 0.578px;},namespaceuri:http: xhtml}]>怎么办?</span></span></h2> </section> <section> <span leaf="">方案1:调提示词,让大模型控制输出的结果。试了下</span><span leaf="" data-pm-slice="1 1 [" para,{tagname:section,attributes:{},namespaceuri:http: www.w3.org 1999 xhtml}]>,不是很理想</span><span leaf="">,没有彻底根除。</span> </section> <section style="text-align: center;" nodeleaf=""> <img src="/upload/d60e9fa9285444430a8d801014705e68.png" class="rich_pages wxw-img" data-ratio="0.5648148148148148" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="304706595"> </section> <section> <span leaf="">方案2:换大模型。</span> </section> <section style="text-align: center;" nodeleaf=""> <img src="/upload/537a2b8e712d5d51da45137f376cb4eb.png" class="rich_pages wxw-img" data-ratio="0.6768518518518518" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="304706596"> </section> <section> <span leaf="">提示词无法解决问题时,换大模型也是一个解决问题的办法。不过这会增加额外回归测试的工作。</span> </section> <section style="text-align: left;"> <span leaf="">先换了</span><span leaf="" data-pm-slice="1 1 [" para,{tagname:section,attributes:{},namespaceuri:http: www.w3.org 1999 xhtml}]>gpt-4o-mini临时解决了问题。</span><span leaf="">gpt-40-mini这个模型输出结果的型号中间没有额外加空格。</span> </section> <section style="text-align: center;" nodeleaf=""> <img src="/upload/3f488e698e345c546ccc92cc0a76d944.png" class="rich_pages wxw-img" data-ratio="0.6310679611650486" data-s="300,640" data-type="png" data-w="206" type="block" data-imgfileid="304706598"> </section> <section style="text-align: left;"> <span leaf="">格式的问题解决了,但是这引发了另一个新问题:就是gpt-4o-mini比国内的大模型要贵不少。</span> </section> <h2 data-tool="mdnice编辑器" data-pm-slice="0 0 []" style="-webkit-tap-highlight-color: transparent;margin: 20px 10px 0px 0px;padding: 0px;outline: 0px;font-weight: bold;font-size: 22px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;background-color: rgb(255, 255, 255);color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;letter-spacing: normal;text-align: left;visibility: visible;><span style="-webkit-tap-highlight-color: transparent;margin: 0px;padding: 0px 0px 0px 10px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: STHeitiSC-Light;color: rgb(14, 136, 235);font-weight: bolder;display: inline-block;border-left: 5px solid rgb(14, 136, 235);visibility: visible;letter-spacing: 0.578px;"><span leaf="" style="-webkit-tap-highlight-color: transparent;margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible;">怎么办?</span></span></h2> <section> <span leaf="">对国内的模型</span><span leaf="">Doubao-1.5-pro-32k</span><span leaf="">进行微调。准确的讲是SFT(精调)。</span> </section> <section> <span leaf="">什么是SFT?</span> </section> <section> <section> <span leaf="">SFT(Supervised Fine-Tuning,监督微调)精调:通过已标注好的数据对模型进行精调优化,以适应特定的任务或领域。</span> </section> </section> <ul style="outline: none;appearance: none;box-sizing: border-box;-webkit-tap-highlight-color: rgba(255, 255, 255, 0);margin: 0px 0px 14px;padding: 0px 0px 0px 16px;list-style: revert;color: rgba(23, 23, 23, 0.8);font-family: PingFangSC, " helvetica neue, hiragino sans gb, arial, microsoft yahei ui, yahei, simsun, sans-serif;font-size: 14px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="outline: none;appearance: none;box-sizing: border-box;-webkit-tap-highlight-color: rgba(255, 255, 255, 0);margin: 0px 0px 4px;padding: 0px;list-style: revert;word-break: break-word;"> <section> <span leaf="">在自然语言处理(NLP)领域,Supervised Finetuning(SFT)是一种至关重要的技术手段,用来提升大模型在某一特定领域的表现。通过精细的策划和实施,SFT 能够指导模型的学习过程,确保其学习成果与既定目标高度吻合。</span> </section></li> <li style="outline: none;appearance: none;box-sizing: border-box;-webkit-tap-highlight-color: rgba(255, 255, 255, 0);margin: 0px 0px 4px;padding: 0px;list-style: revert;word-break: break-word;"> <section> <span leaf="">SFT 指的是,用户提供一份标注好的数据集,即,包含输入的 prompt 和预期输出的 response。然后,在已有的某个基座模型上继续调整参数,来达到和下游任务对齐的目的。</span> </section></li> </ul> <section> <span leaf="">为什么是SFT?</span> </section> <p data-pm-slice="2 2 []"><span leaf="">因为</span><span leaf="" data-pm-slice="1 1 [" para,{tagname:p,attributes:{},namespaceuri:http: www.w3.org 1999 xhtml}]>SFT并不需要大量的训练集,因为SFT可以解决这类输入内容格式化的问题。</span></p> <ul style="outline: none;appearance: none;box-sizing: border-box;-webkit-tap-highlight-color: rgba(255, 255, 255, 0);margin: 0px 0px 14px;padding: 0px 0px 0px 16px;list-style: revert;color: rgba(23, 23, 23, 0.8);font-family: PingFangSC, " helvetica neue, hiragino sans gb, arial, microsoft yahei ui, yahei, simsun, sans-serif;font-size: 14px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="outline: none;appearance: none;box-sizing: border-box;-webkit-tap-highlight-color: rgba(255, 255, 255, 0);margin: 0px 0px 4px;padding: 0px;list-style: revert;word-break: break-word;"> <section> <span leaf="">什么时候需要SFT:</span> </section></li> <ul style="outline: none;appearance: none;box-sizing: border-box;-webkit-tap-highlight-color: rgba(255, 255, 255, 0);margin: 4px 0px 14px;padding: 0px 0px 0px 16px;list-style: revert;" class="list-paddingleft-1"> <li style="outline: none;appearance: none;box-sizing: border-box;-webkit-tap-highlight-color: rgba(255, 255, 255, 0);margin: 0px 0px 4px;padding: 0px;list-style: revert;word-break: break-word;"> <section> <span leaf="">通过 prompt engineering 无法解决或 prompt 中描述过于复杂时。</span> </section></li> <li style="outline: none;appearance: none;box-sizing: border-box;-webkit-tap-highlight-color: rgba(255, 255, 255, 0);margin: 0px 0px 4px;padding: 0px;list-style: revert;word-break: break-word;"> <section> <span leaf="">对大模型输出内容有格式要求时,而模型仍有部分 case 不符合要求。</span> </section></li> <li style="outline: none;appearance: none;box-sizing: border-box;-webkit-tap-highlight-color: rgba(255, 255, 255, 0);margin: 0px 0px 4px;padding: 0px;list-style: revert;word-break: break-word;"> <section> <span leaf="">期望通过 SFT 来减少 prompt 中的内容,加速线上推理的耗时。</span> </section></li> </ul> </ul> <section> <span style="color: rgba(23, 23, 23, 0.8);font-family: PingFangSC, " helvetica neue, hiragino sans gb, arial, microsoft yahei ui, yahei, simsun, sans-serif;font-size: 14px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: left;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;display: inline !important;float: none; data-pm-slice="0 0 []"><span leaf="">做SFT的前置依赖:</span></span> </section> <ul style="outline: none;appearance: none;box-sizing: border-box;-webkit-tap-highlight-color: rgba(255, 255, 255, 0);margin: 4px 0px 14px;padding: 0px 0px 0px 16px;list-style: revert;color: rgba(23, 23, 23, 0.8);font-family: PingFangSC, " helvetica neue, hiragino sans gb, arial, microsoft yahei ui, yahei, simsun, sans-serif;font-size: 14px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: left;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="outline: none;appearance: none;box-sizing: border-box;-webkit-tap-highlight-color: rgba(255, 255, 255, 0);margin: 0px 0px 4px;padding: 0px;list-style: revert;word-break: break-word;"> <section> <span leaf="">0)一方面,把 prompt engineering 做到极致,通过优化 prompt 已经不能解决剩余的 badcase。另一方面,SFT 数据集中也依赖 prompt。因此,做 SFT 之前尽量把 prompt 工程做到最优。</span> </section></li> <li style="outline: none;appearance: none;box-sizing: border-box;-webkit-tap-highlight-color: rgba(255, 255, 255, 0);margin: 0px 0px 4px;padding: 0px;list-style: revert;word-break: break-word;"> <section> <span leaf="">1)一开始不需要急着构造大量 SFT 数据集,可以先用少量数据(50条~100条)对模型做 SFT 后观察真实评估是否有收益。如果有收益,可以尝试以部分数据为种子数据集继续扩充,找到 scaling law。</span> </section></li> </ul> <p><span leaf="">微调的核心任务是让模型从 “能生成文本” 进化为 “能听懂指令、按意图做事”。这个过程中,数据的作用不是 “喂饱模型”,而是 “给模型清晰的‘行为示范’”。</span></p> <p><span leaf="">SFT是用来画龙点睛的。</span></p> <h2 data-tool="mdnice编辑器" data-pm-slice="0 0 []" style="-webkit-tap-highlight-color: transparent;margin: 20px 10px 0px 0px;padding: 0px;outline: 0px;font-weight: bold;font-size: 22px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;background-color: rgb(255, 255, 255);color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;letter-spacing: normal;text-align: left;visibility: visible;><span style="-webkit-tap-highlight-color: transparent;margin: 0px;padding: 0px 0px 0px 10px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: STHeitiSC-Light;color: rgb(14, 136, 235);font-weight: bolder;display: inline-block;border-left: 5px solid rgb(14, 136, 235);visibility: visible;letter-spacing: 0.578px;"><span leaf="" style="-webkit-tap-highlight-color: transparent;margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible;">怎么做?</span></span></h2> <section> <span leaf="">本次使用字节火山引擎的</span><span leaf="">模型精调工具。</span> </section> <p><span leaf="">1、在模型精调页面,点击左上角 创建精调任务 按钮。</span></p> <section> <span leaf=""><img src="/upload/818bcf957561fa81879586b6c2a63c36.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.44074074074074077" data-type="png" data-w="1080" data-imgfileid="304706602"></span> </section> <section> <span leaf="">2、填写模型精调任务名称等基本信息。</span> </section> <p style="text-align: left;"><span leaf=""><span textstyle="" style="font-size: 16px;">任务名称(必填):本次精调任务命名,方便记录检索;支持1~200位可见字符,且只包含大小写字母、中文、数字、中划线、下划线。</span></span></p> <p style="text-align: left;"><span leaf=""><span textstyle="" style="font-size: 16px;">任务描述:本次精调任务添加除名称以外的其他描述信息,方便多次迭代版本,重要信息记录;包含大小写字母、中文、数字、中划线、下划线。</span></span></p> <section> <span leaf=""><img src="/upload/46c5b271c7a620169cd16c7cfc7732fa.png" alt="Image" class="rich_pages wxw-img" data-ratio="0.7101851851851851" data-type="png" data-w="1080" data-imgfileid="304706603"></span> </section> <section style="text-align: center;" nodeleaf=""> <img src="/upload/39c58eeee0ad77aa35aae6c7c7bedcfb.png" class="rich_pages wxw-img" data-ratio="0.6694444444444444" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="304706604"> </section> <section> <span leaf="">SFT参数配置中的参数如何确定?</span> </section> <section> <span leaf="">与训练集有关。</span> </section> <section> <span leaf="">训练集怎么得到?</span> </section> <section> <span leaf="">使用大模型生成。因为SFT并不需要大量的训练集,微调的核心任务,是让模型从 “能生成文本” 进化为 “能听懂指令、按意图做事”。这个过程中,数据的作用不是 “喂饱模型”,而是 “给模型清晰的‘行为示范’”。</span> </section> <section> <span leaf="">引用两句业内比较流行的话:</span> </section> <p><span leaf="">Quality Is All You Need.</span></p> <p><span leaf="">Less Is More for Aligment.</span></p> <section> <span leaf="">话不多说,先来看看生成训练集的提示词:</span> </section> <section style="text-align: center;" nodeleaf=""> <img src="/upload/c442e201ae55c41223bd0d13baebcd92.png" class="rich_pages wxw-img" data-ratio="0.7453703703703703" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="304706605"> </section> <section> <span leaf="">提示词:“</span> </section> <p style="text-align: left;"><span leaf=""><span textstyle="" style="font-size: 16px;">目前douboa-32K-pro大模型在输出数据时,总会给额外加一些空格,譬如</span></span></p> <p style="text-align: left;"><span leaf=""><span textstyle="" style="font-size: 16px;">问题中是“Sikalastic-609”,大模型输出会是“Sikalastic - 609”,即在“-”两边额外添加了一个空格;</span></span></p> <p style="text-align: left;"><span leaf=""><span textstyle="" style="font-size: 16px;">问题中是“水吧台/岛台区域”,大模型输出会是“水吧台 / 岛台区域”,即在“/”两边额外添加了一个空格;</span></span></p> <p style="text-align: left;"><span leaf=""><span textstyle="" style="font-size: 16px;">期望这们的效果:</span></span></p> <p style="text-align: left;"><span leaf=""><span textstyle="" style="font-size: 16px;">问题中是“Sikalastic-609”,大模型如果有相关的内容,原样输出“Sikalastic-609”</span></span></p> <p style="text-align: left;"><span leaf=""><span textstyle="" style="font-size: 16px;">问题中是“水吧台/岛台区域”,大模型如果有相关的内容,原样输出“水吧台/岛台区域”</span></span></p> <p style="text-align: left;"><span leaf=""><span textstyle="" style="font-size: 16px;">基于这个目标,来SFT大模型,按照</span></span></p> <p style="text-align: left;"><span leaf=""><span textstyle="" style="font-size: 16px;">“Quality Is All You Need.</span></span></p> <p style="text-align: left;"><span leaf=""><span textstyle="" style="font-size: 16px;">Less Is More for Aligment.”的规则,提供足够数据的input和output用于精调。</span></span></p> <p style="text-align: left;"><span leaf=""><span textstyle="" style="font-size: 16px;">按“扩充高质量格式数据”的策略输出包含新增符号场景样本 和 增加 “错误 - 修正” 对比样本。</span></span></p> <p style="text-align: left;"><span leaf=""><span textstyle="" style="font-size: 16px;">补充至少 50 条严格格式对齐的样本,覆盖更多领域(如技术文档、日常对话、专业术语)</span></span></p> <section> <span leaf="">"</span> </section> <p style="text-align: left;"><span leaf="">本次生成并使用的</span><span leaf="">训练集,共42条,具体数据见文末。</span><span leaf=""><br></span></p> <p data-pm-slice="0 0 []"><span leaf="">提示词:“使用上面生成的42条训练集,给出截图中参数的配置值”</span></p> <p data-pm-slice="0 0 []"><span leaf="">Answer:结合 42 条训练集的小数据场景,以下是适配的参数配置思路及说明,在原有参数基础上优化以适配小数据的高效学习、避免过拟合:</span></p> <h3 style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin-top: 28px;margin-right: 0px;margin-bottom: 12px !important;margin-left: 0px;padding-top: 0px;padding-right: 0px;padding-bottom: 0px !important;padding-left: 0px;font-size: 18px;font-weight: 700;line-height: 28px;color: rgb(0, 0, 0);overflow-anchor: auto;font-family: Inter, -apple-system, " system-ui, segoe ui, sf pro sc, display, icons, pingfang hiragino sans gb, microsoft yahei, helvetica neue, helvetica, arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">1、参数配置表</span></h3> <table style="-webkit-font-smoothing:antialiased;box-sizing:border-box;-webkit-tap-highlight-color:rgba(0, 0, 0, 0);outline:none;border-width:0.666667px;border-style:solid;border-color:rgba(0, 0, 0, 0.08);border-image:none 100% / 1 / 0 stretch;margin:0px;padding:0px;border-collapse:collapse;text-indent:0px;border-radius:12px;border-spacing:0px;display:block;overflow:auto;max-width:max-content;text-align:left;overflow-anchor:auto;min-width:365px;"> <thead> <tr style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: solid;border-left-style: solid;border-color: initial;border-image: initial;margin: 0px;padding: 0px;overflow-anchor: auto;background-color: rgb(242, 242, 242);"> <th data-colwidth="111" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 600;line-height: 28px;color: rgb(0, 0, 0) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">参数名</span> </section></th> <th data-colwidth="109" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 600;line-height: 28px;color: rgb(0, 0, 0) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">原数值</span> </section></th> <th data-colwidth="120" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 600;line-height: 28px;color: rgb(0, 0, 0) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">调整后推荐值</span> </section></th> <th style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 600;line-height: 28px;color: rgb(0, 0, 0) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">调整逻辑(适配 42 条小数据集)</span> </section></th> </tr> </thead> <tbody> <tr style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0.666667px 0px 0px;border-style: solid;border-top-color: rgba(0, 0, 0, 0.08);border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 0px;overflow-anchor: auto;"> <td data-colwidth="111" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"><code style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 14px;font-variation-settings: normal;background: none 0% auto repeat scroll padding-box border-box rgba(0, 0, 0.06);border-radius: 4px;color: rgb(0, 0);overflow-anchor: auto;><span leaf=""><span textstyle="" style="background-color: rgb(255, 255, 255);">epoch</span></span></code></td> <td data-colwidth="109" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">1</span> </section></td> <td data-colwidth="120" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">2 - 3</span> </section></td> <td style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">小数据需多轮学习强化记忆,2 - 3 轮平衡拟合与过拟合</span> </section></td> </tr> <tr style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0.666667px 0px 0px;border-style: solid;border-top-color: rgba(0, 0, 0, 0.08);border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 0px;overflow-anchor: auto;"> <td data-colwidth="111" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"><code style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 14px;font-variation-settings: normal;background: none 0% auto repeat scroll padding-box border-box rgba(0, 0, 0.06);border-radius: 4px;color: rgb(0, 0);overflow-anchor: auto;><span leaf=""><span textstyle="" style="background-color: rgb(255, 255, 255);">batch_size</span></span></code></td> <td data-colwidth="109" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">8</span> </section></td> <td data-colwidth="120" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">4 或 8</span> </section></td> <td style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">42 条数据用 8 可整除(42÷8=5.25,实际取整为 5 个完整 batch + 2 条余数据;若硬件允许,8 可保留,加速训练;若显存紧张,调为 4 )</span> </section></td> </tr> <tr style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0.666667px 0px 0px;border-style: solid;border-top-color: rgba(0, 0, 0, 0.08);border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 0px;overflow-anchor: auto;"> <td data-colwidth="111" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"><code style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 14px;font-variation-settings: normal;background: none 0% auto repeat scroll padding-box border-box rgba(0, 0, 0.06);border-radius: 4px;color: rgb(0, 0);overflow-anchor: auto;><span leaf=""><span textstyle="" style="background-color: rgb(255, 255, 255);">learning_rate</span></span></code></td> <td data-colwidth="109" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">0.00001</span> </section></td> <td data-colwidth="120" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">5e - 5</span> </section></td> <td style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">原学习率(1e - 5)偏低,小数据场景适度调高至 5e - 5 加速收敛,若训练中出现震荡,可再调回 3e - 5</span> </section></td> </tr> <tr style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0.666667px 0px 0px;border-style: solid;border-top-color: rgba(0, 0, 0, 0.08);border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 0px;overflow-anchor: auto;"> <td data-colwidth="111" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"><code style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 14px;font-variation-settings: normal;background: none 0% auto repeat scroll padding-box border-box rgba(0, 0, 0.06);border-radius: 4px;color: rgb(0, 0);overflow-anchor: auto;><span leaf=""><span textstyle="" style="background-color: rgb(255, 255, 255);">warmup_step_rate</span></span></code></td> <td data-colwidth="109" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">0.05</span> </section></td> <td data-colwidth="120" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">0.1</span> </section></td> <td style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">增加 warmup 比例(10% 步数),让模型逐步适应学习率,避免小数据下初始更新幅度过大</span> </section></td> </tr> <tr style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0.666667px 0px 0px;border-style: solid;border-top-color: rgba(0, 0, 0, 0.08);border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 0px;overflow-anchor: auto;"> <td data-colwidth="111" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"><code style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 14px;font-variation-settings: normal;background: none 0% auto repeat scroll padding-box border-box rgba(0, 0, 0.06);border-radius: 4px;color: rgb(0, 0);overflow-anchor: auto;><span leaf=""><span textstyle="" style="background-color: rgb(255, 255, 255);">lora_rank</span></span></code></td> <td data-colwidth="109" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">32</span> </section></td> <td data-colwidth="120" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">32</span> </section></td> <td style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">因只能选 32 或 64,32 更适配小数据,减少过拟合风险,保留该值</span> </section></td> </tr> <tr style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0.666667px 0px 0px;border-style: solid;border-top-color: rgba(0, 0, 0, 0.08);border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 0px;overflow-anchor: auto;"> <td data-colwidth="111" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"><code style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 14px;font-variation-settings: normal;background: none 0% auto repeat scroll padding-box border-box rgba(0, 0, 0.06);border-radius: 4px;color: rgb(0, 0);overflow-anchor: auto;><span leaf=""><span textstyle="" style="background-color: rgb(255, 255, 255);">lora_alpha</span></span></code></td> <td data-colwidth="109" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">4</span> </section></td> <td data-colwidth="120" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">8</span> </section></td> <td style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">配合&nbsp;</span><code style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 14px;font-variation-settings: normal;background: none 0% auto repeat scroll padding-box border-box rgba(0, 0, 0.06);border-radius: 4px;color: rgb(0, 0);overflow-anchor: auto;><span leaf="">lora_rank=32</span></code><span leaf="">,按公式&nbsp;</span><code style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 14px;font-variation-settings: normal;background: none 0% auto repeat scroll padding-box border-box rgba(0, 0, 0.06);border-radius: 4px;color: rgb(0, 0);overflow-anchor: auto;><span leaf="">scale = lora_alpha / sqrt(lora_rank)</span></code><span leaf="">,原&nbsp;</span><code style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 14px;font-variation-settings: normal;background: none 0% auto repeat scroll padding-box border-box rgba(0, 0, 0.06);border-radius: 4px;color: rgb(0, 0);overflow-anchor: auto;><span leaf="">scale≈0.7</span></code><span leaf="">,调整后&nbsp;</span><code style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 14px;font-variation-settings: normal;background: none 0% auto repeat scroll padding-box border-box rgba(0, 0, 0.06);border-radius: 4px;color: rgb(0, 0);overflow-anchor: auto;><span leaf="">8 / sqrt(32)≈1.4</span></code><span leaf="">,增强参数更新的缩放强度,适配调高的学习率</span> </section></td> </tr> <tr style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0.666667px 0px 0px;border-style: solid;border-top-color: rgba(0, 0, 0, 0.08);border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 0px;overflow-anchor: auto;"> <td data-colwidth="111" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"><code style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 14px;font-variation-settings: normal;background: none 0% auto repeat scroll padding-box border-box rgba(0, 0, 0.06);border-radius: 4px;color: rgb(0, 0);overflow-anchor: auto;><span leaf=""><span textstyle="" style="background-color: rgb(255, 255, 255);">save_model_per_epoch</span></span></code></td> <td data-colwidth="109" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">1</span> </section></td> <td data-colwidth="120" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">1</span> </section></td> <td style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">每 epoch 保存一次,42 条数据训练快,1 次 /epoch 足够记录过程,保留该值</span> </section></td> </tr> <tr style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0.666667px 0px 0px;border-style: solid;border-top-color: rgba(0, 0, 0, 0.08);border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 0px;overflow-anchor: auto;"> <td data-colwidth="111" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"><code style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 14px;font-variation-settings: normal;background: none 0% auto repeat scroll padding-box border-box rgba(0, 0, 0.06);border-radius: 4px;color: rgb(0, 0);overflow-anchor: auto;><span leaf=""><span textstyle="" style="background-color: rgb(255, 255, 255);">dyn_bsz</span></span></code></td> <td data-colwidth="109" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">true</span> </section></td> <td data-colwidth="120" style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border-width: 0px 0.666667px 0px 0px;border-top-style: initial;border-right-style: solid;border-bottom-style: initial;border-left-style: initial;border-top-color: initial;border-right-color: rgba(0, 0, 0, 0.08);border-bottom-color: initial;border-left-color: initial;border-image: initial;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">true</span> </section></td> <td style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px;margin: 0px;padding: 12px 18px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;max-width: 448px;overflow-anchor: auto;"> <section> <span leaf="">保持开启,最大化利用 seq_len×batch_size 填充 token,加速小数据训练效率,保留该值</span> </section></td> </tr> </tbody> </table> <h3 style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin-top: 28px;margin-right: 0px;margin-bottom: 12px !important;margin-left: 0px;padding-top: 0px;padding-right: 0px;padding-bottom: 0px !important;padding-left: 0px;font-size: 18px;font-weight: 700;line-height: 28px;color: rgb(0, 0, 0);overflow-anchor: auto;font-family: Inter, -apple-system, " system-ui, segoe ui, sf pro sc, display, icons, pingfang hiragino sans gb, microsoft yahei, helvetica neue, helvetica, arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">2、核心调整逻辑</span></h3> <ol style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin-top: 8px !important;margin-right: 0px;margin-bottom: 8px !important;margin-left: 0px;padding: 0px 0px 0px 20px;list-style: none;overflow-anchor: auto;color: rgb(0, 0, 0);font-family: Inter, -apple-system, " system-ui, segoe ui, sf pro sc, display, icons, pingfang hiragino sans gb, microsoft yahei, helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px 0px 0px 4px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;list-style-type: decimal;overflow-anchor: auto;"><strong style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-weight: 600;color: rgb(0, 0, 0) !important;font-size: 16px;line-height: 28px;overflow-anchor: auto;"><span leaf="">小数据强化学习</span></strong> <section> <span leaf="">通过增加&nbsp;</span><code style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 14px;font-variation-settings: normal;background: none 0% auto repeat scroll padding-box border-box rgba(0, 0, 0.06);border-radius: 4px;color: rgb(0, 0);overflow-anchor: auto;><span leaf="">epoch</span></code><span leaf="">、适度调高&nbsp;</span><code style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 14px;font-variation-settings: normal;background: none 0% auto repeat scroll padding-box border-box rgba(0, 0, 0.06);border-radius: 4px;color: rgb(0, 0);overflow-anchor: auto;><span leaf="">learning_rate</span></code><span leaf="">,让模型在有限数据中多轮学习、加速收敛,弥补数据量少的短板。</span> </section></li> <li style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 8px 0px 0px;padding: 0px 0px 0px 4px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;list-style-type: decimal;overflow-anchor: auto;"><strong style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-weight: 600;color: rgb(0, 0, 0) !important;font-size: 16px;line-height: 28px;overflow-anchor: auto;"><span leaf="">控制过拟合风险</span></strong> <section> <span leaf="">保留&nbsp;</span><code style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 14px;font-variation-settings: normal;background: none 0% auto repeat scroll padding-box border-box rgba(0, 0, 0.06);border-radius: 4px;color: rgb(0, 0);overflow-anchor: auto;><span leaf="">lora_rank=32</span></code><span leaf="">(相对 64 更安全),配合&nbsp;</span><code style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 14px;font-variation-settings: normal;background: none 0% auto repeat scroll padding-box border-box rgba(0, 0, 0.06);border-radius: 4px;color: rgb(0, 0);overflow-anchor: auto;><span leaf="">warmup</span></code><span leaf="">&nbsp;延长学习率适应过程,避免模型 “死记硬背” 小数据集。</span> </section></li> <li style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 8px 0px 0px;padding: 0px 0px 0px 4px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;list-style-type: decimal;overflow-anchor: auto;"><strong style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-weight: 600;color: rgb(0, 0, 0) !important;font-size: 16px;line-height: 28px;overflow-anchor: auto;"><span leaf="">参数协同适配</span></strong> <section> <span leaf="">调整&nbsp;</span><code style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 14px;font-variation-settings: normal;background: none 0% auto repeat scroll padding-box border-box rgba(0, 0, 0.06);border-radius: 4px;color: rgb(0, 0);overflow-anchor: auto;><span leaf="">lora_alpha</span></code><span leaf="">&nbsp;匹配学习率变化,保证 Lora 模块参数更新的缩放比例合理,让训练更稳定。</span> </section></li> </ol> <p><span leaf="">按此配置,可在小数据场景下高效训练模型学习符号格式对齐,同时降低过拟合可能,若训练后验证集效果不佳(如过拟合),可进一步降低&nbsp;</span><code style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 16px;font-variation-settings: normal;background: none 0% auto repeat scroll padding-box border-box rgba(0, 0, 0.06);border-radius: 4px;color: 0.85) !important;overflow-anchor: auto;font-weight: 400;line-height: 28px;><span leaf="">epoch</span></code><span leaf="">&nbsp;或&nbsp;</span><code style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 16px;font-variation-settings: normal;background: none 0% auto repeat scroll padding-box border-box rgba(0, 0, 0.06);border-radius: 4px;color: 0.85) !important;overflow-anchor: auto;font-weight: 400;line-height: 28px;><span leaf="">learning_rate</span></code><span leaf="">&nbsp;;若收敛慢,则继续微调学习率或&nbsp;</span><code style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 16px;font-variation-settings: normal;background: none 0% auto repeat scroll padding-box border-box rgba(0, 0, 0.06);border-radius: 4px;color: 0.85) !important;overflow-anchor: auto;font-weight: 400;line-height: 28px;><span leaf="">warmup</span></code><span leaf="">&nbsp;比例 。</span></p> <p data-pm-slice="0 0 []"><span leaf="">参数配置有了:</span></p> <section style="text-align: center;" nodeleaf=""> <img src="/upload/cc01e941072eee209b198a718fee03b3.png" class="rich_pages wxw-img" data-ratio="1.16" data-s="300,640" data-type="png" data-w="600" type="block" data-imgfileid="304706606"> </section> <p data-pm-slice="0 0 []"><span leaf="">“混入预置数据集”和“验证集”</span><span leaf="">怎么配?</span></p> <section style="text-align: center;" nodeleaf=""> <img src="/upload/ac918c10331e82de2ebbd8dfc90c9ff1.png" class="rich_pages wxw-img" data-ratio="0.6064814814814815" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="304706607"> </section> <p data-pm-slice="0 0 []"><span leaf="">Query:“给出下面这两个指标的值: 混入预置数据集:在用户上传的训练集数据中混入豆包模型的SFT(Supervised Fine Tuning,有监督微调)数据,混入比例表示混合后SFT数据占总数据量的比例 &nbsp;验证集:Validation Set,模型训练过程中,用于确定网络结构以及调整模型的超参数。可以从训练集中随机分割一定比例作为验证集,也可以上传独立于训练集的数据集。”</span></p> <p><span leaf="">Answer:</span></p> <p><span leaf="">结合你提供的 40 条专项微调数据(</span><span leaf="">输出格式对齐V1</span><span leaf="">),以及 “Quality Is All You Need” 和 “Less Is More” 的原则,这两个指标的推荐值及设置逻辑如下:</span></p> <h3 style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin-top: 28px;margin-right: 0px;margin-bottom: 12px !important;margin-left: 0px;padding-top: 0px;padding-right: 0px;padding-bottom: 0px !important;padding-left: 0px;font-size: 18px;font-weight: 700;line-height: 28px;color: rgb(0, 0, 0) !important;overflow-anchor: auto;"><span leaf="">1. 混入预置数据集比例:0%(不混入)</span></h3> <p><strong style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-weight: 600;color: rgb(0, 0, 0) !important;font-size: 16px;line-height: 28px;overflow-anchor: auto;"><span leaf="">核心原因</span></strong><span leaf="">:</span></p> <ul style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin-top: 8px !important;margin-right: 0px;margin-bottom: 8px !important;margin-left: 0px;padding: 0px 0px 0px 20px;list-style: none;overflow-anchor: auto;" class="list-paddingleft-1"> <li style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px 0px 0px 4px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;list-style-type: disc;overflow-anchor: auto;"> <section> <span leaf="">本次 SFT 目标极其明确(仅解决 “-”“/” 前后多余空格问题),40 条数据已精准覆盖该场景,信号纯度极高。</span> </section></li> <li style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 8px 0px 0px;padding: 0px 0px 0px 4px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;list-style-type: disc;overflow-anchor: auto;"> <section> <span leaf="">混入通用 SFT 数据会稀释专项信号,可能导致模型注意力分散(比如通用数据中可能存在符号格式不严格的样本,反而干扰学习)。</span> </section></li> <li style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 8px 0px 0px;padding: 0px 0px 0px 4px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;list-style-type: disc;overflow-anchor: auto;"> <section> <span leaf="">小数据场景下,“纯专项数据” 更利于模型快速锁定目标规律,符合 “少而精” 的对齐逻辑。</span> </section></li> </ul> <h3 style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin-top: 28px;margin-right: 0px;margin-bottom: 12px !important;margin-left: 0px;padding-top: 0px;padding-right: 0px;padding-bottom: 0px !important;padding-left: 0px;font-size: 18px;font-weight: 700;line-height: 28px;color: rgb(0, 0, 0) !important;overflow-anchor: auto;"><span leaf="">2. 验证集比例:20%(从训练集中随机分割)</span></h3> <p><strong style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-weight: 600;color: rgb(0, 0, 0) !important;font-size: 16px;line-height: 28px;overflow-anchor: auto;"><span leaf="">推荐设置</span></strong><span leaf="">:</span></p> <ul style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin-top: 8px !important;margin-right: 0px;margin-bottom: 8px !important;margin-left: 0px;padding: 0px 0px 0px 20px;list-style: none;overflow-anchor: auto;" class="list-paddingleft-1"> <li style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px 0px 0px 4px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;list-style-type: disc;overflow-anchor: auto;"> <section> <span leaf="">从 40 条数据中随机抽取 8 条作为验证集,剩余 32 条作为训练集。</span><span leaf=""><br></span><strong style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-weight: 600;color: rgb(0, 0, 0) !important;font-size: 16px;line-height: 28px;overflow-anchor: auto;"><span leaf="">核心原因</span></strong><span leaf="">:</span> </section></li> <li style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 8px 0px 0px;padding: 0px 0px 0px 4px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;list-style-type: disc;overflow-anchor: auto;"> <section> <span leaf="">数据量极小(仅 40 条),独立验证集难以保证分布一致性,从训练集中分割更能匹配数据分布。</span> </section></li> <li style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 8px 0px 0px;padding: 0px 0px 0px 4px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;list-style-type: disc;overflow-anchor: auto;"> <section> <span leaf="">20% 比例既能保留足够训练样本(32 条),又能通过验证集监控过拟合(比如验证集中符号格式的正确率是否与训练集一致)。</span> </section></li> <li style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 8px 0px 0px;padding: 0px 0px 0px 4px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;list-style-type: disc;overflow-anchor: auto;"> <section> <span leaf="">若后续补充数据至 100 条以上,可考虑独立验证集;当前规模下,优先保证验证集与训练集的场景一致性。</span> </section></li> </ul> <p><span leaf="">这两个指标的设置均以 “强化专项信号、控制过拟合” 为核心,适配小数据量下的精准微调需求。</span></p> <section style="text-align: center;" nodeleaf=""> <img src="/upload/6b59f1ffc1860777525eb7d2330b1ac9.png" class="rich_pages wxw-img" data-ratio="1.1307901907356948" data-s="300,640" data-type="png" data-w="734" type="block" data-imgfileid="304706608"> </section> <p data-pm-slice="0 0 []"><span leaf="">万事俱备,点击“提交精调任务”。</span></p> <section class="mp_common_sticker_iframe_wrp" nodeleaf=""> <mp-common-sticker data-pluginname="emotion" data-md5="693ab1fa201de5e830431192ca3625cb" data-emoji_url="https://mmbiz.qpic.cn/sz_mmbiz_gif/G3Ggb8COicY3nab8mq6xjO1L1XlYAdjOuBp3yxGw0xA4ibJTjMwFW6EFM6bcTx4NtFdPjyAxAc9myD4Ml0UbwCiaw/0" data-is_ban="0" data-type="0" data-loading="0" data-error="0" data-inserted="1"></mp-common-sticker> </section> <section> <span leaf="">经过</span><span leaf="">49 分 38 秒,SFT任务执行完成。</span> </section> <section style="text-align: center;" nodeleaf=""> <img src="/upload/12b59158b0f5062e2f686f740f9f3c97.png" class="rich_pages wxw-img" data-ratio="0.55" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="304706609"> </section> <p data-pm-slice="0 0 []"><span leaf="">看下效果:</span></p> <section style="text-align: center;" nodeleaf=""> <img src="/upload/4018d93fa638f60a706edde00b974d44.png" class="rich_pages wxw-img" data-ratio="0.20833333333333334" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="304706610"> </section> <p data-pm-slice="0 0 []"><span leaf="" data-pm-slice="1 1 [" para,{tagname:p,attributes:{data-pm-slice:0 0 []},namespaceuri:http: www.w3.org 1999 xhtml}]>精调后,</span><span leaf="">格式ok。</span></p> <section style="text-align: center;" nodeleaf=""> <img src="/upload/5b26b5c36c64eda09e79217997812476.png" class="rich_pages wxw-img" data-ratio="0.21296296296296297" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="304706611"> </section> <p data-pm-slice="0 0 []"><span leaf="" data-pm-slice="1 1 [" para,{tagname:p,attributes:{data-pm-slice:0 0 []},namespaceuri:http: www.w3.org 1999 xhtml}]>精调后,</span><span leaf="">格式ok。</span></p> <section style="text-align: center;" nodeleaf=""> <img src="/upload/b6021380c90e566b5ecbebacff4d63f2.png" class="rich_pages wxw-img" data-ratio="0.1638888888888889" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="304706612"> </section> <p data-pm-slice="0 0 []"><span leaf="" data-pm-slice="1 1 [" para,{tagname:p,attributes:{data-pm-slice:0 0 []},namespaceuri:http: www.w3.org 1999 xhtml}]>精调后,</span><span leaf="">格式ok。</span></p> <section style="text-align: center;" nodeleaf=""> <img src="/upload/9cbf81168c7a6e1b621b1f06faec3260.png" class="rich_pages wxw-img" data-ratio="0.23055555555555557" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="304706613"> </section> <p data-pm-slice="0 0 []"><span leaf="">精调后,格式ok。</span></p> <section class="mp_common_sticker_iframe_wrp" nodeleaf=""> <mp-common-sticker data-pluginname="emotion" data-md5="7f684059a31b5dd80cb1b85a2d881372" data-emoji_url="https://mmbiz.qpic.cn/sz_mmbiz_gif/HNMJdGcocUu7ntc0G7gdmKGvqKdyIZicfPa9kqib9zVsdgdFcQW7MsEwqrzfOz7eib4ukgBZ2a3BNs10Ea4ulVuOw/0" data-is_ban="0" data-type="0" data-loading="0" data-error="0" data-inserted="1"></mp-common-sticker> </section> <section> <span leaf="">等等,你忘记大模型的“幻觉”了吗?</span> </section> <section style="text-align: center;" nodeleaf=""> <img src="/upload/7b04c90d495bb920b9df68e8dd8a801d.png" class="rich_pages wxw-img" data-ratio="0.6620370370370371" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="304706619"> </section> <section> <h3 style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin-top: 28px;margin-right: 0px;margin-bottom: 12px !important;margin-left: 0px;padding-top: 0px;padding-right: 0px;padding-bottom: 0px !important;padding-left: 0px;font-size: 18px;font-weight: 700;line-height: 28px;color: rgb(0, 0, 0);overflow-anchor: auto;font-family: Inter, -apple-system, " system-ui, segoe ui, sf pro sc, display, icons, pingfang hiragino sans gb, microsoft yahei, helvetica neue, helvetica, arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; data-pm-slice="0 0 []"><span leaf="" data-pm-slice="1 1 [" para,{tagname:h3,attributes:{style:-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0);outline: none;border: 0px solid;margin-top: 28px;margin-right: 0px;margin-bottom: 12px !important;margin-left: 0px;padding-top: 0px;padding-right: 0px;padding-bottom: !important;padding-left: 0px;font-size: 18px;font-weight: 700;line-height: 28px;color: rgb(0, 0);overflow-anchor: auto;font-family: inter, -apple-system, \system-ui\, \segoe ui\, \sf pro sc\, display\, icons\, \pingfang \hiragino sans gb\, \microsoft yahei\, \helvetica neue\, helvetica, arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;,data-pm-slice:0 0 []},namespaceuri:http: www.w3.org 1999 xhtml}]>要有PlanB。</span></h3> <h2 data-tool="mdnice编辑器" data-pm-slice="0 0 []" style="-webkit-tap-highlight-color: transparent;margin: 20px 10px 0px 0px;padding: 0px;outline: 0px;font-weight: bold;font-size: 22px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;background-color: rgb(255, 255, 255);color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc, cambria, cochin, georgia, times, times new roman, serif;letter-spacing: normal;text-align: left;visibility: visible;><span style="-webkit-tap-highlight-color: transparent;margin: 0px;padding: 0px 0px 0px 10px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: STHeitiSC-Light;color: rgb(14, 136, 235);font-weight: bolder;display: inline-block;border-left: 5px solid rgb(14, 136, 235);visibility: visible;letter-spacing: 0.578px;"><span leaf="" style="-webkit-tap-highlight-color: transparent;margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible;">PlanB</span></span></h2> </section> <h3 style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin-top: 28px;margin-right: 0px;margin-bottom: 12px !important;margin-left: 0px;padding-top: 0px;padding-right: 0px;padding-bottom: 0px !important;padding-left: 0px;font-size: 18px;font-weight: 700;line-height: 28px;color: rgb(0, 0, 0);overflow-anchor: auto;font-family: Inter, -apple-system, " system-ui, segoe ui, sf pro sc, display, icons, pingfang hiragino sans gb, microsoft yahei, helvetica neue, helvetica, arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; data-pm-slice="0 0 []"><span leaf="">1、后处理层:兜底的格式修正</span></h3> <p><span leaf="">若训练后仍有残留问题,通过</span><strong style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-weight: 600;color: rgb(0, 0, 0) !important;font-size: 16px;line-height: 28px;overflow-anchor: auto;"><span leaf="">推理阶段后处理</span></strong><span leaf="">兜底修正,确保最终输出符合要求:</span></p> <h4 style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin-top: 24px;margin-right: 0px;margin-left: 0px;padding-top: 0px;padding-right: 0px;padding-left: 0px;font-size: 16px;font-weight: 700;line-height: 28px;color: rgb(0, 0, 0);overflow-anchor: auto;font-family: Inter, -apple-system, " system-ui, segoe ui, sf pro sc, display, icons, pingfang hiragino sans gb, microsoft yahei, helvetica neue, helvetica, arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;margin-bottom: 8px !important;padding-bottom: 0px !important;><span leaf="">1.1 正则表达式替换(简单有效)</span></h4> <p><span leaf="">推理时,用 Python 正则自动清理符号前后空</span></p> <p><span leaf="" style="white-space: pre-wrap;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 13px;font-variation-settings: normal;border-radius: 4px;word-break: normal;word-spacing: normal;overflow-wrap: normal;hyphens: none;line-height: 1.5;tab-size: 4;-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgb(177, 94, 242);>import</span><code style="white-space:pre-wrap;-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 13px;font-variation-settings: normal;background: transparent;border-radius: 4px;color: rgba(0, 0, 0.85);word-break: normal;word-spacing: normal;overflow-wrap: normal;hyphens: none;line-height: 1.5;tab-size: 4;overflow-anchor: auto;><span leaf="" style="white-space: pre-wrap;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 13px;font-variation-settings: normal;border-radius: 4px;word-break: normal;word-spacing: normal;overflow-wrap: normal;hyphens: none;line-height: 1.5;tab-size: 4;-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgb(177, 94, 242);>&nbsp;re</span><span leaf=""><br></span><span leaf=""><br></span><span leaf="" style="white-space: pre-wrap;font-family: Menlo, Monaco, Consolas, " courier new, monospace;font-feature-settings: normal;font-size: 13px;font-variation-settings: normal;border-radius: 4px;word-break: normal;word-spacing: normal;overflow-wrap: normal;hyphens: none;line-height: 1.5;tab-size: 4;-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgb(177, 94, 242);>def&nbsp;</span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgb(255, 93, 77);"><span leaf="">fix_symbol_format</span></span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85);"><span leaf="">(</span></span><span leaf="">text</span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85);"><span leaf="">)</span></span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85);"><span leaf="">:</span></span><span leaf=""><br></span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.45);"><span leaf=""># 处理“/”前后空格</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; text&nbsp;</span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85) !important;"><span leaf="">=</span></span><span leaf="">&nbsp;re</span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85);"><span leaf="">.</span></span><span leaf="">sub</span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85);"><span leaf="">(</span></span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgb(77, 166, 33);"><span leaf="">r'\s*/\s*'</span></span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85);"><span leaf="">,</span></span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgb(77, 166, 33);"><span leaf="">'/'</span></span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85);"><span leaf="">,</span></span><span leaf="">&nbsp;text</span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85);"><span leaf="">)</span></span><span leaf=""><br></span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.45);"><span leaf=""># 处理“-”前后空格(注意区分连字符与减号,可根据场景调整)</span></span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; text&nbsp;</span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85) !important;"><span leaf="">=</span></span><span leaf="">&nbsp;re</span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85);"><span leaf="">.</span></span><span leaf="">sub</span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85);"><span leaf="">(</span></span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgb(77, 166, 33);"><span leaf="">r'\s*-\s*'</span></span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85);"><span leaf="">,</span></span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgb(77, 166, 33);"><span leaf="">'-'</span></span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85);"><span leaf="">,</span></span><span leaf="">&nbsp;text</span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85);"><span leaf="">)</span></span><span leaf=""><br></span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgb(177, 94, 242);"><span leaf="">return</span></span><span leaf="">&nbsp;text</span><span leaf=""><br></span><span leaf=""><br></span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.45);"><span leaf=""># 推理示例</span></span><span leaf=""><br></span><span leaf="">output&nbsp;</span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85) !important;"><span leaf="">=</span></span><span leaf="">&nbsp;model</span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85);"><span leaf="">.</span></span><span leaf="">generate</span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85);"><span leaf="">(</span></span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85);"><span leaf="">.</span></span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85);"><span leaf="">.</span></span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85);"><span leaf="">.</span></span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85);"><span leaf="">)</span></span><span leaf=""><br></span><span leaf="">fixed_output&nbsp;</span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85) !important;"><span leaf="">=</span></span><span leaf="">&nbsp;fix_symbol_format</span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85);"><span leaf="">(</span></span><span leaf="">output</span><span style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;overflow-anchor: auto;background: transparent;color: rgba(0, 0, 0, 0.85);"><span leaf="">)</span></span></code></p> <p style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin-top: 24px;margin-right: 0px;margin-left: 0px;padding-top: 0px;padding-right: 0px;padding-left: 0px;font-size: 16px;font-weight: 700;line-height: 28px;color: rgb(0, 0, 0);overflow-anchor: auto;font-family: Inter, -apple-system, " system-ui, segoe ui, sf pro sc, display, icons, pingfang hiragino sans gb, microsoft yahei, helvetica neue, helvetica, arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;margin-bottom: 8px !important;padding-bottom: 0px !important;><code><span leaf="">1.2 构建格式校验器</span></code></p> <ul style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin-top: 8px !important;margin-right: 0px;margin-bottom: 8px !important;margin-left: 0px;padding: 0px 0px 0px 20px;list-style: none;overflow-anchor: auto;color: rgb(0, 0, 0);font-family: Inter, -apple-system, " system-ui, segoe ui, sf pro sc, display, icons, pingfang hiragino sans gb, microsoft yahei, helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px 0px 0px 4px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;list-style-type: disc;overflow-anchor: auto;"> <section> <span leaf="">用规则引擎或小型分类模型,对输出文本做 “格式合规性检查”:</span> </section></li> <ul style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin-top: 4px !important;margin-right: 0px;margin-bottom: 0px;margin-left: 0px;padding-top: 0px;padding-right: 0px;padding-bottom: 0px;padding-left: 20px !important;list-style: none;overflow-anchor: auto;" class="list-paddingleft-1"> <li style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 4px 0px 0px;padding: 0px 0px 0px 4px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;list-style-type: circle;overflow-anchor: auto;"> <section> <span leaf="">若检测到符号格式错误,触发 “重新生成” 或 “后处理替换”;</span> </section></li> <li style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 4px 0px 0px;padding: 0px 0px 0px 4px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;list-style-type: circle;overflow-anchor: auto;"> <section> <span leaf="">结合业务场景,可定制更复杂的格式规则(如 “/ 仅用于领域术语分隔,日常对话中保留空格”)。</span> </section></li> </ul> </ul> <h3 style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin-top: 28px;margin-right: 0px;margin-bottom: 12px !important;margin-left: 0px;padding-top: 0px;padding-right: 0px;padding-bottom: 0px !important;padding-left: 0px;font-size: 18px;font-weight: 700;line-height: 28px;color: rgb(0, 0, 0);overflow-anchor: auto;font-family: Inter, -apple-system, " system-ui, segoe ui, sf pro sc, display, icons, pingfang hiragino sans gb, microsoft yahei, helvetica neue, helvetica, arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">2、验证与迭代:闭环优化确保效果</span></h3> <section> <strong style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-weight: 600;color: rgb(0, 0, 0) !important;font-size: 16px;line-height: 28px;overflow-anchor: auto;"><span leaf="">2.1 构建格式测试集</span></strong> </section> <section style="text-align: left;"> <strong><span leaf="" style="color: rgba(0, 0, 0, 0.9);font-size: 17px;font-family: mp-quote, " pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;line-height: 1.6;letter-spacing: 0.034em;font-style: normal;font-weight: normal;><span textstyle="" style="font-size: 16px;">准备 100 + 条含 “/”、“-” 的测试用例,覆盖训练 / 未训练场景,验证格式对齐率。</span></span></strong> </section> <section> <strong style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-weight: 600;color: rgb(0, 0, 0) !important;font-size: 16px;line-height: 28px;overflow-anchor: auto;"><span leaf="">2.2 迭代优化流程</span></strong> </section> <ol style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin-top: 8px !important;margin-right: 0px;margin-bottom: 8px !important;margin-left: 0px;padding: 0px 0px 0px 20px;list-style: none;overflow-anchor: auto;color: rgb(0, 0, 0);font-family: Inter, -apple-system, " system-ui, segoe ui, sf pro sc, display, icons, pingfang hiragino sans gb, microsoft yahei, helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <ul style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin-top: 4px !important;margin-right: 0px;margin-bottom: 0px;margin-left: 0px;padding-top: 0px;padding-right: 0px;padding-bottom: 0px;padding-left: 20px !important;list-style: none;overflow-anchor: auto;" class="list-paddingleft-1"> <li style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 4px 0px 0px;padding: 0px 0px 0px 4px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;list-style-type: circle;overflow-anchor: auto;"> <section> <span leaf="">若测试集格式错误率>5%,回到</span><strong style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-weight: 600;color: rgb(0, 0, 0) !important;font-size: 16px;line-height: 28px;overflow-anchor: auto;"><span leaf="">数据层</span></strong><span leaf="">补充样本;</span> </section></li> <li style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 4px 0px 0px;padding: 0px 0px 0px 4px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;list-style-type: circle;overflow-anchor: auto;"> <section> <span leaf="">若训练中验证集格式正确率低,调整</span><strong style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-weight: 600;color: rgb(0, 0, 0) !important;font-size: 16px;line-height: 28px;overflow-anchor: auto;"><span leaf="">训练参数</span></strong><span leaf="">增强约束;</span> </section></li> <li style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 4px 0px 0px;padding: 0px 0px 0px 4px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;list-style-type: circle;overflow-anchor: auto;"> <section> <span leaf="">若推理后仍有漏网,优化</span><strong style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-weight: 600;color: rgb(0, 0, 0) !important;font-size: 16px;line-height: 28px;overflow-anchor: auto;"><span leaf="">后处理规则</span></strong><span leaf="">覆盖更多边界情况。</span> </section></li> </ul> </ol> <h3 style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin-top: 28px;margin-right: 0px;margin-bottom: 12px !important;margin-left: 0px;padding-top: 0px;padding-right: 0px;padding-bottom: 0px !important;padding-left: 0px;font-size: 18px;font-weight: 700;line-height: 28px;color: rgb(0, 0, 0);overflow-anchor: auto;font-family: Inter, -apple-system, " system-ui, segoe ui, sf pro sc, display, icons, pingfang hiragino sans gb, microsoft yahei, helvetica neue, helvetica, arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;><span leaf="">核心逻辑总结</span></h3> <p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:" mp-quote, pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;>格式对齐的本质是</span><strong><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:" mp-quote, pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;>让模型在小数据中精准学习 “人类对符号的严格规范”</span></strong><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:" mp-quote, pingfang sc, system-ui, -apple-system, blinkmacsystemfont, helvetica neue, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;>,需通过:</span></p> <section> <span leaf=""><br></span> </section> <ul style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin-top: 8px !important;margin-right: 0px;margin-bottom: 8px !important;margin-left: 0px;padding: 0px 0px 0px 20px;list-style: none;overflow-anchor: auto;color: rgb(0, 0, 0);font-family: Inter, -apple-system, " system-ui, segoe ui, sf pro sc, display, icons, pingfang hiragino sans gb, microsoft yahei, helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px 0px 0px 4px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;list-style-type: disc;overflow-anchor: auto;"><strong style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-weight: 600;color: rgb(0, 0, 0) !important;font-size: 16px;line-height: 28px;overflow-anchor: auto;"><span leaf="">数据强化</span></strong> <section> <span leaf="">提供充足且清晰的格式样本;</span> </section></li> <li style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 8px 0px 0px;padding: 0px 0px 0px 4px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;list-style-type: disc;overflow-anchor: auto;"><strong style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-weight: 600;color: rgb(0, 0, 0) !important;font-size: 16px;line-height: 28px;overflow-anchor: auto;"><span leaf="">训练优化</span></strong> <section> <span leaf="">让模型聚焦格式学习而非过拟合;</span> </section></li> <li style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 8px 0px 0px;padding: 0px 0px 0px 4px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;list-style-type: disc;overflow-anchor: auto;"><strong style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px;font-weight: 600;color: rgb(0, 0, 0) !important;font-size: 16px;line-height: 28px;overflow-anchor: auto;"><span leaf="">后处理兜底</span></strong> <section> <span leaf="">确保极端情况也能修正。</span> </section></li> </ul> <section> <span leaf=""><br></span> </section> <section class="mp_common_sticker_iframe_wrp" nodeleaf=""> <mp-common-sticker data-pluginname="emotion" data-md5="ab329ba8ef7099ded90bbb8ebbe99026" data-emoji_url="https://mmbiz.qpic.cn/sz_mmbiz_gif/Q5kfpj3T93E3AIV27R5zupaj6sXz9LYEl8VbkeBDwVgSqjk18Nxure9FCSqQiaXH6zkmNtHaSlq0s5frtzQp6rw/0" data-is_ban="0" data-type="0" data-loading="0" data-error="0" data-inserted="1"></mp-common-sticker> </section> <p><span leaf=""><br></span></p> <p style="text-align: left;"><span leaf="">SFT训练数据集</span></p> <p style="text-align: left;"><span leaf="" data-pm-slice="1 1 [" para,{tagname:p,attributes:{style:text-align: left;},namespaceuri:http: www.w3.org 1999 xhtml}]>https://f.chaojihao.net/ai/dataset/sft/format/symbol_format_finetune_data20250808V2.jsonl</span></p> <p><span leaf="">SFT 最佳实践</span></p> <p><span leaf="">https://www.volcengine.com/docs/82379/1221664</span></p> <p><span leaf="">创建模型精调任务</span></p> <p><span leaf="">https://www.volcengine.com/docs/82379/1099459</span></p> <p><span leaf="">最后再补张图,没有完全理解的朋友可以整体再看一下,找找感觉:</span></p> <section style="text-align: center;" nodeleaf=""> <img src="/upload/d45ded2ecbcd4a806895316645768ac8.png" class="rich_pages wxw-img" data-ratio="0.5435185185185185" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="304706614"> </section> <blockquote class="js_blockquote_wrap"> <section class="js_blockquote_digest"> <p style="text-align: left;"><span leaf="">面对传统Code RAG和Code Agent在召回率、准确率和稳定性上的不足,以及领域“黑话”和代码风格差异带来的挑战,使用以大模型微调(SFT)为核心的解决方案成功解决了问题。</span></p> </section> <section class="blockquote_info js_blockquote_source" data-json="%7B%22type%22%3A%22inner%22%2C%22article%22%3A%7B%22title%22%3A%22%E8%AE%A9AI%E8%AF%BB%E6%87%82%E4%BB%A3%E7%A0%81%E9%9C%80%E6%B1%82%EF%BC%9A%E6%A8%A1%E5%9D%97%E5%8C%96%E5%A4%A7%E6%A8%A1%E5%9E%8B%E5%BE%AE%E8%B0%83%E5%8A%A9%E5%8A%9B%E9%AB%98%E6%95%88%E4%BB%A3%E7%A0%81%E7%90%86%E8%A7%A3%E4%B8%8E%E8%BF%81%E7%A7%BB%22%2C%22url%22%3A%22https%3A%2F%2Fmp.weixin.qq.com%2Fs%2FW4LfBSPKDwHDDptcr390tQ%22%2C%22nickname%22%3A%22%E9%98%BF%E9%87%8C%E4%BA%91%E5%BC%80%E5%8F%91%E8%80%85%22%2C%22authorName%22%3A%22%E5%8D%9A%E8%B7%83%22%7D%7D"> <span class="blockquote_biz">博跃,公众号:阿里云开发者<a class="blockquote_article" href="https://mp.weixin.qq.com/s/W4LfBSPKDwHDDptcr390tQ">让AI读懂代码需求:模块化大模型微调助力高效代码理解与迁移</a></span> </section> </blockquote> <section> <span leaf=""><br></span> </section> <section> <span leaf="">什么是</span><span leaf="" data-pm-slice="1 1 [" para,{tagname:p,attributes:{},namespaceuri:http: www.w3.org 1999 xhtml}]>LoRA?</span> </section> <p style="text-align: left;"><span leaf="">LoRA(Low-Rank Adaptation,低秩适应)是一种高效微调大模型的技术,由微软团队于 2021 年提出。</span></p> <p style="text-align: left;"><span leaf="">LoRA的核心是在不改变原模型参数的情况下,通过添加少量低秩矩阵参数来适配新任务。训练时仅优化这些新增的少量参数,大幅降低计算成本;推理时将低秩矩阵的影响合并回原模型,不增加额外开销。这种方式用极少参数就能实现接近全量微调的效果,广泛用于大模型的任务适配。</span></p> <p data-pm-slice="0 0 []" style="text-align: left;"><span leaf="">具体来说,传统微调需要更新模型的全部参数,当模型规模庞大(如数十亿甚至千亿参数)时,会消耗大量计算资源和存储空间。而 LoRA 的做法是:</span></p> <ul style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin-top: 8px !important;margin-right: 0px;margin-bottom: 8px !important;margin-left: 0px;padding: 0px 0px 0px 20px;list-style: none;overflow-anchor: auto;color: rgb(0, 0, 0);font-family: Inter, -apple-system, " system-ui, segoe ui, sf pro sc, display, icons, pingfang hiragino sans gb, microsoft yahei, helvetica neue, helvetica, arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial; class="list-paddingleft-1"> <li style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 0px;padding: 0px 0px 0px 4px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;list-style-type: disc;overflow-anchor: auto;"> <section> <span leaf="">在预训练模型的关键层(如注意力层的权重矩阵)中插入两个低秩矩阵(可理解为维度较小的矩阵),这两个矩阵的乘积近似于该层在新任务上所需的参数更新量;</span> </section></li> <li style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 8px 0px 0px;padding: 0px 0px 0px 4px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;list-style-type: disc;overflow-anchor: auto;"> <section> <span leaf="">训练过程中,仅优化这两个低秩矩阵的参数,而冻结预训练模型的原始参数;</span> </section></li> <li style="-webkit-font-smoothing: antialiased;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);outline: none;border: 0px solid;margin: 8px 0px 0px;padding: 0px 0px 0px 4px;font-size: 16px;font-weight: 400;line-height: 28px;color: rgba(0, 0, 0, 0.85) !important;list-style-type: disc;overflow-anchor: auto;"> <section> <span leaf="">推理时,将低秩矩阵的乘积与原始参数相加,等效于完成了参数更新,不增加额外计算开销。</span> </section></li> </ul> <p style="text-align: left;"><span leaf="">由于低秩矩阵的参数规模远小于原始模型参数(通常仅为原始参数的 1%-10%),LoRA 大幅降低了微调的成本,同时还能有效避免过拟合,在多种自然语言处理任务(如文本分类、翻译、问答等)中表现出色,目前已成为大模型微调的主流技术之一。</span></p> <section> <span leaf=""><span textstyle="" style="color: rgb(255, 255, 255);">立秋了,晚上天变凉了。21点慢跑3公里,今天只是微微出汗,上周每次跑完都是汗如雨下的。</span></span> </section> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>

小白都会用的一站式 AI 数字人镜像(Heygem+Multitalk+Flux)

作者:微信小助手

<section style="background: linear-gradient(135deg, #f5f7fa 0%, #e4e8f0 100%);padding: 20px;font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;"> <section style="background: #ffffff;border-radius: 16px;padding: 24px;margin-bottom: 20px;box-shadow: 0 4px 20px rgba(0,0,0,0.05);"> <p style="font-size: 28px;font-weight: bold;color: #1a365d;text-align: center;margin-bottom: 16px;"><span leaf="">前言</span></p> <p style="font-size: 16px;line-height: 1.8;color: #2d3748;margin-bottom: 16px;"><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;AI数字人今年特别火热,百度数字人、京东数字人等应用纷纷投入获客,用来解决企业营销困境、老板出镜难、拍摄文案剪辑成功高等问题。</span></p> <p style="font-size: 16px;line-height: 1.8;color: #2d3748;margin-bottom: 16px;"><span leaf="">但普通人想要使用,费用高昂,市面上服务收费高达</span><span style="color: #e53e3e;font-weight: bold;"><span leaf="">3~5元/分钟</span></span><span leaf="">,开源方案(如heygem/multitalk)部署复杂,使用门槛极高。</span></p> <p style="font-size: 16px;line-height: 1.8;color: #2d3748;margin-bottom: 16px;"><span leaf="">以下是一家数字人小程序的价格截图。</span></p> <section> <span leaf=""><img class="rich_pages wxw-img" src="https://mmbiz.qpic.cn/mmbiz_jpg/1R4u3u9HsYvVLibkc2icxIL3ucUdpianpicjL2YrHYoGTnNHDKxw6ia4ia5kqKPzj35bmXVw2mFhqibCuF5m9oPibuXPhw/0?wx_fmt=jpeg&amp;from=appmsg" data-cropselx2="490" data-cropsely2="490" data-imgfileid="100000337" data-ratio="0.30864197530864196" data-s="300,640" src="/upload/137b40f4fd42787c136e331760e79be6.jpg" data-type="jpeg" data-w="729" style="width: 100%;height: auto;border-radius: 12px;margin: 16px 0;">&nbsp; &nbsp;</span> </section> </section> <section style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);border-radius: 16px;padding: 24px;margin-bottom: 20px;color: white;"> <p style="font-size: 28px;font-weight: bold;text-align: center;margin-bottom: 16px;text-shadow: 0 2px 4px rgba(0,0,0,0.2);"><span leaf="">一站式AI数字人</span></p> <p style="font-size: 16px;line-height: 1.8;margin-bottom: 16px;text-shadow: 0 1px 2px rgba(0,0,0,0.1);"><span leaf="">为解决以上痛点,作者在国内最好的 GPU 平台:仙宫云,集合顶尖开源大模型,打造一站式</span><span style="font-weight: bold;font-size: 18px;"><span leaf="">AI数字人web镜像</span></span><span leaf="">,实现一键部署,网页操作,使用体验极简高效。只有有网就能用,还能共享给同事朋友。</span></p> <section> <span leaf=""><img class="rich_pages wxw-img" src="https://mmbiz.qpic.cn/mmbiz_png/1R4u3u9HsYvGmgDlnvNroYUhtFibs865lwgX2YoAfwDeLzicyYv5vhWwS46DRVXojzE6U7sWAjVWR9BPJac0CWGQ/0?wx_fmt=png&amp;from=appmsg" data-cropselx2="490" data-cropsely2="490" data-imgfileid="100000328" data-ratio="0.73359375" data-s="300,640" src="/upload/9a38118d9c6fd0b7d531e7cff00876a3.png" data-type="png" data-w="1280" style="width: 100%;height: auto;border-radius: 12px;margin: 16px 0;box-shadow: 0 4px 15px rgba(0,0,0,0.15);">&nbsp; &nbsp;</span> </section> </section> <section style="background: #ffffff;border-radius: 16px;padding: 24px;margin-bottom: 20px;box-shadow: 0 4px 20px rgba(0,0,0,0.05);"> <p style="font-size: 22px;font-weight: bold;color: #2b6cb0;margin-bottom: 12px;border-left: 4px solid #3182ce;padding-left: 12px;"><span leaf="">Flux生成(可选)</span></p> <p style="font-size: 16px;line-height: 1.8;color: #2d3748;margin-bottom: 16px;"><span leaf="">采用顶级开源Flux大模型生成超写实主播形象,支持多风格定制,从商务精英到虚拟偶像全覆盖。</span></p> <section> <span leaf=""><img class="rich_pages wxw-img" src="https://mmbiz.qpic.cn/mmbiz_png/1R4u3u9HsYvVLibkc2icxIL3ucUdpianpicj1dicjJBSDJkDEc2AF3WRicwDloxGuJoOnc5JnEOtENJRwU3FhDQMWEUA/0?wx_fmt=png&amp;from=appmsg" data-cropselx2="490" data-cropsely2="490" data-imgfileid="100000338" data-ratio="0.5472287275565965" data-s="300,640" src="/upload/1279040d6695e3126d8a113cec1986e5.png" data-type="png" data-w="2562" style="width: 100%;height: auto;border-radius: 12px;margin: 16px 0;">&nbsp; &nbsp;</span> </section> </section> <section style="background: #ffffff;border-radius: 16px;padding: 24px;margin-bottom: 20px;box-shadow: 0 4px 20px rgba(0,0,0,0.05);"> <p style="font-size: 22px;font-weight: bold;color: #2b6cb0;margin-bottom: 12px;border-left: 4px solid #3182ce;padding-left: 12px;"><span leaf="">Flux-kontext改图(可选)</span></p> <p style="font-size: 16px;line-height: 1.8;color: #2d3748;margin-bottom: 16px;"><span leaf="">革命性"用嘴改图"技术,通过语音指令实时修改数字人形象细节,服装、场景、表情随心调整。</span></p> <p style="font-size: 16px;line-height: 1.8;color: #2d3748;margin-bottom: 16px;"><span leaf="">不会英文?不怕,用上页面自带的豆包智能体,输入中文提示词,就能获得优化后的英文提示词,一键粘贴。</span></p> <section> <span leaf=""><img class="rich_pages wxw-img" src="https://mmbiz.qpic.cn/mmbiz_png/1R4u3u9HsYvVLibkc2icxIL3ucUdpianpicjeXQ6wgb8Fsj9HfW27b9nSsAZNicrGJBObHRsRSvtSXlUhLagbnta53Q/0?wx_fmt=png&amp;from=appmsg" data-cropselx2="490" data-cropsely2="490" data-imgfileid="100000339" data-ratio="0.6488661302121433" data-s="300,640" src="/upload/7e4f514acc7f449ce71beef63468794a.png" data-type="png" data-w="2734" style="width: 100%;height: auto;border-radius: 12px;margin: 16px 0;">&nbsp; &nbsp;</span> </section> </section> <section style="background: #ffffff;border-radius: 16px;padding: 24px;margin-bottom: 20px;box-shadow: 0 4px 20px rgba(0,0,0,0.05);"> <p style="font-size: 22px;font-weight: bold;color: #2b6cb0;margin-bottom: 12px;border-left: 4px solid #3182ce;padding-left: 12px;"><span leaf="">Multitalk图片生成视频</span></p> <p style="font-size: 16px;line-height: 1.8;color: #2d3748;margin-bottom: 16px;"><span leaf="">使用上生成的单张图片,即可生成数字人视频样本,上传口播音频,底层依靠阿里 Wan 视频大模型,生成自然度媲美真人主播。</span></p> <p style="font-size: 16px;line-height: 1.8;color: #2d3748;margin-bottom: 16px;"><span leaf="">建议只生成 5-10s 样本视频即可,生成 5s 视频大概耗时5 分钟(48G4090D)。</span></p> <p style="font-size: 16px;line-height: 1.8;color: #2d3748;margin-bottom: 16px;"><span leaf="">拿到主播5s样本视频,扔给后续 Heygem 去快速生成。</span></p> <section> <span leaf=""><img class="rich_pages wxw-img" src="https://mmbiz.qpic.cn/mmbiz_png/1R4u3u9HsYvVLibkc2icxIL3ucUdpianpicjJG1p7IJp8G85zQWEDPicd57Ffej1TJmElcdqIfZHCiaPI745R23Fxy2w/0?wx_fmt=png&amp;from=appmsg" data-cropselx2="490" data-cropsely2="490" data-imgfileid="100000340" data-ratio="0.8422738190552442" data-s="300,640" src="/upload/f594ad3bc0ba756992e2b58c17bbd8aa.png" data-type="png" data-w="2498" style="width: 100%;height: auto;border-radius: 12px;margin: 16px 0;">&nbsp; &nbsp;</span><span leaf="" data-pm-slice="1 1 [" para,{tagname:section,attributes:{style:background: linear-gradient(135deg, #f5f7fa 0%, #e4e8f0 100%); padding: 20px; font-family: -apple-system, blinkmacsystemfont, &#39;segoe ui&#39;, &#39;pingfang sc&#39;, &#39;hiragino sans gb&#39;, &#39;microsoft yahei&#39;, sans-serif;},namespaceuri:http: www.w3.org 1999 xhtml},para,{tagname:section,attributes:{style:background: #ffffff; border-radius: 16px; 24px; margin-bottom: box-shadow: 0 4px 20px rgba(0,0,0,0.05);},namespaceuri:http: xhtml},para,{tagname:p,attributes:{style:font-size: line-height: 1.8; color: #2d3748; 16px;},namespaceuri:http: xhtml}]><br></span> </section> <section> <span leaf="" data-pm-slice="1 1 [" para,{tagname:section,attributes:{style:background: linear-gradient(135deg, #f5f7fa 0%, #e4e8f0 100%); padding: 20px; font-family: -apple-system, blinkmacsystemfont, &#39;segoe ui&#39;, &#39;pingfang sc&#39;, &#39;hiragino sans gb&#39;, &#39;microsoft yahei&#39;, sans-serif;},namespaceuri:http: www.w3.org 1999 xhtml},para,{tagname:section,attributes:{style:background: #ffffff; border-radius: 16px; 24px; margin-bottom: box-shadow: 0 4px 20px rgba(0,0,0,0.05);},namespaceuri:http: xhtml},para,{tagname:p,attributes:{style:font-size: line-height: 1.8; color: #2d3748; 16px;},namespaceuri:http: xhtml}]>没有音频?使用内置的 IndexTTS 开源音色克隆模型,内置多种热门音色。</span> </section> <section> <span leaf="">B 站开源的 IndexTTS,克隆音色又快又像,超赞!</span> </section> <section style="text-align: center;" nodeleaf=""> <img class="rich_pages wxw-img js_insertlocalimg" data-imgfileid="100000341" data-ratio="0.515625" data-s="300,640" src="/upload/aca18b4392b65ab4ec3130be9cd5c701.png" data-type="png" data-w="1280" type="block"> </section> <section> <span leaf="" data-pm-slice="1 1 [" para,{tagname:section,attributes:{style:background: linear-gradient(135deg, #f5f7fa 0%, #e4e8f0 100%); padding: 20px; font-family: -apple-system, blinkmacsystemfont, &#39;segoe ui&#39;, &#39;pingfang sc&#39;, &#39;hiragino sans gb&#39;, &#39;microsoft yahei&#39;, sans-serif;},namespaceuri:http: www.w3.org 1999 xhtml},para,{tagname:section,attributes:{style:background: #ffffff; border-radius: 16px; 24px; margin-bottom: box-shadow: 0 4px 20px rgba(0,0,0,0.05);},namespaceuri:http: xhtml},para,{tagname:p,attributes:{style:font-size: line-height: 1.8; color: #2d3748; 16px;},namespaceuri:http: xhtml}]><br></span> </section> </section> <section style="background: #ffffff;border-radius: 16px;padding: 24px;margin-bottom: 20px;box-shadow: 0 4px 20px rgba(0,0,0,0.05);"> <p style="font-size: 22px;font-weight: bold;color: #2b6cb0;margin-bottom: 12px;border-left: 4px solid #3182ce;padding-left: 12px;"><span leaf="">Heygem快速生成短视频</span></p> <p style="font-size: 16px;line-height: 1.8;color: #2d3748;margin-bottom: 16px;"><span leaf="">Heygem 作为开源顶流数字人,虽然速度快,但是部署起来超级难。</span></p> <p style="font-size: 16px;line-height: 1.8;color: #2d3748;margin-bottom: 16px;"><span leaf="">这次我们内置到镜像,同时优化成(语音+文本)双模式驱动。(heygem 本身只有音频驱动)</span></p> <p style="font-size: 16px;line-height: 1.8;color: #2d3748;margin-bottom: 16px;"><span leaf="">同时支持管理数字人形象,上传的同时设置为常用,可以避免每次上传,下次使用只要下拉列表,就能选择上传过的数字人形象啦!</span></p> <section> <span leaf=""><img class="rich_pages wxw-img" src="https://mmbiz.qpic.cn/mmbiz_png/1R4u3u9HsYvVLibkc2icxIL3ucUdpianpicjwVCRyp1qBgLicXOGicUnjwAjsEEB91YQWsjYOZLaZiaRcqcbWWnzWaV6A/0?wx_fmt=png&amp;from=appmsg" data-cropselx2="490" data-cropsely2="490" data-imgfileid="100000342" data-ratio="0.804380664652568" data-s="300,640" src="/upload/b34e980b77a3484a02c2af10a3a2f4a6.png" data-type="png" data-w="2648" style="width: 100%;height: auto;border-radius: 12px;margin: 16px 0;">&nbsp; &nbsp;速度真的超级快!30 多秒的口播视频,只用了 1 分半钟。</span> </section> <section> <span leaf=""><br></span> </section> <section> <span leaf="">&nbsp; &nbsp;一个小时大概能生成 20 分钟视频,如果按市面数字人费用 算,20*5=100 块。</span> </section> <section> <span leaf="">&nbsp;&nbsp;</span> </section> <section> <span leaf="">&nbsp; 但是在仙宫云1 个小时显卡才2 块左右,性价比超 50 倍。</span> </section> <section style="text-align: center;" nodeleaf=""> <img class="rich_pages wxw-img js_insertlocalimg" data-imgfileid="100000344" data-ratio="0.9215686274509803" data-s="300,640" src="/upload/4d56697c5bb4f3892db57b1fe7947aaf.png" data-type="png" data-w="714" type="block"> </section> <section> <span leaf="">而且镜像内置优化了 Heygem,可以上传无音视频,特别适合从即梦或者可灵生成的无配音AI 视频。</span><span leaf="" data-pm-slice="1 1 [" para,{tagname:section,attributes:{style:background: linear-gradient(135deg, #f5f7fa 0%, #e4e8f0 100%);padding: 20px;font-family: -apple-system, blinkmacsystemfont, &#39;segoe ui&#39;, &#39;pingfang sc&#39;, &#39;hiragino sans gb&#39;, &#39;microsoft yahei&#39;, sans-serif;},namespaceuri:http: www.w3.org 1999 xhtml},para,{tagname:section,attributes:{style:background: #ffffff;border-radius: 16px;padding: 24px;margin-bottom: 20px;box-shadow: 0 4px 20px rgba(0,0,0,0.05);},namespaceuri:http: xhtml},para,{tagname:section,attributes:{},namespaceuri:http: xhtml}]>(解决了heygem 必须要用带音频的样本视频问题)</span> </section> <section> <span leaf=""><br></span> </section> <section> <span leaf="">其实这种方式是最快的,免去了前面的操作,但是要注意侵权问题</span> </section> <section> <span leaf=""><br></span> </section> <section> <span leaf="">(ps:怎么去视频水印,👇进群交流)</span> </section> </section> <section> <span leaf=""><br></span> </section> <section style="background: linear-gradient(135deg, #48bb78 0%, #38a169 100%);border-radius: 16px;padding: 24px;margin-bottom: 20px;color: white;"> <p style="font-size: 22px;font-weight: bold;margin-bottom: 16px;text-shadow: 0 2px 4px rgba(0,0,0,0.2);"><span leaf="">怎么使用</span></p> <p style="font-size: 16px;line-height: 1.8;margin-bottom: 16px;text-shadow: 0 1px 2px rgba(0,0,0,0.1);"><span style="display: block;margin-bottom: 8px;"><span leaf="">1️⃣ 先访问仙宫云平台,通过邀请注册就能白嫖5个小时4090 显卡</span></span><span style="display: block;margin-bottom: 8px;"><span leaf=""><span textstyle="" style="color: rgb(255, 251, 0);">https://www.xiangongyun.com/register/ICEKVE</span></span></span></p> <p style="font-size: 16px;line-height: 1.8;margin-bottom: 16px;text-shadow: 0 1px 2px rgba(0,0,0,0.1);"><span style="display: block;margin-bottom: 8px;"><span leaf="">2️⃣ 然后选择本镜像一键部署(根据使用选择不同显卡配置)</span></span><span style="display: block;margin-bottom: 8px;"><span leaf=""><span textstyle="" style="color: rgb(255, 251, 0);">https://www.xiangongyun.com/image/detail/f0ceaf6d-749c-4c14-8eb4-aadcd8ccf9b0?r=ICEKVE</span></span></span></p> <section style="text-align: center;" nodeleaf=""> <img class="rich_pages wxw-img js_insertlocalimg" data-imgfileid="100000345" data-ratio="0.6634146341463415" data-s="300,640" src="/upload/85d02e0f67aa77ab21636a753378658c.png" data-type="png" data-w="1230" type="block"> </section> <p style="font-size: 16px;line-height: 1.8;margin-bottom: 16px;text-shadow: 0 1px 2px rgba(0,0,0,0.1);"><span style="display: block;margin-bottom: 8px;"><span leaf="">3️⃣ 部署成功后,通过“小白都会用的 web 端”进入 web 页面</span></span></p> <section style="text-align: center;" nodeleaf=""> <img class="rich_pages wxw-img js_insertlocalimg" data-imgfileid="100000346" data-ratio="0.24765625" data-s="300,640" src="/upload/2df3f6617e07fe3a5b2ba4698305964b.png" data-type="png" data-w="1280" type="block"> </section> <p style="font-size: 16px;line-height: 1.8;margin-bottom: 16px;text-shadow: 0 1px 2px rgba(0,0,0,0.1);"><span style="display: block;margin-bottom: 8px;"><span leaf="" data-pm-slice="1 1 [" para,{tagname:section,attributes:{style:background: linear-gradient(135deg, #f5f7fa 0%, #e4e8f0 100%); padding: 20px; font-family: -apple-system, blinkmacsystemfont, &#39;segoe ui&#39;, &#39;pingfang sc&#39;, &#39;hiragino sans gb&#39;, &#39;microsoft yahei&#39;, sans-serif;},namespaceuri:http: www.w3.org 1999 xhtml},para,{tagname:section,attributes:{style:background: #48bb78 #38a169 border-radius: 16px; 24px; margin-bottom: color: white;},namespaceuri:http: xhtml},para,{tagname:p,attributes:{style:font-size: line-height: 1.8; text-shadow: 0 1px 2px rgba(0,0,0,0.1);},namespaceuri:http: xhtml},node,{tagname:span,attributes:{style:display: block; 8px;},namespaceuri:http: xhtml}]>刚部署成功后,如果生成失败,请稍等2-4 分钟,请后台服务启动成功。</span></span></p> <p style="font-size: 16px;line-height: 1.8;margin-bottom: 16px;text-shadow: 0 1px 2px rgba(0,0,0,0.1);"><span style="display: block;"><span leaf="">4️⃣ 尽情使用吧(一定要仔细看使用说明后再用</span><span leaf="">)</span></span></p> </section> <section style="background: #ffffff;border-radius: 16px;padding: 24px;box-shadow: 0 4px 20px rgba(0,0,0,0.05);"> <p style="font-size: 22px;font-weight: bold;color: #2b6cb0;margin-bottom: 16px;text-align: center;"><span leaf="">技术交流</span></p> <p style="font-size: 16px;line-height: 1.8;color: #2d3748;margin-bottom: 16px;text-align: center;"><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;📧 微信:</span><span leaf="">yyllff2025</span><span leaf=""><br></span><span leaf="">&nbsp; &nbsp; &nbsp; &nbsp;💬 社群:扫描下方二维码加入技术交流群</span><span leaf=""><br></span></p> <section> <span leaf=""><img class="rich_pages wxw-img" src="https://mmbiz.qpic.cn/mmbiz_jpg/1R4u3u9HsYvVLibkc2icxIL3ucUdpianpicjeWccHgibs3Mtqy3I2IsIPkMWiaAhCiaryZxMrmf60oSFraAibcKJWLfBDg/0?wx_fmt=jpeg&amp;from=appmsg" data-cropselx2="200" data-cropsely2="200" data-imgfileid="100000347" data-ratio="1.5149700598802396" data-s="300,640" src="/upload/57762dd1ffa3a218b4b559aa673b43d3.jpg" data-type="jpeg" data-w="668" style="width: 200px;height: 200px;border-radius: 12px;margin: 0 auto;display: block;box-shadow: 0 4px 15px rgba(0,0,0,0.1);"></span> </section> <section> <span leaf=""><br></span> </section> <section> <span leaf="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span> </section> <section> <span leaf=""><br></span> </section> <section> <span leaf="">&nbsp;视频版教程 &nbsp;&nbsp;</span> </section> <section class="channels_iframe_wrp" nodeleaf=""> <mp-common-videosnap class="js_uneditable custom_select_card channels_iframe videosnap_video_iframe videosnap_video_iframe" data-pluginname="mpvideosnap" data-url="https://findermp.video.qq.com/251/20304/stodownload?encfilekey=rjD5jyTuFrIpZ2ibE8T7YmwgiahniaXswqzBDVb6Xp5kvVYH3o9gqSZ6f7HuWibLkejUzTo6UBFIfhnyEBGf2fWricdiaXe1VSV2YSHH0ObqjzMyiahttoV5toNPw&amp;token=ic1n0xDG6awiccsKJuloURRm31ZWAzj1jge6gkNwYCuJiaDXplxEN4uqpIZBHbUEpXywSTqbRtjoeaZGGvtl4vF2ficX94pxax97W6dD91xa4U30Slek9VcrlxR2r48S1dagjFibn6JTaW7Kn87RBCrWQMKQVBdLqQIsTpXOzIfpLkCw&amp;idx=1&amp;hy=SH&amp;m=&amp;scene=2&amp;uzid=1" data-headimgurl="http://wx.qlogo.cn/finderhead/0T8yO33zeegqqjZJJPzJOlwDsibgSMu5hTCaSpxL1XmF29XH0Wtkr9y2Z0HeqfcWTHib3p43H48nk/0" data-username="v2_060000231003b20faec8c4e38011cad1c903e533b07730cfcf5e78a2a714f6b542ed4d881338@finder" data-nickname="AI先锋榜" data-desc="仙宫云+Heygem强强联合,小白也能玩转 AI 数字人! #AI #数字人 #仙宫云 #Heygem #AI视频 #教程 " data-nonceid="2929715760978074542" data-width="1920" data-height="1080" data-type="video" data-id="export/UzFfAgtgekIEAQAAAAAAu7QAcXIbXAAAAAstQy6ubaLX4KHWvLEZgBPEkIBUcjtbdeaPzNPgMItqnzHH_iIJRmIRiNvW7P3V"></mp-common-videosnap> </section> <section> <span leaf=""><br></span> </section> </section> </section> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>

解决vcpkg使用VS2022报错问题

作者:じ☆ve不哭

使用vcpkg安装librdkafka时执行`vcpkg install librdkafka`出现以下错误 ``` error: in triplet x64-windows: Unable to find a valid Visual Studio instance Could not locate a complete Visual Studio instance The following paths were examined for Visual Studio instances: D:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Auxiliary/Build\vcvarsall.bat ``` 在官方github issues找到解决方法,原文地址:`https://github.com/microsoft/vcpkg/issues/22074` ### 1. 安装英语语言包 利用VS的官方安装器安装语言包 - 英语。 ### 2. 安装完整相关组件 这是vcpkg官方给出的解决办法,把一下组件都要安装上 - C++相关: 用于 Windows 的 C++ CMake 工具 C++核心功能 Visual Studio 最新的生成工具 MS Build - Windows SDK(安装一个即可): Windows 8 SDK 8.1 Windows 10 SDK 10.0.18362 Windows 10 SDK 10.0.19041 Windows 10 SDK 10.0.20348 Windows 11 SDK 11.0.22000 - ARM/ARM64相关: ARM相关的最新生成工具 - UWP相关: UWP最新的生成工具 3. 再安装2019版本的MSVC编译器(对我有用) 再已安装最新2022版本的MSVC编译器的情况下,再安装一个旧版本2019的MSVC编译器。 利用VS官方安装器安装`单个组件 - MSVC v142 - VS 2019 C++ x64/x86 生成工具(v14.29-16.11)`,ARM同样安装对应版本的2019 MSVC。 因为最终发现出现这个问题是因为最新的MSVC编译器与旧版本的vcpkg不兼容,如果不想更新vcpkg,就再安装一个2019的编译器。 ### 我最终安装的相关配置 ![1b24d624ccb0484db48a150c32d0dfd0.png](https://studyjava.cn/files/articlePicture/zsljava11757384237194555.png)