
最近在尝试把一些重复性工作交给 AI 自动处理时我发现了一个很有意思的现象很多开发者一听到“Agent”智能体这个词第一反应是去找最前沿、最复杂的框架试图构建一个能“自主思考”的超级大脑。结果往往是花了大把时间配置环境、调试参数最后连一个稳定的文件处理流程都跑不通。这让我想起一个更本质的问题我们真正需要的或许不是那个能“自主思考”的终极形态而是一个能可靠执行明确指令、把我们从重复劳动中解放出来的“数字副手”。这个副手不需要无所不能但它必须足够稳定、可控并且能清晰地告诉我们“它做了什么”以及“哪里出了问题”。今天要聊的正是围绕这个核心需求展开的一套实践方法。它不依赖于某个特定的、尚未成熟的“全能 Agent”框架而是基于 Anthropic 这类提供稳定、强大推理能力的模型 API结合清晰的任务拆解和流程设计来构建真正可用的“Agent Skills”智能体技能。你会发现从“跑通一个 Demo”到“拥有一个能放进生产流程的自动化技能”中间隔着的不是更复杂的算法而是一系列工程化的思考和设计。1. 先想清楚你要的到底是“工具”还是“技能”在开始写任何代码之前我们需要先区分两个容易混淆的概念Agent Tools智能体工具和Agent Skills智能体技能。很多教程和框架会把它们混为一谈但这恰恰是后续一切混乱的根源。Agent Tools工具通常指的是一些离散的、原子化的能力接口。比如一个“读取文件”的函数。一个“调用某 API 查询天气”的接口。一个“执行 Shell 命令”的模块。你可以把它们想象成工具箱里的一把把螺丝刀、钳子、锤子。它们功能明确但单独拿出来完成不了一件像样的“工作”。Agent Skills技能则是一个完整的、为达成特定目标而设计的工作流。它内部会按需调用一个或多个 Tools并包含决策逻辑、错误处理和结果整合。例如技能“周报生成器”1. 读取指定目录下的工作日志文件Tool: 读文件。2. 提取关键项目和进展调用大模型分析。3. 按照固定模板整理成文档Tool: 写文件。4. 通过邮件发送给指定人Tool: 发邮件。技能“数据简报员”1. 连接数据库Tool: 数据库连接。2. 执行预定义的 SQL 查询Tool: 执行查询。3. 将查询结果转换成图表调用图表生成库。4. 将图表插入 PPT 模板Tool: 操作文档。看到区别了吗Skill 是面向任务的、完整的解决方案而 Tool 是面向功能的、基础的构建块。我们常说的“Agent 开发”其核心价值往往不在于发明新的“锤子”Tool而在于如何用现有的“锤子、螺丝刀”组合出一套高效的“家具组装流程”Skill。所以在动手之前请先回答这个问题我要解决的是一个具体的、重复性的任务Skill还是仅仅想测试某个模型的新接口能力Tool如果你的答案是前者那么我们的重点就应该放在“工作流设计”和“可靠性保障”上而不是盲目追求 Agent 的“自主性”。2. 为什么选择 Anthropic 的模型作为“大脑”当我们确定了要构建的是Skill之后就需要一个可靠的“决策中枢”或“推理引擎”。这就是大模型扮演的角色。在众多选择中Anthropic 的 Claude 系列模型特别是 Claude 3 系列为什么是一个值得考虑的选项这不仅仅是性能问题更是稳定性和设计哲学的问题。首先是 API 的稳定性和一致性。对于生产级的 Skill 来说模型的输出是否稳定、API 服务是否可靠是首要考虑因素。Anthropic 的 API 在设计上强调清晰的结构化输出通过系统提示词和工具调用规范这大大降低了我们解析模型返回结果的复杂度。相比之下一些开源模型或新兴 API 可能在单次测试中表现惊艳但长期运行的稳定性和版本迭代的兼容性往往是未知数。其次是上下文长度和“思考”过程。Claude 模型支持超长的上下文如 200K tokens这对于处理多步骤任务、需要参考大量历史信息或长文档的 Skill 至关重要。更重要的是Anthropic 在模型设计上注重“可预测性”和“可控性”通过系统提示词System Prompt可以非常精确地约束模型的行为范围让它严格扮演你设定的“角色”比如“严谨的数据分析员”或“富有创意的文案助手”减少“胡言乱语”或执行超出范围操作的风险。一个常见的误区很多人会纠结于“Anthropic vs. OpenAI API 兼容性”这类问题。其实对于 Skill 开发而言核心是找到一套稳定、强大且你熟悉的“推理服务”。它们的 API 接口在核心功能聊天补全、工具调用上大同小异。关键在于你是否能利用好它的系统提示词、工具调用格式以及错误处理机制。选择哪一个更多取决于你的项目预算、对模型风格的偏好以及对服务商生态的依赖。关于网络连接问题在开发过程中你可能会遇到unable to connect to anthropic services或failed to connect to api.anthropic.com这类错误。这通常不是模型本身的问题而是环境配置或网络策略导致的。排查顺序应该是检查 API Key是否正确配置且未过期、未超过额度。检查网络连通性在终端使用curl或ping命令测试是否能访问 API 域名。检查代理设置如果你的开发环境需要通过特定网络配置访问外部服务请确保你的 HTTP 客户端如requests、httpx库或 SDK正确配置了代理。查看官方状态页访问 Anthropic 的状态页面确认服务是否出现区域性中断。把模型服务当作一个稳定的外部依赖是构建可靠 Skill 的第一步。3. 构建你的第一个 Skill从“单次跑通”到“流程固化”理论说再多不如动手构建一个。我们以一个常见的需求为例自动整理会议纪要。假设我们每次会议后都有一个粗糙的录音转文字文本我们需要一个 Skill 来将其整理成结构清晰的纪要。3.1 定义输入、输出和核心处理逻辑在写代码前先用自然语言把流程写下来输入一个包含杂乱对话的文本文件meeting_raw.txt。目标输出一个结构化的会议纪要 Markdown 文件meeting_summary.md。结构化要求会议主题参会人员讨论要点分条列出达成的共识或决议待办事项分配给人、截止时间处理逻辑调用大模型根据上述要求从杂乱文本中提取、归纳、重组信息。这个定义本身就是你 Skill 的“设计文档”。3.2 环境准备与最小可行代码我们使用 Python 和anthropic官方 SDK。首先确保环境就绪# 安装 SDK pip install anthropic httpx # 设置环境变量或在代码中直接配置 export ANTHROPIC_API_KEYyour-api-key-here接着编写最小可行代码目标是“跑通一次”import anthropic import os from pathlib import Path # 1. 初始化客户端 client anthropic.Anthropic( api_keyos.environ.get(ANTHROPIC_API_KEY) ) # 2. 定义 Skill 的核心函数 def summarize_meeting(raw_text_path: str, output_path: str): 会议纪要整理 Skill # 读取原始文本 with open(raw_text_path, r, encodingutf-8) as f: raw_text f.read() # 3. 构建给模型的系统提示词 - 这是 Skill 的“灵魂” system_prompt 你是一个专业的会议纪要整理助手。请根据提供的原始会议对话文本提取并生成一份结构清晰的会议纪要。 纪要必须包含以下部分并使用 Markdown 格式输出 1. **会议主题**用一句话概括。 2. **参会人员**列出所有提到的人名。 3. **讨论要点**分条列出会议中讨论的核心议题和观点。 4. **共识与决议**明确会议达成的结论和决定。 5. **待办事项 (Action Items)**列出具体的任务、负责人如可识别和期望截止时间如可识别。 要求内容准确、条理清晰、语言精炼。如果某些信息无法从文本中推断请注明“未明确提及”。 # 4. 调用模型 try: message client.messages.create( modelclaude-3-sonnet-20240229, # 根据实际情况选择模型版本 max_tokens2000, systemsystem_prompt, messages[ {role: user, content: f这是会议原始文本\n\n{raw_text}} ] ) summary message.content[0].text except Exception as e: # 5. 基础错误处理 print(f调用模型 API 失败: {e}) return False # 6. 保存结果 with open(output_path, w, encodingutf-8) as f: f.write(summary) print(f会议纪要已生成: {output_path}) return True # 7. 执行一次 if __name__ __main__: success summarize_meeting(meeting_raw.txt, meeting_summary.md) if success: print(Skill 执行成功) else: print(Skill 执行失败。)恭喜你的第一个 Skill 的“心脏”已经跳动了。它完成了从读取、处理到输出的完整流程。但请注意这仅仅是“单次跑通”。它脆弱得像实验室里的原型机无法应对真实世界的复杂情况。4. 从“能跑”到“好用”工程化必须补上的四块拼图一个只能在你本地电脑上对着特定文件跑一次的脚本算不上真正的 Skill。要让它能被你自己或他人长期、稳定地使用你需要系统地解决以下四个问题。4.1 拼图一健壮的输入输出处理上面的代码假设输入文件一定存在、可读输出路径一定可写。这太理想了。改进步骤输入验证检查文件是否存在、格式是否正确比如是不是文本文件、大小是否合理避免意外传入超大文件耗尽资源。路径处理使用pathlib库处理跨平台路径问题解析相对路径和绝对路径。输出安全检查输出目录是否存在如果不存在是否创建如果输出文件已存在是覆盖、重命名还是报错这需要根据你的业务逻辑决定。编码处理明确指定读写文件的编码如utf-8并处理可能遇到的编码错误。from pathlib import Path import sys def validate_and_prepare_paths(raw_text_path: str, output_path: str): 验证并准备输入输出路径 input_path Path(raw_text_path) output_path Path(output_path) # 检查输入 if not input_path.exists(): raise FileNotFoundError(f输入文件不存在: {input_path}) if not input_path.is_file(): raise ValueError(f输入路径不是文件: {input_path}) # 可选检查文件大小例如限制为 10MB if input_path.stat().st_size 10 * 1024 * 1024: raise ValueError(f输入文件过大超过10MB: {input_path}) # 准备输出目录 output_dir output_path.parent output_dir.mkdir(parentsTrue, exist_okTrue) # 自动创建不存在的目录 # 检查输出文件是否已存在示例策略报错 if output_path.exists(): # 策略1: 直接报错防止覆盖 raise FileExistsError(f输出文件已存在请指定新路径: {output_path}) # 策略2: 自动生成带时间戳的新文件名 # timestamp datetime.now().strftime(%Y%m%d_%H%M%S) # new_output_path output_path.with_stem(f{output_path.stem}_{timestamp}) # return input_path, new_output_path return input_path, output_path4.2 拼图二完善的错误处理与日志记录“调用模型 API 失败: {e}” 这样的打印信息在后台运行时毫无用处。你需要结构化的日志以便事后排查。改进步骤使用logging模块替代print可以设置不同级别DEBUG, INFO, WARNING, ERROR并输出到文件和控制台。分类处理异常网络超时、API 配额不足、模型过载、输入格式错误……不同类型的异常应有不同的处理或重试策略。添加重试机制对于网络波动或 API 限流导致的临时失败可以实现带指数退避的重试逻辑。import logging import time from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type # 配置日志 logging.basicConfig( levellogging.INFO, format%(asctime)s - %(name)s - %(levelname)s - %(message)s, handlers[ logging.FileHandler(skill_meeting_summary.log), logging.StreamHandler(sys.stdout) ] ) logger logging.getLogger(__name__) # 定义可重试的异常类型例如网络相关 def is_retryable_exception(exception): return isinstance(exception, (anthropic.APIConnectionError, anthropic.RateLimitError)) retry( stopstop_after_attempt(3), # 最多重试3次 waitwait_exponential(multiplier1, min2, max10), # 指数退避等待 retryretry_if_exception_type(is_retryable_exception) ) def call_model_with_retry(client, **kwargs): 带重试的模型调用 return client.messages.create(**kwargs) def summarize_meeting_robust(raw_text_path: str, output_path: str): logger.info(f开始处理会议纪要输入: {raw_text_path}, 输出: {output_path}) try: input_path, output_path_obj validate_and_prepare_paths(raw_text_path, output_path) with open(input_path, r, encodingutf-8) as f: raw_text f.read() # ... 构建 system_prompt ... message call_model_with_retry( clientclient, modelclaude-3-sonnet-20240229, max_tokens2000, systemsystem_prompt, messages[...] ) summary message.content[0].text with open(output_path_obj, w, encodingutf-8) as f: f.write(summary) logger.info(f成功生成会议纪要: {output_path_obj}) return True except FileNotFoundError as e: logger.error(f输入文件错误: {e}) return False except anthropic.AuthenticationError as e: logger.critical(fAPI 认证失败请检查 API Key: {e}) return False except Exception as e: logger.exception(f处理过程中发生未预期错误: {e}) # 会记录完整的堆栈跟踪 return False4.3 拼图三配置化与参数管理把模型类型、API Key、文件路径、提示词模板都硬编码在代码里是灾难。你需要一个配置系统。改进步骤使用配置文件如config.yaml或.env文件。分离提示词模板将system_prompt甚至user_prompt的模板放在单独的文件如prompts/meeting_summary.j2中使用 Jinja2 等模板引擎渲染便于管理和迭代。环境变量管理密钥API Key 等敏感信息永远不要写进代码。# config.yaml model: name: claude-3-sonnet-20240229 max_tokens: 2000 temperature: 0.2 # 控制创造性对于纪要整理低一点更稳定 paths: default_input_dir: ./data/input default_output_dir: ./data/output skill: meeting_summary: prompt_file: ./prompts/meeting_summary_system.j2 output_extension: .md# 在代码中加载配置 import yaml from jinja2 import Environment, FileSystemLoader with open(config.yaml, r) as f: config yaml.safe_load(f) env Environment(loaderFileSystemLoader(.)) template env.get_template(config[skill][meeting_summary][prompt_file]) # 可以根据需要传入变量到模板 system_prompt template.render()4.4 拼图四批量化与调度执行一个真正的 Skill 应该能处理批量任务并能被定时或事件触发。改进步骤批量处理扫描输入目录处理所有符合条件的文件。任务队列对于大量任务可以引入简单的任务队列如RQ、Celery避免阻塞。调度使用cron(Linux/macOS) 或Task Scheduler(Windows) 定时运行脚本或者集成到 Web 服务中通过 API 触发。def batch_process_meetings(input_dir: str, output_dir: str): 批量处理一个目录下的所有会议原始文本 input_dir Path(input_dir) output_dir Path(output_dir) output_dir.mkdir(exist_okTrue) for input_file in input_dir.glob(*.txt): # 假设原始文件是 .txt output_file output_dir / f{input_file.stem}_summary.md logger.info(f处理文件: {input_file} - {output_file}) success summarize_meeting_robust(str(input_file), str(output_file)) if not success: logger.warning(f文件处理失败: {input_file}) # 可选处理成功后将原文件移动到“已处理”文件夹避免重复处理当你把这四块拼图——健壮的 IO、完善的日志与错误处理、灵活的配置、批量化能力——都补上后你的“会议纪要整理 Skill”才从一个脆弱的脚本进化成了一个可维护、可监控、可扩展的自动化工具。这才是 Agent Skill 工程化的核心。5. 进阶思考Skill 的编排、评估与迭代当你拥有多个可靠的 Skill 后自然会想到能否让它们协同工作如何知道它们工作得好不好这就进入了更进阶的领域。5.1 Skill 的编排从单技能到工作流“会议纪要整理 Skill”的输出是一份 Markdown。也许下一个 Skill 是“周报生成器”它需要读取本周所有的会议纪要和项目文档来生成周报。这时你就需要编排Orchestration。你可以编写一个“主控”脚本或使用轻量级工作流引擎如Prefect、Airflow的轻量用法甚至是一个简单的 Python 调度脚本来定义 Skill 的执行顺序和数据传递。# 一个简单的工作流示例 def weekly_report_workflow(week_start_date): 周报生成工作流 # 1. 调用 Skill A: 汇总本周所有会议纪要 all_meetings_summary skill_summarize_weekly_meetings(week_start_date) # 2. 调用 Skill B: 从项目管理工具获取本周任务状态 project_updates skill_fetch_project_updates(week_start_date) # 3. 调用 Skill C: 整合信息生成周报 final_report skill_generate_weekly_report(all_meetings_summary, project_updates) # 4. 调用 Skill D: 将周报发布到指定频道如 Slack, Email skill_publish_report(final_report) return final_report5.2 Skill 的评估如何衡量“好”与“坏”AI 生成的内容质量不稳定。你需要建立评估机制。人工抽查定期随机检查 Skill 的输出结果这是最直接有效的方式。自动化指标对于一些任务可以定义自动化指标。例如对于摘要 Skill可以计算生成摘要与人工摘要的 ROUGE 分数需要参考摘要对于信息提取 Skill可以检查关键字段如“待办事项”、“负责人”的提取准确率和召回率。业务指标最终Skill 的价值要用业务指标衡量。比如使用“会议纪要整理 Skill”后员工编写纪要的平均时间是否下降了周报的完整性和及时性是否提高了在 Skill 的日志中可以加入评估环节的记录为持续优化提供数据支持。5.3 Skill 的迭代提示词工程与流程优化Skill 不是一次开发就永远完美的。你需要一个迭代循环收集失败案例通过日志和人工抽查收集 Skill 处理出错或效果不佳的样本。分析根因是输入数据格式意外是提示词指令模糊还是模型在某些场景下理解有偏差优化提示词这是迭代成本最低、效果往往最明显的一步。让指令更清晰增加正面和反面的例子Few-shot Learning明确输出格式的约束。优化流程有时问题不在模型而在前后流程。比如在调用模型前是否可以先对原始文本做一次简单的清洗去除无关字符、分段输出后是否需要一个简单的格式校验步骤更新与部署将优化后的提示词模板或预处理代码更新到配置中重新部署 Skill。构建 Agent Skill 的本质是将人类处理复杂任务的“经验”和“判断逻辑”通过清晰的指令提示词和稳定的流程代码固化成一个可重复、可扩展的自动化服务。它不需要一开始就追求完全的自主和智能而是从解决一个具体的、高频率的痛点开始通过不断的工程化打磨和迭代变得真正可靠和有用。从这个角度看学习 Agent Skills 的最佳路径不是去追逐最炫酷的框架而是选择一个像 Anthropic Claude 这样稳定强大的“大脑”然后从设计一个解决自己实际问题的、完整的“技能工作流”开始亲手把它从实验室原型打磨成能在生产环境中稳定运行的工程化组件。这个过程所积累的才是真正属于你的、关于 AI 工程化的核心能力。