同一个大模型,为什么换一套接口就能更会做事?

同一个大模型,为什么换一套接口就能更会做事?

你大概率遇到过这种怪事:同一个模型,同一个问题,在网页对话框里问它,回答得四平八稳、滴水不漏,但也没什么用;换到某个工具或者应用里再问一遍,它突然就像换了个人,能查资料、能算数、能一步步把活干完。模型没变,参数没变,变的只是外面那层“接口”。

这事我琢磨了很久,也踩过不少坑。早些年我以为模型能力是固定的,接口就是个传话筒,后来自己动手搭过几套不同形态的调用方式,才发现接口这层壳子对最终效果的影响,远比大多数人想象的大。它决定了模型能看到什么、能做什么、做完之后谁来验收。说白了,模型是发动机,接口是变速箱加底盘,同一台发动机装在不同底盘上,跑出来的表现完全不是一回事。

这篇文章我想把这件事讲透。不管你是刚接触大模型调用、只会复制粘贴提示词的新手,还是已经写过一些调用脚本、但总觉得效果不稳定的开发者,都能从里面找到能直接用的东西。我会从接口到底改变了什么讲起,拆解几种主流形态的差异,给出可以照着搭的最小实现,最后把我自己踩过的坑整理成一份排查清单。全程不聊虚的,只讲能落地的部分。

1. 先搞清楚:接口到底改变了什么

1.1 模型能力是固定的,但“可发挥空间”不是

先把一个容易混淆的概念掰开。模型本身的能力,在训练完成那一刻就基本定型了。它认识多少字、会不会推理、擅长什么领域,这些是权重里写死的东西,你换什么接口都改不了。但模型在具体一次对话里能发挥出多少,取决于三件事:它看到了什么上下文、它被允许做什么动作、它的输出被怎么处理。

网页对话框是最“素”的一种形态。你输入一段话,它回一段话,结束。它看不到你的文件,不能上网,不能执行代码,也没有第二次机会修正自己。这种形态下,模型只能靠肚子里那点存货硬答,遇到需要实时信息或者多步计算的任务,自然就露怯。

而一套更完整的接口,会在模型外面套一层循环。模型说“我需要查一下某个数据”,接口就去查,把结果塞回给模型;模型说“我要算一下”,接口就调计算器,把结果塞回去;模型输出完了,接口还能检查格式对不对、有没有漏步骤,不对就让它重来。这一套下来,同一个模型能做的事就完全不一样了。

注意:很多人把“模型能力”和“产品能力”混为一谈。你用的某个应用很聪明,不代表它背后的模型比别家强,很可能只是它的接口层做得更厚。

1.2 三种典型接口形态的差异

我把常见的调用形态分成三类,方便你对照自己手上的场景。

形态模型能看到什么能做什么动作典型表现
纯对话只有当前对话历史只能输出文本通用问答还行,复杂任务容易断片
带工具调用对话历史加工具返回结果可调用外部函数能查数据、能算数、能操作外部系统
带编排循环完整任务状态加历史步骤可多轮调用、可自我修正能完成多步骤复杂任务

第一类就是最基础的对话接口,你给它一段文字,它还你一段文字。第二类在对话基础上增加了工具调用能力,模型可以主动说“我要调用某个函数”,接口执行完把结果还给它。第三类更进一步,外面有一层编排逻辑,会管理整个任务的进度,决定什么时候继续、什么时候重试、什么时候收尾。

大部分让人觉得“更会做事”的接口,本质都是第二类和第三类。它们没有让模型变聪明,而是给了模型手脚和记忆。

1.3 为什么“换接口”比“换模型”更划算

这里有个很现实的考量。换模型意味着重新评估、重新调提示词、重新测试,成本高且不确定。而优化接口层,是在现有模型基础上做加法,风险可控,收益直接。

我做过一个对比,同一个模型,纯对话形态下做一份需要查三个数据源、做两次计算的报告,成功率大概三成,经常漏步骤或者编数据。加上工具调用和一轮校验之后,同样的任务成功率能到八成以上。模型一个字没改,只是外面多了一层调度。

这也是为什么很多团队在模型选型上没那么纠结,反而在接口层投入大量精力。模型差一点,接口补一补还能用;接口烂,再好的模型也发挥不出来。

2. 接口层到底加了哪些“外挂”

2.1 工具调用:给模型装上手脚

工具调用是效果提升最明显的一环。原理不复杂:你提前告诉模型有哪些函数可用,每个函数叫什么、干什么、需要什么参数。模型在回答过程中,如果判断需要用到某个函数,就不直接输出最终答案,而是输出一个结构化的调用请求。接口层拿到这个请求,执行对应函数,把结果再喂回给模型,模型基于结果继续往下走。

举个具体例子。你问“某个城市现在的天气怎么样”,纯对话模型只能根据训练数据里可能过时的信息瞎猜。但如果你给它配了一个查天气的函数,它会先输出一个调用请求,接口去查实时数据,把结果返回,模型再组织成自然语言回答你。

这里的关键在于,函数描述写得好不好,直接决定模型会不会用、用得对不对。我见过太多人随便写一句“查询数据”就扔给模型,结果模型根本不知道什么时候该调、该传什么参数。函数描述要像写给一个新同事看的说明书,说清楚什么场景下用、每个参数是什么含义、返回什么格式。

# 一个函数描述的示例结构 { "name": "query_sales_data", "description": "查询指定时间段和地区的销售数据。当用户询问销售额、销量、同比环比等数据时使用此函数。", "parameters": { "type": "object", "properties": { "region": { "type": "string", "description": "地区名称,如'华东'、'华南'" }, "start_date": { "type": "string", "description": "开始日期,格式YYYY-MM-DD" }, "end_date": { "type": "string", "description": "结束日期,格式YYYY-MM-DD" } }, "required": ["region", "start_date", "end_date"] } }

这段描述里,我特意写了“当用户询问销售额、销量、同比环比等数据时使用”,这就是在帮模型做判断。参数描述里给了示例格式,模型就不容易传错。这些细节看着琐碎,但实测下来对调用准确率影响很大。

提示:函数数量不要一次给太多。我试过一次性挂二十多个函数,模型反而容易选错。控制在十个以内,按场景分组,需要哪组给哪组,准确率明显更高。

2.2 上下文管理:让模型记住该记的

纯对话形态下,上下文就是聊天记录,越聊越长,最后要么超长度限制,要么模型被无关信息干扰。而一套好的接口层,会主动管理上下文,决定哪些信息该留、哪些该压缩、哪些该丢。

常见的做法是分层。系统提示词放最前面,定义角色和规则;然后是任务相关的背景资料;再然后是最近的对话历史;最后是当前问题。当长度接近上限时,优先压缩或丢弃早期的对话历史,保留系统提示和关键背景。

还有一种做法叫“摘要记忆”。当对话很长时,接口层先让模型把前面的内容总结成一段话,用摘要替代原始记录,这样既保留了关键信息,又大幅缩短了长度。我自己在做一个长周期任务助手时用过这招,效果比硬截断好很多,模型不会突然忘记前面聊过什么。

上下文管理里有个容易被忽略的点:信息的摆放顺序会影响模型注意力。放在开头和结尾的信息,模型记得最牢;放在中间的容易被忽略。所以关键指令要么放最前面,要么在结尾再强调一遍。这是我从多次调试里总结出来的,不是什么玄学,是模型注意力机制的特性。

2.3 输出校验与重试:给结果加一道质检

模型输出不稳定是常态,同样的输入,两次结果可能一次对一次错。接口层能做的一件事,就是在输出之后加一道校验,不合格就让它重来。

校验分两种。一种是格式校验,比如你要求输出JSON,那就检查能不能解析、字段全不全。另一种是内容校验,比如要求必须包含某个计算结果,那就检查结果里有没有。格式校验用代码就能做,内容校验可以再调一次模型来判断,或者用规则匹配。

重试也不是简单重复。第一次失败后,把失败原因告诉模型,让它带着反馈重新生成,成功率会高很多。比如“你上次的输出缺少了日期字段,请补上”,比单纯说“重新生成”有效得多。

# 一个简单的校验重试逻辑示意 def generate_with_retry(prompt, max_retries=3): for i in range(max_retries): result = call_model(prompt) if validate(result): return result # 把失败原因追加到提示里,让模型知道哪里错了 prompt = prompt + f"\n上次输出有问题:{get_issue(result)},请修正后重新输出。" return result # 多次失败后返回最后一次结果

这段逻辑不复杂,但加上之后,输出合格率提升非常明显。尤其是对格式要求严格的场景,比如要生成结构化数据给下游系统用,这道质检基本是必须的。

2.4 任务编排:把大活拆成小步

复杂任务一次性丢给模型,它容易顾此失彼。接口层可以做的一件事,是把大任务拆成多个小步骤,一步步来,每步的输出作为下一步的输入。

比如做一份分析报告,可以拆成:先收集数据、再清洗数据、再计算指标、再生成结论、最后组织成文。每一步都是一个独立的模型调用,接口层负责把上一步的结果传给下一步,并在中间做必要的校验和转换。

这样做的好处是每步都简单,模型不容易出错;坏处是调用次数多,成本和耗时增加。所以拆分的粒度要权衡。我的经验是,单个步骤如果模型一次能做对,就别拆;如果经常出错或者漏东西,就拆开。

编排还有一种形态叫“规划加执行”。先让模型出一个计划,列出要做哪几步,然后接口层按计划逐步执行,执行过程中如果发现计划有问题,还可以让模型调整计划。这种方式适合步骤不确定的任务,灵活性更高。

3. 动手搭一套最小可用的增强接口

3.1 整体架构与选型考量

我下面给一套最小实现,不依赖特定平台,思路通用。整体分四层:接入层负责接收请求,编排层负责管理流程,模型层负责调用模型,工具层负责执行具体函数。

选型上,编排逻辑用Python写最省事,生态全、调试方便。工具函数可以是本地函数,也可以是外部服务的调用。模型调用部分,只要支持工具调用能力的接口都能用,具体用哪家看你的实际情况。

为什么不建议一上来就上重型框架?我试过几个编排框架,功能确实全,但学习成本和调试成本都高,出了问题不好定位。对于大多数场景,自己写一两百行编排逻辑就够了,透明可控,改起来也快。等业务复杂到一定程度,再考虑引入框架也不迟。

3.2 核心代码骨架

先定义一个工具注册表,把可用的函数登记进去。

# 工具注册表 TOOLS = {} def register_tool(name, description, parameters): def decorator(func): TOOLS[name] = { "function": func, "schema": { "name": name, "description": description, "parameters": parameters } } return func return decorator # 注册一个查数据的工具 @register_tool( name="query_data", description="查询业务数据。当需要获取具体数值时使用。", parameters={ "type": "object", "properties": { "metric": {"type": "string", "description": "指标名称"}, "period": {"type": "string", "description": "时间段,如'本月'"} }, "required": ["metric", "period"] } ) def query_data(metric, period): # 实际查询逻辑,这里用模拟数据代替 return {"metric": metric, "period": period, "value": 12345}

然后是主循环,负责调用模型、处理工具调用请求、把结果喂回去。

def run_agent(user_input, max_turns=10): messages = [ {"role": "system", "content": "你是一个助手,可以调用工具来完成任务。"}, {"role": "user", "content": user_input} ] for turn in range(max_turns): # 调用模型,传入可用工具的描述 response = call_model(messages, tools=[t["schema"] for t in TOOLS.values()]) # 如果模型没有调用工具,说明它给出了最终答案 if not response.get("tool_calls"): return response["content"] # 处理工具调用 messages.append(response) # 把模型的调用请求加入历史 for tool_call in response["tool_calls"]: tool_name = tool_call["name"] tool_args = tool_call["arguments"] # 执行工具 result = TOOLS[tool_name]["function"](**tool_args) # 把结果作为工具返回消息加入历史 messages.append({ "role": "tool", "tool_call_id": tool_call["id"], "content": str(result) }) return "达到最大轮次限制"

这段代码不长,但已经包含了工具调用的核心循环。模型判断需要工具就调,调完拿到结果继续,直到给出最终答案或者达到轮次上限。

3.3 参数选择与调优过程

几个关键参数需要根据实际情况调。

最大轮次限制是防止死循环的。设太小,复杂任务做不完;设太大,万一模型陷入循环会浪费大量调用。我的经验值是十到十五轮,大多数任务够用,真遇到需要更多轮次的,说明任务该拆分了。

工具返回结果的格式也影响效果。返回纯文本,模型理解起来可能不准;返回结构化数据,模型更容易提取关键信息。我一般返回JSON字符串,字段名用英文,值可以是中文,模型处理起来比较稳。

还有一个容易忽略的参数是温度。做工具调用时,温度调低一点,让模型输出更确定,减少乱调工具的情况。做创意生成时再调高。同一个任务里不同步骤可以用不同温度,接口层完全可以按步骤设置。

提示:调试阶段把每一轮的模型输入输出都打日志,出问题时能快速定位是哪一步跑偏了。我早期没打日志,排查一个问题花了大半天,后来加上日志,同样的问题十分钟就能找到原因。

4. 常见问题与排查清单

4.1 模型不调用工具怎么办

这是最常见的问题。模型该调工具的时候不调,直接凭记忆瞎答。原因通常有三个:工具描述不清楚、系统提示没强调要用工具、或者模型本身对工具调用的支持不好。

先检查工具描述。描述里要明确写“当用户询问某某类问题时使用此工具”,把触发场景写清楚。然后检查系统提示,加一句“涉及具体数据时必须调用工具查询,不要凭记忆回答”。如果还不行,可能是模型能力问题,换一个对工具调用支持更好的模型试试。

还有一种情况是模型调了工具但参数传错。这通常是参数描述不够明确,补充示例格式和取值范围能改善。

4.2 多轮之后模型“忘了”前面的事

长对话里模型忘记早期信息,是上下文管理的典型问题。先确认是不是超了长度限制,如果是,就要做压缩或截断。截断时优先保留系统提示和最近几轮,早期的对话可以摘要化。

如果不是长度问题,那可能是信息摆放位置的问题。关键信息如果埋在中间,容易被忽略。可以在每轮输入的最后再重复一遍关键约束,比如“记住,输出必须是JSON格式”。

我自己的做法是维护一个“任务状态”对象,把关键信息结构化存起来,每轮都把它放在提示的显眼位置。这样不管对话多长,核心信息始终在模型眼前。

4.3 工具调用结果模型不用

有时候工具明明返回了正确结果,模型却视而不见,还是按自己想法答。这通常是工具返回格式的问题。如果返回的是一大段文本,模型可能抓不住重点;改成结构化数据,并且明确标注哪个字段是答案,模型就容易用了。

还有一种可能是模型在调用工具之前就已经“想好”了答案,工具结果只是走过场。这种情况要在系统提示里强调“必须基于工具返回结果作答,不得使用其他来源信息”。

4.4 排查速查表

现象可能原因排查动作
不调用工具描述不清或提示未强调补充触发场景描述,系统提示加约束
参数传错参数描述不明确补充格式示例和取值范围
忘记上下文超长度或信息位置不佳压缩历史,关键信息前置或后置重复
忽略工具结果返回格式不友好改为结构化数据,标注关键字段
输出格式错缺少校验加格式校验和重试逻辑
循环调用缺少终止条件设最大轮次,提示模型及时收尾

这张表是我自己排查时用的,基本覆盖了八成以上的常见问题。遇到新问题先对照这张表过一遍,能省不少时间。

4.5 几个反直觉的经验

第一个,工具不是越多越好。我一度以为给模型更多工具它就能做更多事,结果发现工具多了之后选择困难,调用准确率反而下降。后来按场景分组,每次只给相关的那组,效果好很多。

第二个,提示词不是越长越好。早期我喜欢把所有规则都写进系统提示,结果模型被一堆约束搞得畏手畏脚。后来精简到只留最关键的几条,效果反而更稳。规则要精不要多,每条都要有明确的触发场景。

第三个,重试不是万能的。有些错误是模型能力边界导致的,重试多少次都一样。这时候要么换模型,要么把任务拆得更细。判断方法是看错误是否随机,随机错误重试有效,稳定错误重试无效。

第四个,成本和质量要平衡。增强接口意味着更多调用、更多token,成本会上升。不是所有任务都值得上全套增强,简单问答用纯对话就够了。我的做法是按任务复杂度分级,简单的走轻量通道,复杂的走增强通道。

这套东西我断断续续调了小半年,从最开始什么都想加,到后来学会做减法,最大的体会是:接口层的价值不在于堆功能,而在于把模型放在一个它能发挥好的环境里。环境对了,同一个模型能给你完全不一样的答案。环境不对,再强的模型也白搭。

相关新闻

AI毕设选题指南:100个可落地题目与答辩避坑建议

AI毕设选题指南:100个可落地题目与答辩避坑建议

很多同学来问人工智能方向的毕设选题,我干脆把这几年当评审和带项目时见过的选题思路都整理出来,按方向拆了一百个左右可落地的题目,每个都附上为什么能做、难在哪、怎么包装创新点。这篇文章不是让你抄一个标题就完事,而是帮你看…

2026/10/20 7:00:49 阅读更多 →
100套人工智能毕设选题清单:从计算机视觉到强化学习全指南

100套人工智能毕设选题清单:从计算机视觉到强化学习全指南

又到了一年一度被毕设选题反复折磨的时候。人工智能、深度学习、机器学习方向的毕业论文到底选什么题?既要“看起来有东西做”,又得“真能在几个月内做出来”,还要让答辩导师觉得工作量够、逻辑顺、代码靠谱——这三个要求叠在一起&#xff0…

2026/10/20 7:00:49 阅读更多 →
JavaScript MD5实战:从哈希原理到文件校验与接口签名

JavaScript MD5实战:从哈希原理到文件校验与接口签名

看了标题就知道,这文章大概率是在处理一个非常实际的前端痛点:我怎么知道用户上传的文件没被改过、接口请求的参数在传输过程中有没有被动手脚、或者说某些业务字段能不能对得上号。MD5在这个领域是老面孔了,虽然这几年它的名声不太好&#x…

2026/10/20 6:59:49 阅读更多 →

最新新闻

CAT12 VBM全流程实战:从安装配置到多模态形态学建模

CAT12 VBM全流程实战:从安装配置到多模态形态学建模

简介:本资源是面向神经影像学研究者与计算神经科学初学者的CAT12工具箱完整安装与分析套件,专为基于体素的形态计量学(VBM)研究设计,解决sMRI数据预处理、组织分割、统计建模与结果可视化等核心问题。包内共518个文件&…

2026/10/20 7:59:20 阅读更多 →
Flutter 动画还能这么玩:从框架分析到渲染管线,性能翻倍的底层秘密

Flutter 动画还能这么玩:从框架分析到渲染管线,性能翻倍的底层秘密

Flutter 动画还能这么玩:从框架分析到渲染管线,性能翻倍的底层秘密 【免费下载链接】flutter Flutter makes it easy and fast to build beautiful apps for mobile and beyond 项目地址: https://gitcode.com/GitHub_Trending/flutter41/flutter …

2026/10/20 7:59:20 阅读更多 →
SecureCRT中文版深度适配原理与实战指南

SecureCRT中文版深度适配原理与实战指南

简介:SecureCRT中文版是一款面向网络工程师、系统管理员及Linux/Unix运维人员的免安装终端仿真工具,专为安全、高效地管理SSH远程服务器与网络设备而设计。资源包共198个文件,含15个可执行程序(主程序及配套工具)、52个…

2026/10/20 7:59:20 阅读更多 →
Matlab肌肉激活度计算:从sEMG信号到%MVC的完整实现

Matlab肌肉激活度计算:从sEMG信号到%MVC的完整实现

简介:这份资源面向运动生物力学、康复工程与人体运动分析方向的学习者和研究者,提供一套用Matlab求解肌肉激活度的完整实现方案,解决从表面肌电信号到激活度曲线这一环节缺少可运行参考代码的问题。压缩包共5个文件,约135KB&#…

2026/10/20 7:59:20 阅读更多 →
鄱阳湖水系shp数据在ArcGIS中的处理全流程:坐标系、属性表与出图

鄱阳湖水系shp数据在ArcGIS中的处理全流程:坐标系、属性表与出图

简介:长江流域鄱阳湖水系的地形图矢量资料,以通用的shp格式提供湖泊与河流要素,同时包含90米分辨率数字高程模型(DEM)和山体阴影栅格,并配有ArcGIS工程文件(mxd),可直接用…

2026/10/20 7:59:20 阅读更多 →
Python数据分析与可视化源码包实战:从数据清洗到图表输出的完整链路拆解

Python数据分析与可视化源码包实战:从数据清洗到图表输出的完整链路拆解

简介:这份资源面向希望系统掌握Python数据分析与可视化的学习者,覆盖从编程基础到实战项目的完整技能链路,适合高校学生、转行者及需要处理结构化数据的从业者。压缩包共162个文件,约31.27MB,以67个ipynb实验代码、11个…

2026/10/20 7:58:20 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →