news 2026/9/26 8:38:51

agent-skills:从提示词工程到可复用技能包,让AI Agent稳定落地

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
agent-skills:从提示词工程到可复用技能包,让AI Agent稳定落地

如果你最近在折腾 AI Agent,大概没少撞上同一堵墙:模型本身已经很能说了,但真让它按你团队的流程把活儿干完,它要么漏步骤,要么把规则忘得一干二净;你往系统提示词里多写几句约束,它又开始自由发挥,给出一个“听起来很合理、实际没法用”的结果。agent-skills 这个方向,就是专门来解决这个问题的——它把 Agent 干活所需的能力做成一个个独立、可复用、可测试的“技能包”,让模型在合适的场景里调用合适的技能,而不是靠临场发挥。这篇文章想把我在 agent-skills 项目上的设计思路、实操过程和踩坑记录完整写下来,适合正在做 Agent 应用,或者想让团队 AI 工具真正落地的开发者参考。

1. 内容整体设计与思路拆解

1.1 从“对话模型”到“技能执行”:agent-skills 要解决的核心问题

很多人第一次做 Agent 时,会把所有业务流程直接写进 system prompt,比如“你是一个客服助手,第一步查询订单状态,第二步判断是否可退换,第三步生成处理结果”。这套方案在演示环境里跑得通,一旦进入真实业务,问题马上冒出来:模型对重复规则会产生注意力衰减,长提示词里靠后的规则经常被忽略;更尴尬的是,不同任务的边界模糊,模型容易把 A 任务的规则套到 B 任务上。我的判断是,问题的根源不在于提示词写得不够好,而在于我们让模型承担了太多“记忆”和“执行顺序”的责任。

agent-skills 的核心思路,是把“工作流程外置”。一个技能包不再是一段文字,而是一个带目录、脚本、测试的独立模块。模型要做的事情只有一件:判断当前用户请求应该匹配哪个技能,然后调用这个技能。至于这个技能内部有几步、每一步怎么做、需要什么参数,都不需要模型临时推理,而是由技能包自身定义好。换句话说,agent-skills 不是给模型更多指令,而是给模型一块可以随时取用的“操作面板”,它知道什么时候按哪个按钮就够了。

我在实际设计中最先确定的一个原则是:技能必须可以被单独测试。过去调试一个 Agent 业务流,出问题后你分不清是模型理解错了,还是数据源出错了,还是提示词写得不清楚。但技能一旦被拆出来,我就可以直接运行它的脚本,看输入输出是否正常。这样模型负责的部分和工程负责的部分被清晰切开,定位问题的成本一下子降了下来。这也是为什么 agent-skills 在项目结构上不像一个“插件”,更像一个“测试友好的工具包集合”。

1.2 技能的分层设计:从原子操作到完整工作流

在面对一堆业务需求时,我习惯先把技能分成三个层次。底层是原子技能,例如“读取文件”“调用某个 API”“执行 SQL 查询”;中间层是领域技能,封装了特定业务规则,例如“检查订单是否符合退款条件”“判断一段文本是否包含敏感词”;上层是工作流技能,它把多个技能按顺序组合在一起,完成一个端到端的目标,例如“生成本周项目周报”“批量处理客户投诉”。

一开始我差点把“周报生成”做成一个大而全的技能,里面既包含 Git 操作、又包含数据聚合、还包含模板渲染。后来发现这种做法是给自己挖坑:一旦模板要改,整个技能都得重新验证;如果另一个场景也需要“Git 操作”但不需要“模板渲染”,又得复制一份代码。所以我现在倾向于让每个技能只做一件事,复合需求通过上层技能去编排。分层之后还有一个额外好处:每一层都可以独立写测试,底层出问题不会连累上层逻辑。

分层设计也影响技能的触发策略。原子技能往往适合做成常驻工具,让模型随时调用;工作流技能则需要更严格的触发词,不能用户说一句“查一下数据”就直接把整套周报流程跑起来。我在 SKILL.md 的元信息里专门留了一个when_to_use字段,就是用来写清楚“什么情况下才应该使用这个技能”,这个字段比 description 更关键,它能帮模型排除掉大量错误选择。

1.3 为什么我把 agent-skills 做成一堆 Markdown 和脚本

你可能好奇,为什么不直接用一个复杂的编排框架,为什么非要用 Markdown 加脚本这种“简陋”的组合。我的理由很直接:技能包最大的价值是易写、易读、易维护。Markdown 是人和大模型都能理解的语言,大模型可以直接读取并优化 SKILL.md;脚本则负责做那些模型不擅长的确定性计算,比如日期运算、数据过滤、文件合并。这两者组合,恰好覆盖了“语义理解”和“精确执行”两个互补的能力域。

相比一个几千行的 JSON 配置文件,Markdown 加脚本的目录结构还有一个隐藏优势:方便代码评审。团队里其他成员不用理解整个 Agent 框架,只需要打开一个技能目录,就能看清楚这个技能干什么、依赖什么、怎么测试。而且每个技能包都是自包含的,放到任意 Agent 工程里都能通过统一加载器注册。这种“模块化 + 可复制”的思路,让技能库可以像 Git 仓库一样做版本管理,出了问题回滚一个目录即可,不会影响其他正在运行的技能。

我当时也对比过用数据库存技能定义,但最终放弃,因为数据库不利于追踪历史变更,更不利于离线开发和测试。用文件系统做存储,天然支持 diff、branch、review,这套工作流开发团队早就习惯了,没必要为了“统一配置”去重新发明一套方案。

2. agent-skills 核心细节解析与实操要点

2.1 技能包标准结构拆解

一个标准技能包,我通常按下面的目录结构组织:

skills/ └── weekly-report/ ├── SKILL.md ├── scripts/ │ ├── collect_commits.py │ └── render_report.py ├── templates/ │ └── report_template.md.j2 ├── tests/ │ ├── test_collect_commits.py │ └── fixtures/ │ └── sample_commits.json └── requirements.txt

SKILL.md是整个技能包唯一必须存在的文件,它是 Agent 理解技能的入口。里面会写清楚这个技能叫什么、什么时候用、输入输出是什么、执行步骤是什么。scripts/目录放的是可执行代码,我不建议把代码直接内嵌在 SKILL.md 里,因为脚本往往要调试,独立成文件更方便。templates/目录放输出模板,比如周报的 Markdown 模板。tests/目录放自动化测试和模拟数据,这一层被很多人忽略,但它恰恰是最能保证技能长期可用的部分。requirements.txt记录脚本依赖,避免出现“在我机器上能跑,到你机器上就跑不了”的问题。

每个技能包必须自包含,不能偷偷依赖另一个技能包内部的脚本。我见过有项目直接在技能 A 里去调用技能 B 的scripts/common.py,刚开始没问题,后来技能 B 被重构,技能 A 立刻挂掉,而且报错信息非常难懂。所以我在团队里立了一条规矩:跨技能复用能力,必须把公共部分提取成独立包,或者通过外部接口调用,而不是互相引用文件。

2.2 SKILL.md 怎么写才真正被 Agent 读得懂

SKILL.md 不是给程序员看的接口文档,而是给模型看的使用手册。所以我写它的时候会刻意做到“把模型当成一个聪明的实习生”来交代,而不是当成一个“SQL 解析器”。下面是我常用的一个结构示例:

--- name: weekly-report-generator description: 当用户需要汇总指定时间段内的代码提交、PR 和关键进展,并生成 Markdown 周报时使用。 when_to_use: 用户提到“周报”“weekly report”“汇总本周工作”“这个迭代的进展”等表达时优先匹配。 input: start_date: 开始日期,格式 YYYY-MM-DD,可省略,默认 7 天前 end_date: 结束日期,格式 YYYY-MM-DD,可省略,默认今天 project: 项目编号或仓库名,可省略 output: Markdown 格式的周报文件,保存到 outputs/weekly_report.md dependencies: - python >= 3.10 - git - requests --- # 周报生成技能 1. 解析输入参数。若 start_date 为空,取当前日期减 7 天;若 end_date 为空,取当前日期。 2. 调用 scripts/collect_commits.py,传入 start_date、end_date、project,获取提交记录 JSON。 3. 调用 scripts/render_report.py,传入提交记录 JSON 和模板文件,生成最终 Markdown。 4. 将 Markdown 写入 outputs/weekly_report.md,并向用户返回文件路径。

frontmatter 里的name是技能的唯一标识,description是给模型做初筛用的,when_to_use要写得具体,最好带上用户常见说法里的关键词。真正执行时,模型会先读description和when_to_use,判断要不要选择这个技能;选中之后,再读正文里的步骤。所以正文里的步骤描述不需要过于口语化,但要把“按顺序做哪几件事”讲清楚。

我踩过的一个坑是:description 写得太抽象,比如“生成周报”这四个字。结果用户说“总结一下这周的工作”,模型完全没有把这个请求和“生成周报”对应上。后来我把描述改成“汇总指定时间段内的代码提交、PR 和关键进展,并生成 Markdown 周报”,并在 when_to_use 里增加了常见变体表达,匹配率立刻提升。你可以在描述里放 3 个左右的触发词变体,但不要堆砌,否则模型会被无关词干扰。

2.3 脚本与工具的接入方式

技能包里的脚本承担的是模型“不擅长”但“必须精确”的工作。比如日期计算、文本格式化、网络请求处理。脚本在设计时必须遵循一个原则:无交互、参数化、结果可预期。Agent 调用脚本时不可能像人一样在终端里回答“是否继续”,所以脚本的输入应该全部来自命令行参数或标准输入,输出应该写到标准输出或指定文件。

我通常用 Python 写脚本,因为它的标准库足够覆盖大部分场景,团队也好维护。一个最小可用的脚本入口大概是这样的:

python scripts/collect_commits.py --start 2025-01-01 --end 2025-01-07 --output tmp/commits.json

脚本解析参数后,把数据源里的记录读出来,经过过滤和聚合,最后以 JSON 写入tmp/commits.json。Agent 不需要关心脚本内部是怎么实现的,它只需要知道这个命令能返回 JSON 文件。这样做的好处是,当模型需要“调用技能”时,我可以在运行时里直接把这个命令封装成一个工具函数,甚至不需要让模型真的去理解代码逻辑。

Python 版本和第三方库的版本是需要提前锁定的。我在requirements.txt里会写上明确的版本范围,例如jinja2>=3.0,<4.0,避免某次重装环境后技能突然跑不起来。如果你所在团队的 Agent 运行在 Docker 容器里,我建议把每个技能包依赖构建到一个基础镜像里,而不是等运行时再临时安装。

2.4 技能测试用例:让 Agent 学会“自检”

测试用例是我后期才补上的,补完之后我才意识到它有多重要。测试有两个作用:一是给开发者做回归验证,改完代码后跑一遍就知道有没有破坏原有行为;二是给 Agent 一个“自检”的判据,当调用技能后返回异常,模型可以主动运行测试来判断是环境问题还是数据问题,从而触发重试或兜底逻辑。

我习惯在每个技能包里放一个tests目录,里面至少覆盖两条路径:正常路径和边界路径。以周报技能为例,正常路径是给一个包含提交记录的时间段,验证输出 Markdown 里出现了对应条目;边界路径是给一个没有任何提交的时间段,验证输出里能正确显示“暂无提交”,而不是直接抛异常。

运行测试的命令要固定下来,我一般写成:

cd skills/weekly-report && python -m pytest tests/ -q

如果 Agent 运行时检测到技能脚本返回失败,它可以先跑一次测试,如果测试失败,就直接告诉用户“技能环境当前不可用,请检查依赖”,而不是把一堆半生不熟的结果硬返回。这种设计能把 Agent 从“盲目重试”中解放出来,也大大减少了我半夜被线上告警吵醒的次数。

3. 实操过程与核心环节实现

3.1 从场景出发:手写一个“周报生成”技能

我会用一个非常常见的场景来说明完整落地过程:生成项目周报。需求是用户说“生成上周周报”,Agent 需要从 Git 仓库里获取代码提交记录,从项目管理接口获取 PR 和任务状态,然后按团队模板生成一份 Markdown 周报。这个技能非常适合作为第一个练手项目,因为它涉及外呼数据、参数解析、模板渲染和文件输出,几乎覆盖了 agent-skills 的全部关键点。

在设计阶段,我先定义输入和输出边界:

输入类型说明
start_datestring开始日期,格式 YYYY-MM-DD,可省略,默认 7 天前
end_datestring结束日期,格式 YYYY-MM-DD,可省略,默认今天
projectstring项目编号或仓库名,可省略
输出说明
一个 Markdown 文件按模板渲染,包含提交统计、PR 列表、工作小结

我把边界想得很清楚:这个技能只负责汇总和渲染,不负责分析代码质量,也不负责给改周报的人提供修改建议。边界越清晰,模型越不会在调用技能之后画蛇添足。

3.2 技能包落地全过程

第一步是创建目录,按照前面说的结构搭好空壳。第二步是写 SKILL.md,把元信息、输入输出和步骤写好。第三步是实现脚本,我用 Python 写了一个collect_commits.py,核心思路是通过git log获取提交信息,然后按日期过滤并输出 JSON。

import argparse import json import subprocess from datetime import datetime, timedelta def collect_commits(start, end): cmd = [ "git", "log", f"--since={start}", f"--until={end}", "--pretty=format:%H|%an|%ad|%s", "--date=short" ] result = subprocess.run(cmd, capture_output=True, text=True, check=True) commits = [] for line in result.stdout.strip().splitlines(): sha, author, date, subject = line.split("|", 3) commits.append({"sha": sha, "author": author, "date": date, "subject": subject}) return commits if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--start", required=True) parser.add_argument("--end", required=True) parser.add_argument("--output", required=True) args = parser.parse_args() data = collect_commits(args.start, args.end) with open(args.output, "w", encoding="utf-8") as f: json.dump(data, f, ensure_ascii=False, indent=2)

这里故意用subprocess.run配合参数列表,而不是把命令拼成一个字符串,主要是为了防止特殊字符把整条命令拆开从而产生安全问题。下一步是写render_report.py,它会读入提交记录 JSON,基于templates/report_template.md.j2渲染出最终 Markdown。模板里我会预留“本周完成”“风险与阻塞”“下周计划”几个区块,即使数据缺少,也会保留标题结构。

最后一个环节是写测试。我在tests/fixtures/下放了一个sample_commits.json,在测试里用真实模板渲染一次,然后断言输出文件里包含预期的小节标题。从这个案例可以看到,整个技能包的开发其实和普通软件开发没有本质区别,只不过消费方从人变成了 Agent。

3.3 在 agent 运行时里注册与调用

技能包本身不会自动生效,它需要一个加载器把它注册到 Agent 的工具列表里。我写了一个很轻量的加载函数:

def load_skills(skills_dir): skills = [] for dir_path in Path(skills_dir).glob("*/SKILL.md"): meta = parse_frontmatter(dir_path / "SKILL.md") meta["path"] = dir_path.parent skills.append(meta) return skills

加载器会把每个技能的name、description、parameters转成 model API 需要的 function definition。这样,模型在收到用户消息后,先根据触发词决定要不要调用“周报生成技能”,一旦决定调用,运行时就把前端传来的参数解析为脚本需要的命令行参数并执行。我会把 SKILL.md 的完整正文放在一个单独的工具参数里,让模型在调用前“阅读手册”,但这种方案会消耗更多 token,所以更推荐只在必要时注入。

实际项目里,我更倾向用“两级索引”来组织技能:第一级是只有名称和一句话描述,常驻在系统提示词里,保证模型能快速判断该用哪个技能;第二级是技能全文,只有模型选中某技能后才作为工具说明注入。这样技能库扩展到几十个之后,上下文也不会爆掉。

3.4 为什么我建议先手动跑一次完整链路

接入 Agent 之前,我一定会先在终端里把技能包完整跑一遍。先单独执行collect_commits.py,确认能拿到预期 JSON;再执行render_report.py,确认能生成 Markdown;最后跑一遍pytest,确认测试通过。这个过程看起来很原始,却能提前挡住 80% 的问题。脚本能不能跑、路径对不对、依赖缺没缺,这些在 Agent 介入前就能被暴露出来。

跑通之后,我还会把一次完整的输出保存起来,当作这个技能的 golden sample。以后每次改动技能,我把新旧输出做一次 diff,就能快速看出影响范围。这个习惯帮我避免过好几次“模型说技能执行成功,但输出格式已经完全不对”的诡异问题。你可以把 golden sample 放到tests/fixtures/expected_report.md里,在测试里强行比对,这比纯靠人的眼睛可靠得多。

4. 常见问题与排查技巧实录

4.1 技能文件存在,但 Agent 就是不调它

这是我在多个项目里遇到频率最高的问题。技能包老老实实躺在skills目录里,测试也过了,但用户输入“生成上周周报”时,模型就像看不见这个技能一样,直接凭空生成一段周报。第一次遇到这种问题时,我花了一个下午去翻模型日志,最后发现是 description 里的触发词和用户表达对不上。用户说“这周干了啥”,我的描述里只写了“周报”“weekly report”,模型自然匹配不到。

排查这个问题时,我按三步走:先打印技能注册列表,确认技能确实被加载;再用一条包含明确触发词的 prompt 直接测试,看模型会不会选择该技能;如果还是不行,就打开模型调用的日志,看它在几十个工具描述里到底有没有考虑过这个技能。大多数时候问题出在描述太窄,我会把用户可能的口语化表达补进when_to_use,比如“这周干了啥”“总结一下进度”“周报搞一下”。这比修改模型参数性价比高得多。

4.2 上下文爆炸:技能文档太长导致模型“迷失”

技能库一旦超过十个,最直接的问题不是模型不会选,而是系统提示词太长。如果把每个 SKILL.md 的完整正文都塞进系统提示词,一次请求可能多消耗几千甚至上万 token,模型对后面的内容也会逐渐不敏感。我经历过一次线上事故:某个任务的技能文档特别长,导致模型在处理这个任务时把前面的安全规则忘掉了,输出了不符合预期的内容。

解决办法就是前面提到的“两级索引”:系统提示词里只放每个技能的name、description和when_to_use摘要,技能全文按需加载。我还给自己定了一个量化标准:单技能的 description 尽量控制在 200 字以内,SKILL.md 正文字数控制在 1500 字左右。脚本和模板不算上下文,它们只是被调用的资源。如果你的团队里有很多结构相似的技能,还可以用向量检索做粗排,但我会保留一个关键词规则的硬过滤,避免纯语义检索把明显无关的技能捞出来。

4.3 技能之间互相打架:命名、依赖与冲突

技能数量上去后,第二个高频问题是命名和依赖冲突。我见过两个技能都定义了get_data.py这样的通用文件,导致加载时互相覆盖;也见过技能 A 依赖requests的版本是 2.25,技能 B 却要求 2.31,统一环境升级后,技能 A 直接不可用。

规避方法有三个。第一,技能名和脚本名加前缀,比如weekly_report_collect.py,而不是collect.py,降低冲突概率。第二,依赖隔离,每个技能包要么使用独立虚拟环境,要么在容器里分别构建;退一步说,至少要在requirements.txt里固定版本并定期全量回归测试。第三,建立跨技能调用规范,不允许直接读其他技能目录下的文件,必要的能力提升为公共库。这样做短期内会多一些重构工作,长期能保住系统的可维护性。

4.4 权限与安全:技能不是任何脚本都能执行

技能包的最大安全风险是脚本获得了过高权限。Agent 一旦被诱导执行某个技能,脚本可能在服务器上删除文件、修改数据库、访问内网服务。我在生产环境里采用了几条硬性规则:技能脚本使用专门的低权限系统用户运行;重要的破坏性操作需要在 SKILL.md 里写明二次确认机制;脚本禁止直接把用户输入拼进 shell 命令,统一用subprocess参数列表。

我自己还有一个习惯:所有技能脚本的网络请求都必须走白名单代理或网关,从源头上避免访问意料之外的外部地址。比如周报技能里的requests.get只会访问公司内部的项目管理 API,域名在配置里写死,任何从用户输入中提取的动态域名都会被直接拒绝。下面是常见风险场景与缓解方案的对应表:

风险场景缓解方案
用户输入拼进 shell 命令用参数列表方式调用子进程,禁止字符串拼接
脚本删除业务文件运行账号最小权限,删除前强制二次确认
技能依赖被恶意篡改锁定依赖版本,容器镜像做不可变构建
外部 API 返回恶意内容对响应做 schema 校验,防止脏数据反噬

这些措施不会让技能系统变成铜墙铁壁,但能挡住绝大多数偶然事故和低水平攻击。做 agent-skills 时,我一直把它当作“给 Agent 造了一只手”,手能干活,也就能闯祸,控制权限和控制输入输出格式同样重要。

5. agent-skills 生态与进阶方向

5.1 与 MCP 的定位差异

很多刚开始接触 agent-skills 的人会把它和 MCP 搞混,实际上两者解决的层级不一样。MCP 是一个标准化的工具调用协议,它解决的是“模型如何与外部工具交互”的问题,类似给工具装上了统一的 USB-C 接口。agent-skills 则更关心“一个复杂任务应该如何被拆解为可沉淀、可教学的操作步骤”,它强调的是技能内容本身,而不是传输层协议。

在我的项目里,这两者是互补关系。我可以用 agent-skills 定义“周报生成”这个技能包,再把其中的脚本调用暴露成一个或多个 MCP 工具,让 Agent 通过标准协议调用。技能包的核心资产是 SKILL.md 和脚本逻辑,底层走不走 MCP,只是接入方式的差异。理解了这层关系,你在设计系统时就不会陷入“二选一”的纠结。

5.2 社区如何共享技能包

技能包天然适合用 Git 仓库共享。我见过一些团队把技能库做成一个 monorepo,每个技能一个目录,通过分支和 PR 协作;也见过有人把经过验证的技能包发布到内部制品库,其他人通过包管理工具拉取。社区里已经能看到不少 curated skills 仓库,它们通常会给每个技能标注适用场景、依赖要求、测试覆盖情况,这和开源软件的分发逻辑几乎一样。

评估一个外部技能包能不能用,我会先看三样东西:有没有清晰的触发条件描述;有没有测试用例;依赖清单是否完整。如果只有一段 SKILL.md 正文,没有脚本和测试,我通常会把它当作参考模板而不是可复用技能。技能包和代码库一样,没有测试的模块进入生产环境,就是在给未来埋雷。

5.3 从“个人技能库”到“团队技能市场”

我最初做 agent-skills 只是为了自己开发 Agent 时少加班,后来发现它真正能放大价值的地方在团队协作。运营团队沉淀一个“竞品信息收集”技能,数据团队沉淀一个“SQL 审核”技能,研发团队沉淀一个“变更发布预检”技能,所有技能放到同一个内部仓库里,大家按统一规范提交和评审。这时候技能库就变成了团队的自动化能力中心,而不是某个开发者电脑上的私人脚本。

团队技能市场要跑起来,关键不在技术,而在流程。至少要有技能写作规范、评审人机制、版本发布节奏。我和团队定的流程很简单:先写 SKILL.md,再开会评审触发词和边界,然后补脚本和测试,通过 CI 后再发布。这个流程看起来比“直接把脚本丢给模型”重,但一旦技能数量超过十个,没有流程管控就会变成一团乱麻。技能市场听起来很远,实际上从一个团队里最常用的三五个技能开始攒,三个月就能看出效果。

我在实际项目里把 agent-skills 跑起来之后,最明显的变化不是模型变强了,而是我的调试思路变得清晰了:每个任务都有边界、输入输出和测试,出问题不再是玄学,而是可以定位、可以回滚、可以让别人接手。如果你也想把手边的 Agent 从“偶尔好用”推向“稳定能用”,我的建议是从你最常做的那个重复劳动开始,把它拆成一个技能包,先跑通、再优化。技能的价值不只是让模型更听话,更是让整个团队对 AI 的能力边界有了共同的语言。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/26 8:38:49

算术表达式LR分析实战:从文法设计到驱动表实现

简介&#xff1a;一份面向编译原理学习者的C语言源码&#xff0c;实现算术表达式的LR语法分析。程序包含词法分析器与LR分析器核心逻辑&#xff0c;可读取用户输入的算术表达式&#xff0c;完成移进/归约操作并验证语法正确性&#xff0c;适合编译器设计入门及相关实验参考。压…

作者头像 李华
网站建设 2026/9/26 8:38:20

淘宝数据采集SDK:从开放平台API到登录爬取的工程化实践

简介&#xff1a;面向淘宝开放平台以及淘宝、天猫、阿里巴巴等电商站点的登录与数据抓取场景&#xff0c;这套爬虫软件开发工具包提供了登录模拟、验证码与Cookie处理、商品详情/价格/评论采集等核心模块&#xff0c;适合需要做市场分析、竞品监控、价格追踪或数据挖掘的开发者…

作者头像 李华
网站建设 2026/9/26 8:36:48

docling实战:从复杂PDF到干净Markdown的文档解析指南

很多做RAG或者文档智能处理的同学&#xff0c;应该都有过这样的经历&#xff1a;拿到一份PDF&#xff0c;里面既有正文又有表格&#xff0c;还有扫描图片&#xff0c;想把它喂给大模型或者做知识库&#xff0c;结果要么文字挤成一团&#xff0c;要么表格直接乱掉&#xff0c;比…

作者头像 李华
网站建设 2026/9/26 8:36:39

Windows 11 安装 TortoiseGit 四层依赖与右键集成详解

1. 为什么在 Windows 11 上装 TortoiseGit 不是“点下一步就完事”&#xff1f;——一个十年 Git 用户的真实观察 TortoiseGit 这个名字听起来像某种动物保护组织&#xff0c;但其实它是 Windows 平台上最成熟、最省心的 Git 图形化客户端。它不替代 Git 命令行&#xff0c;而是…

作者头像 李华