最近两三个月我把手头一个智能体项目的架构重写了一遍核心动作就一件事把散落在各种 Prompt 里的能力描述统一收编为一套叫agent-skills的模块化技能体系。说实话动手之前我低估了这个改造的收益——不光代码结构清爽了很多模型在复杂任务上的稳定性和可维护性都明显上了一个台阶连新同学上手排查问题的速度都快了不少。这篇文章就把这次重构的完整思路、技能包设计规范、匹配与执行链路、一段可以直接参考的落地代码以及我踩过的几个坑一次性讲透。适合那种“工具函数越加越多、Prompt 越改越乱、多步任务经常翻车”的 Agent 项目团队参考也适合刚接触 Agent 开发、想给自己的机器人构建一个清晰能力框架的同学。1. 从 Prompt 堆砌到技能模块化这次重构是被“翻车”逼出来的1.1 一个线上 Agent 是怎么被几十个工具函数埋掉的先说背景。我维护的智能体项目早期其实不算复杂核心是一个大号 Prompt里面塞了角色设定、对话策略、业务流程外加一堆 Function Calling 的函数描述。刚上线那阵子体验还行但随着业务方不断提需求函数从最早的五六个增加到了三十多个Prompt 单文件也膨胀到了快 5000 字。这个阶段问题开始集中爆发。最典型的是漏调用工具用户问“把昨天的销售数据给我”模型有时只返回了一段文本压根没调取数工具。更麻烦的是调错工具比如有两个工具一个叫generate_report一个叫export_report光看名字都能猜到它们职责有重叠模型经常把本来该走导出流程的请求发到生成流程里产出一份格式完全不对的临时文件。有一次线上事故直接导致我下决心重构。用户要求“把上周各区域的销售汇总发到群里”Agent 调了数据查询工具但参数里漏掉了“按区域分组”这个字段——因为这个参数的说明散落在 Prompt 中间一大段文字里模型根本没读到。当时排查这类问题特别痛苦先翻 Log 看模型实际传参再回去翻那一大坨 Prompt 找哪里写漏了一个晚上就搭进去了。真正的问题是接口越多靠“一段自然语言描述”去约束模型准确调用的难度越大Prompt 写的越长注意力越容易被稀释。1.2 技能和 Function Calling、Prompt 模板到底有什么区别很多人第一次听到 Agent Skills第一反应是“这不就是包装一下函数描述吗”。我重构前也是这么想的等真正做完才发现它跟传统的 Function Calling 和 Prompt 模板有本质区别。Function Calling 解决的是“如何把函数签名呈现给模型”的问题它停留在接口层。你把函数名、参数类型、一句话描述传给模型模型决定调不调用。但它不负责这个函数背后的实现如何组织、依赖怎么管理、边界条件是什么、谁来测试这个能力。Prompt 模板则更原始本质是字符串拼接。你把不同场景的指令文本拼在一起塞给模型它适合做内容生成类任务但完全不擅长管理工具的复杂度。Agent Skills 是一种自治单元。一个技能包不只包含“模型看到的描述文本”还包含实现该功能的代码、依赖声明、参数结构、触发条件、使用示例甚至测试用例。模型看到的只是这个技能包的“门面”但整个技能的生命周期是可以独立维护、独立版本化、独立部署的。打个比方Function Calling 相当于递给模型一把手术刀而 Agent Skills 是整套手术箱里面除了刀还有使用说明书、消毒记录、适用患者范围、以及一把备用刀。模型只需要知道该开哪个箱剩下的全部由箱子的机制来保证。1.3 什么规模的项目才值得上 Skills别过早设计我也见过反面案例。有朋友看了这套思路特别兴奋手里就三个工具硬是要搞一套技能注册中心结果光搭框架花了两周收益几乎为零。Skill 是有成本的主要体现在设计、检索、执行器三层都需要额外代码所以判断什么时候该上很重要。我根据自己的实际经验整理了一个判断清单信号说明工具数量超过 10 个描述信息开始互相重叠模型漏调率明显上升单个 Prompt 超过 3000 字中间参数说明容易被模型漏读改一处常引发其他行为变化同一能力被多个场景复用比如“数据查询”在客服、报表、分析三个入口都要用需要统一维护团队需要并行开发多人改同一个 Prompt 的冲突概率极高技能包能隔离出独立开发边界能力需要给非开发人员理解技能描述本身也是一份可读的“能力白皮书”如果你的项目还处在三五个工具的小工具链阶段老老实实用函数调用就够了没必要为 Skill 付出额外成本。如果上面列出的信号你命中了两条以上那我认为值得认真考虑一次向技能模块化的迁移。2. Agent Skills 的技能包结构与元信息设计2.1 一份最小技能包的目录结构长什么样技能包本质上是一个自包含的目录。我一开始给每个技能单独开一个 Git 仓库后来发现这种方式太重了——跨技能改公共逻辑时要同时提很多 MR非常费劲。最终采用的方案是一个skills/大仓库统一管理每个技能一个子目录每个子目录内部保持完全自治。以我这个项目早期的“会议纪要”技能为例目录结构是这样组织的skills/ └── meeting_minutes/ ├── SKILL.md ├── requirements.txt ├── scripts/ │ ├── extract_todos.py │ └── render_minutes.py ├── assets/ │ └── templates/ │ └── minutes_template.md ├── examples/ │ ├── input_sample.txt │ └── output_sample.md └── tests/ └── test_skill.py每个目录的职责很明确SKILL.md是技能包的“门面”负责向 Agent 主系统描述这个技能是干什么的、什么条件下触发、有哪些参数、什么情况下不要调用。scripts/放真正的执行代码每个脚本只做一件小事便于测试和复用。assets/放模板、静态资源这类非代码文件比如会议纪要的 Markdown 模板。examples/放一组输入输出示例这部分的意义不仅是给开发者看更关键的是它可以作为模型少样本提示的参考素材也可以作为回归测试的基线。tests/放技能自己的测试用例。我在后面会专门讲为什么这一项容易被忽略却极其重要。这个目录标准不是凭空定的我参考了社区里几种常见的 Agent Skills 格式也结合了自己的使用习惯。核心原则就一条任何人拿到这个目录不需要额外的口头说明只看SKILL.md和examples/就能理解这个技能怎么用、什么时候用、用不了的边界在哪里。2.2 SKILL.md 里哪些字段最值得认真写SKILL.md是技能包的灵魂也是最容易写废的地方。很多人写技能描述跟写产品介绍一样形容词堆了一大堆关键时刻那个字段没写。我在反复调整后用 YAML Front Matter 加上正文的结构来组织下面是一个实际可以跑起来的示例--- name: meeting_minutes_extractor id: skill_meeting_minutes_001 version: 1.2.0 description: 从会议转录文本或已有会议记录中提取议程、决定事项、待办任务 并生成结构化的 Markdown 会议纪要。适用于“整理会议内容”“提取待办事项” “生成会议纪要”等场景。不适用于对历史会议做效果复盘、 统计报表类查询。 parameters: transcript: type: string required: true description: 会议原始文本可以是逐字稿、速记或已有纪要正文 output_format: type: string enum: [md, json] default: md description: 输出格式md 为 Markdown 文档json 为结构化数据 timezone: type: string default: Asia/Shanghai description: 生成待办到期时间所使用的时区 output: content: 生成的会议纪要 Markdown 或 JSON todos_file: 待办清单文件的保存路径 dependencies: python: 3.10 packages: [pandas] ---字段看起来不少但真正决定一个技能能不能被模型正确调用的是description和parameters这两个。description起着“标签”的作用。模型在面对用户请求时不可能把每个技能的完整代码都读一遍它通常只会拿到所有技能的description列表然后基于这些简短的描述做路由决策。所以描述要写得像“搜索引擎里的索引页”而不是“产品说明书”。我在这块的写法总结成一个三层结构第一层这个技能能做什么用动词开头比如“提取”“生成”“转换”“查询”。第二层适用于哪些具体场景给出用户可能说的话作为线索。第三层也是很多人会漏的不适用于哪些场景用否定句明确划出边界。parameters部分则要尽量用enum、type约束模型能传的值。模型不像程序会严格校验类型它本质是概率生成所以不约束就一定会出现传错格式的情况。把output_format限制成md或json模型在推理时会更容易从候选值里选一个而不是自由发挥出什么text、markdown之类的变体。2.3 用“反例声明”给技能划出清晰的边界我在第 1.1 节提到的那个“数据查询”事故根子其实就在描述文件里。当时query_sales这个技能的描述写的是“查询销售数据”听起来好像所有跟销售数字相关的问题它都能接。结果用户问“上周销售为什么下滑”模型也调了这个技能技能只给了原始数据根本没有归因分析能力回答自然是一堆数字堆砌用户体验极差。后来我引入了一个习惯每个技能的description必须写“不适用场景”并配一两条反例。改完之后的效果是立竿见影的下面这段对比可以直观说明# 改之前 description: 查询销售数据支持按天、按周、按月查看支持按地区筛选。 # 改之后 description: 返回销售指标明细数据支持时间维度和地区维度筛选。 适用于“查询销售额”“对比不同区域数据”“导出明细表”。 不适用于需要解释数据波动原因、生成分析结论的任务请使用 analysis_sales_skill需要修改或删除历史数据请走人工审批流程。一开始我还担心写这么多“不适用”会限制技能的发挥空间实测下来恰恰相反。模型在候选技能数量变多之后最缺的恰恰是“排除法”的依据。有了明确的反例声明它不会再把分析类请求错误地路由到查询类技能上误调率下降得很明显。3. 技能加载、匹配与运行时全链路3.1 描述索引层别把技能全文塞进上下文这是我重构中最关键的一个决策技能描述不能全量注入。刚开始我把十来个技能的SKILL.md全文拼到系统 Prompt 里模型上下文很快被吃掉一大块响应变慢Token 成本也肉眼可见地涨。真正的问题不是 Token 贵而是上下文被无关信息污染之后模型的注意力会被稀释反而更容易选错技能。现在的做法是给技能建一个“轻量索引”。注册中心只向主系统暴露每个技能的浓缩信息一般就三项name、description、关键tags。把这些浓缩信息合并成一个技能总表全部加上也就两三千 Token可以安全地放进系统 Prompt。等到模型确认要用某一个技能时才动态加载对应SKILL.md的完整内容。下面这段代码描述了注册中心怎么构建索引from pathlib import Path import yaml class SkillRegistry: def __init__(self): self._skills {} def load_from_dir(self, skills_root: str): for skill_dir in Path(skills_root).iterdir(): skill_file skill_dir / SKILL.md if not skill_file.exists(): continue meta self._load_front_matter(skill_file) self._skills[meta[name]] { dir: skill_dir, meta: meta, } return self def build_index(self) - str: 生成轻量技能总表注入系统提示词 lines [] for name, skill in self._skills.items(): m skill[meta] lines.append( f- {name}: {m[description][:200]} ) return \n.join(lines) def load_detail(self, name: str) - str: skill_file self._skills[name][dir] / SKILL.md return skill_file.read_text()我这里有个经验索引里的description只用前 200 个字符。因为轮询读完整描述的开销很大而真正影响路由决策的核心往往就是前几句话。后续如果模型需要详细参数说明走load_detail单独加载。3.2 路由匹配LLM 决策、向量召回和规则路由如何配合技能匹配是我踩坑最多的部分先后试过三种主流路由方式它们的特性各不相同路由方式实现成本适用场景典型问题规则路由低关键词明确、触发条件可以被枚举用户表达灵活时规则写不完兜底困难向量召回中数量大、语义模糊、需要快速缩小候选集对 token 化质量敏感容易召回语义相似但实际不同的技能LLM 决策高场景复杂、需要综合上下文判断候选太多时会犹豫、选错Token 消耗大我现在跑线上使用的是一种混合策略先用向量召回做粗筛把几十个技能缩小到 Top 5 左右再让模型在候选中做精排。这一步能同时兼顾召回的广度和决策的智能度。流程上的核心代码大致长这样def agent_handle(user_request: str, registry: SkillRegistry, llm): # 第一步向量召回粗筛 candidates embed_retriever.retrieve( user_request, top_k5 ) # 第二步把候选技能的完整描述注入决策上下文 context build_base_context(user_request) for name in candidates: detail registry.load_detail(name) context.compose(skill_detail(name, detail)) # 第三步让 LLM 在候选集里做最终决策不再暴露全部技能 plan llm.decide(context, availablecandidates) for action in plan: if action.type skill_call: skill registry.get(action.skill_id) result skill.run(action.params)这里有一个细节值得展开向量召回阶段我用的是name description tags拼接后的文本做 embedding而不用完整SKILL.md。原因也很简单完整文档里的实现细节、依赖信息对语义检索没有帮助反而会引入噪声。把“门面信息”和“内部信息”分开检索效果会稳定不少。3.3 统一执行器技能代码不能“裸奔”进系统技能包本质上是可执行代码如果不做任何约束直接跑会带来超时失控、权限过大、异常难追踪等一系列问题。我给所有技能设计了一个统一的SkillExecutor任何技能都必须通过这个执行器运行不允许直接subprocess.run。执行器管四件事参数校验、超时控制、命令白名单、结果格式化。import subprocess import json class SkillExecutor: def __init__(self, allowlistNone, timeout30): self.allowlist allowlist or [] self.timeout timeout def run(self, skill, params: dict): # 1. 参数 Schema 校验 self._validate_params(skill, params) # 2. 构造执行命令 script_path skill.exec_script(params) command [script_path] self._serialize_params(params) # 3. 白名单判断 if script_path not in self.allowlist: raise PermissionError(f技能执行路径未在白名单: {script_path}) try: proc subprocess.run( command, capture_outputTrue, textTrue, timeoutself.timeout, ) except subprocess.TimeoutExpired: return {status: error, error: f技能执行超过 {self.timeout}s} # 4. 结果规范化 stdout proc.stdout.strip() try: data json.loads(stdout) except json.JSONDecodeError: data {raw: stdout} return { status: success if proc.returncode 0 else error, data: data, }实际运行中超时这一项帮我避掉过很多次事故。有的技能在输入数据量很大时会进入长时间计算如果没有超时控制整个 Agent 工作流会被卡死。我这边统一设了 30 秒个别重计算类的技能单独放宽到 120 秒但都必须显式配置不能默默容忍无界执行。4. 实战构建一个可接入主流程的会议纪要技能包4.1 为什么选“会议纪要与待办提取”作为示例场景单独讲概念容易飘我拿一个完整实现的技能包拆给大家看。我选这个场景是因为它在一个技能包里同时覆盖了四类能力文档类文本输入、LLM 结构化抽取、格式化输出、文件生成。这四类能力几乎覆盖了日常 Agent 技能开发的全部链路你理解透这一个技能其他技能基本就是替换输入输出格式的事。需求拆解下来是这样输入一段会议的转录文本或者是已有的会议记录正文处理提取出三块内容——议程、决定事项、待办任务每个待办任务需要有执行人、截止时间、备注输出一份 Markdown 格式的会议纪要文件同时生成一个 JSON 格式的待办清单供后续自动化流程使用边界如果用户输入的内容不是会议材料技能应该直接报错而不是强行生成一份假纪要4.2 SKILL.md 与核心脚本的落地实现SKILL.md就按第 2.2 节的元数据标准来写。核心脚本scripts/extract_todos.py做的事情是调用 LLM 从原始文本中抽取结构化信息并转换成 JSON。为了防止模型在宽松提示下输出五花八门的字段这个脚本会把输出格式硬编码成固定结构不允许模型自由发挥。# scripts/extract_todos.py import json import sys RAW_TEXT sys.argv[1] SYSTEM_PROMPT 你是会议纪要分析器。只允许输出 JSON不要输出任何其他文字。 JSON 结构必须严格符合: { agenda: [议题1, 议题2], decisions: [决定1], todos: [ {owner: 执行人, task: 任务描述, due: YYYY-MM-DD, note: } ] } 如果原文中没有足够信息推断某个字段用空数组或空字符串不要编造。 .strip() def call_llm(text: str) - dict: # 这里是实际对模型 API 的调用封装 resp llm_complete(SYSTEM_PROMPT, text) return resp if __name__ __main__: result call_llm(RAW_TEXT) print(json.dumps(result, ensure_asciiFalse))这个脚本本身不负责“生成汇报文案”它只负责把非结构化文本转成结构化 JSON。下游的render_minutes.py再负责把 JSON 套进 Markdown 模板职责分离以后想换输出模板只需要动最后一个脚本。4.3 接入主 Agent 的完整流程代码技能包写完之后把它接入主 Agent 的流程比我想象中简单。关键在于注册中心和执行器要提前搭好接入新技能只是新建目录、写SKILL.md、把脚本丢进去三步from skill_registry import SkillRegistry from skill_executor import SkillExecutor registry SkillRegistry().load_from_dir(./skills) executor SkillExecutor( allowlist[./skills/meeting_minutes/scripts/extract_todos.py], timeout60, ) # 构建轻量索引并注入模型 skill_index registry.build_index() def on_user_request(user_input: str): # 向量召回粗筛这里省略了 embedding 部分 candidates [meeting_minutes_extractor] # 加载候选技能详情 context f 你可以使用的技能列表如下请根据用户需求选择并调用 {skill_index} 用户请求{user_input} # 模型决策实际项目会走结构化输出 chosen_skill meeting_minutes_extractor params {transcript: user_input} skill registry.get(chosen_skill) result executor.run(skill, params) if result[status] success: render_minutes(result[data])你可能会问这一步里“模型决策”看起来很潦草实际项目应该怎么让它自动填参数我这边用的是让模型输出结构化 JSON 的方式来解这个问题的即{skill: xxx, params: {...}}。这一步做完后整个技能调用链路就闭环了。5. 技能系统真正跑起来之后我踩过的几个大坑5.1 排查实例技能描述“太用力”模型反而找不到正确的技能这个坑我印象很深。某次上线了一个新的“周报生成”技能结果连续几天发现它抢了另一个“数据回顾”技能的活。用户说“帮我写这周的工作总结”模型直接调了周报生成这本身没错但用户说“这周我的数据涨了多少”它也去调周报生成产出就是一段模板话术数据一个都没有。完整的排查链路是这样走的第一步先看模型决策日志发现所有包含“周”字的请求都被路由到了weekly_report_skill。第二步拉出这个技能的description发现我写的描述是“适用于周报、总结、每周进展、周数据回顾等各种场景”。第三步问题定位清楚了描述里的“周数据回顾”这种用例其实对应的是数据查询能力不是周报生成能力。我把两个维度的语义混进了同一个技能描述里向量召回自然会把所有和周相关的请求都拉过来。第四步修改description把“周数据回顾”显式剔除加反例“不适用于具体数据指标查询”同时把数据回顾类请求重新映射到data_query_skill。第五步补了一条测试用例防回归输入“这周各渠道的转化率是多少”期望选择data_query_skill。这次排查给我最大的启发是技能描述不是越全越好它要有非常清晰的“召回边界”。一个技能想覆盖的场景越广它在向量空间里的位置就越模糊和别的技能的区分度就越低。所以我现在每写一个技能描述都会问自己一个问题“用户说哪类话绝对不能选中它”答案要写进描述里。5.2 Token 失控从 8k 回到 3k 的上下文瘦身技能数量过了 20 个之后另一个问题浮上水面上下文 Token 每天在涨。我把所有SKILL.md全文都拼进系统 Prompt 时整个上下文直接到 8k其中 5k 都是技能说明。这不仅费钱还让模型响应明显变慢。我把方案改成第 3.1 节说的轻量索引看了一下实际效果阶段系统提示词 Token 数平均响应时间全量注入 20 个技能详情约 8000约 4.2 秒轻量索引 按需加载视频约 3200约 2.1 秒瘦身过程中有一个容易忽略的点当候选技能变少之后技能详情加载可能要补进“当前轮请求”的上下文里而不是塞进系统级上下文中。这样做的好处是用户发起一个新请求时上一次请求加载的技能详情不会残留避免了上下文污染。5.3 状态不同步技能间通过文件交换数据为什么不可靠技能拆细之后第一个真实业务流程是“先抽摘要再生成待办最后发送通知”。最开始我的设计是前一个技能把中间结果写到一个临时文件后一个技能去读这个文件。本地单机跑得好好的一旦并发量上来就出问题日志里各种“文件不存在”报错甚至出现一个用户读到了另一个用户中间文件的情况。排查后定位到根因技能执行器是独立进程工作目录不共享并发执行时临时文件命名还会冲突。后来我彻底弃用了“文件交换数据”的模式改成在技能调用链里显式传递结构化数据——前一个技能的输出 JSON 直接作为后一个技能的输入参数。只有最终需要落地磁盘的结果才通过assets/目录写出并且文件名带执行 ID。这个经验也是我后来在技能参数设计时特别重视output定义的原因每个技能都要明确自己的输出结构技能之间通过结构化的数据契约对接而不是依赖文件系统这种隐式状态。5.4 安全边界允许技能执行命令但绝不能什么都允许最后聊一个非常容易被忽略的问题安全。在我的架构里技能是可以执行任意脚本、读取文件、调用系统命令的这让整个 Agent 的能力上限变得很高但也意味着任何一个技能开发者失误都可能成为系统的一个漏洞入口。“白名单机制”是我最终采用的最小方案技能脚本路径必须显式注册不在名单里的路径一律拒绝执行。所有技能内部对外的请求比如 HTTP 调用、数据库查询必须走统一封装的网关卡不允许直接用requests裸连。技能不能无限制写文件只能写到自己的工作目录。超时是硬指标任何技能都不能启动无界运行。我在实际使用中甚至遇到过一种情况某个技能为了测试方便在脚本里写死了rm -rf清理逻辑差点在正式环境删掉一个公共目录。虽然那次被拦截了但也说明了一个道理——技能包的好用和风险是并存的权限设计必须在一开始就考虑进去。好用的技能系统应该像好的乐高积木每块积木自己是什么形状能搭出什么结构写得清清楚楚但它不能是一个到处乱跑的积木块必须有拼插规则和安全锁扣。我个人的体会是Agent 项目的复杂度增长是必然的逃避不了agent-skills这套体系并不是银弹它只是把复杂度从“模型面前的一大坨 Prompt”转移到了“工程侧的多模块协作”上。想让它真的发挥作用关键还是耐心维护技能描述的质量和边界做好回归用例。最后再分享一个我受益很大的小习惯每个技能在tests/里配两条回归用例一条正向用例一条反向用例。正向用例验证“该触发时必须触发”反向用例验证“不该触发时必须不触发”。技能少的时候看不出价值等技能多到几十个几次大改之后你就会发现这两条用例能帮你省下大量的回归排查时间。
企业数字化 ERP 产品动态
相关推荐
货拉拉AI Coding落地实践:从个人提效到组织提效的四个关键 刚在货拉拉把 AI Coding 从“一群人自己玩”推到“全研发流程用起来”,我印象最深的一句话,是一个后端同学说的:“我自己写代码快了至少一倍,但需求该什么时候上还是什么时候上。”这句话几乎把问题说完了——工具给你省了敲键盘的… · 2026/9/26 8:41:14
Higgsfield深度测评:AI视频如何告别“飘”?物理感生成全解析 如果把最近AI视频圈的讨论做一个词频统计,higgsfield大概率是绕不开的那个。我第一次注意到它,是刷到一条不起眼的小视频:一颗篮球从高处落下,砸在水泥地上,先是挤压变形,然后带起一圈尘土弹起,… · 2026/9/26 8:41:14
LeetCode 1401:圆与矩形重叠判断的最近点法详解 1. 先聊聊这道题到底在考什么LeetCode 1401这道题,题目描述很直白:给你一个圆的圆心坐标和半径,再给你一个矩形的左下角和右上角坐标,判断圆和矩形是否有重叠。但题目越短,陷阱越多。我第一次交的时候,自信… · 2026/9/26 8:41:14
一个指针解引用后,CPU 到底做了什么?从虚拟地址到页表、TLB 与物理内存 1. 两个进程明明用了同一个地址,为什么不会互相干扰?
假设有两个正在运行的进程。它们都访问地址 0x400000,却读出了各自的数据:
进程 A:访问 0x400000 → 读到 A 的数据
进程 B:访问 0x400000 → 读到 B 的… · 2026/9/26 9:09:58
功能安全咨询公司如何用AI Agent实现知识产品化落地 1. 功能安全咨询行业为什么开始卖AI Agent 功能安全咨询这个行当,过去十几年一直是典型的“人力密集、知识密集、交付周期长”的生意。一家做ISO 26262、IEC 61508合规咨询的公司,核心资产就是那几位懂HARA、懂FMEA、懂安全案例(Safety Case&… · 2026/9/26 9:09:52
Claude Skills全攻略:用SKILL.md给AI代理装上“超能力”,让大模型为你打工 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 9:09:46
Agent时代CLI设计指南:从工具到智能体执行入口 1. 从"CLI-Anything"说起:命令行工具正在经历一场静默革命第一次看到"CLI-Anything"这个说法,我脑子里蹦出来的不是某个具体工具,而是一种趋势判断——命令行界面正在从"运维专属"变成"人人都能用的自动化… · 2026/9/26 9:09:39
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍 简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践 一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46