Claude Certified Architect 的前置准备里,Claude API 是最容易让人高估自己进度的一环。很多人以为把示例代码复制下来、能跑通一次,就算“会用 API”了。实际上一旦进入认证备考或者真实项目,环境配置、连接报错、结构化输出、批量任务一致性,每一件事都会把你拉回起点。Part 4 这个阶段的核心,就是通过 Claude API 搭出一套可复现的调用结构,而不是停留在“能收到回复”这一步。这篇文章适合正在准备认证的人,也适合刚接触 Claude API、想直接做工程集成的开发者,我会按“环境 -> 单次调用 -> 结构化输出 -> 可复用模块 -> 排查验证”的顺序,把整条链路拆开讲清楚。
1. 前置准备要准备的,不是“会用”,而是“能交付”
1.1 这个阶段到底在练什么
Claude Certified Architect 这类认证,不会只考提示词写得好不好。越是往架构师方向走,越看重你能不能把一个模型能力变成产品功能。前置准备阶段的目的,是把 API 调用的每个环节都跑熟,包括鉴权、参数、错误处理、输出解析、成本和稳定性。
从标题里的 Stru 看,Part 4 的重点更偏向“结构”:结构化输出、调用结构、代码目录结构。也就是说,你要能设计出一个稳定的 API 调用模块,让程序可以自动处理模型的返回结果,而不是每次都在命令行里肉眼判断。
我见过不少人在这个阶段只做一件事:把官方文档里的示例跑一遍。跑通之后很开心,但换一个输入就崩,换一台机器就崩,模型输出稍微带一点解释文字就崩。这不算准备完成。真正的完成标准是:换一台干净机器,照着你的说明能从头跑通,并且每个环节都能说明白为什么这么配。
1.2 结构能力为什么是分水岭
普通调用关心的是 content 文本,架构级集成关心的是 content 是否可解析、可校验、可重试。模型返回一段自然语言,人看没问题,程序处理却容易崩。结构化输出解决的就是接口契约问题。
举个例子。你在提示词里写“请返回 JSON”,模型很可能返回一段带反引号的代码块,或者在 JSON 前后加几句解释。人眼能看懂,但json.loads会直接报错。架构设计里不能把稳定性押在模型心情上,必须用更严格的校验和更可靠的方式去约束输出。
前置准备阶段把结构化输出练好,后面做工具调用、多步任务、规则引擎集成都会顺很多。因为那些场景本质上都是同一个问题:模型输出如何安全地进入下游系统。
2. 三个高频连接问题:证书、等待响应、API 网关
2.1 self-signed certificate 报错,通常不是模型问题
本地调试时,很多人会通过网关或内部服务转发 API 请求。网关为了保证通信安全,可能使用自签名证书。这时 SDK 会直接报错,例如“unable to connect to api: self-signed certificate”。
这句话的意思很明确:请求发出去了,但目标服务器的证书无法被验证。常见原因有三个:
- 网关使用了自签名证书,没有加入系统信任链。
- 环境变量里没有指定 CA 证书路径。
- 本地系统时间不对,导致证书有效期判断失败。
先别急着关掉证书校验。关掉确实能绕过报错,但也等于把凭证和请求内容暴露在中间链路上。生产环境更不建议这么干。
比较稳妥的做法是让客户端信任你的 CA 证书。以常见的语言环境为例:
# Node.js 环境 export NODE_EXTRA_CA_CERTS=/path/to/ca.pem # Python requests / httpx 环境 export REQUESTS_CA_BUNDLE=/path/to/ca.pem # 或者使用 OpenSSL 通用变量 export SSL_CERT_FILE=/path/to/ca.pem配置完成后,重新跑一次最小请求,确认证书报错消失。如果还在报错,优先看路径是否正确、证书文件是否是 PEM 格式。
2.2 waiting for API response:先分清是网络、请求体还是任务本身
Claude Code 这类交互式工具里,如果一直显示 waiting for API response,很多人第一反应是模型太慢。实际上要先确认请求到底有没有发出去。排查顺序建议固定下来。
先看 API 网关是否可达。网络不通的时候,客户端会一直等待连接超时。再看 API key 和 base_url 是否正确,鉴权失败有时会表现为长时间等待,而不是立刻返回 401。接着看请求体大小。上下文越长,模型处理时间越长,这是正常现象。如果上下文已经好几万字,等待时间变长是合理的,但不代表没有别的隐藏问题。
还要看日志。交互式工具一般会记录请求耗时和错误信息。如果是流式输出,要检查是否一直累积内容但没有结束标记。这种问题经常被当成“模型卡住”,其实是输出解析或事件流处理出了问题。
如果你的任务本身需要模型多次调用工具,每一次调用之间的等待时间也会累加起来。这时候不要只调大超时,先确认每个步骤是否都正常结束。
2.3 API 地址配置:用网关统一 base_url 是常规工程做法
多环境、多团队协作时,把 API 请求统一指向一个网关非常常见。原因有三个:统一鉴权、统一日志、统一配额。本地调试脚本里,也可以通过环境变量切换 API 地址,而不是改代码。
常见的环境变量大概长这样:
export ANTHROPIC_API_KEY=你的密钥 export ANTHROPIC_BASE_URL=https://your-gateway.example.com export ANTHROPIC_AUTH_TOKEN=你的令牌这里有个容易踩的坑:如果你设置了ANTHROPIC_AUTH_TOKEN,注意和ANTHROPIC_API_KEY的优先级差异。具体行为要看你使用的 SDK 版本。无论如何,不要把密钥硬编码到代码里。放在.env文件里,通过加载器注入,是最低成本的正确做法。
本地机器安装配置时,最常见的两个问题就是:API 地址填错,以及证书不被信任。如果你在安装客户端后第一次连接就失败,先确认这两个点,再去看更深的错误。
3. 结构化输出:把模型的“回答”变成程序的“数据”
3.1 为什么不能只靠一句“请返回 JSON”
提示词可以要求 JSON,但模型可能加注释、漏字段、字段类型错误,甚至输出被 max_tokens 截断。架构上不能把稳定性押在提示词上,至少要做三层保障:
- 请求侧:明确约束输出格式,并提供示例。
- 响应侧:解析 JSON 后做字段完整性校验。
- 失败侧:解析失败或校验失败时,触发重试或记录现场。
不同 API 版本对结构化输出的支持方式不同,有的版本支持强制 JSON 模式,有的版本需要用工具调用约束参数结构。具体参数要以你使用的 SDK 对应文档为准,但上面三层保障思路是通用的。
3.2 先有一条最小命令能跑通
我建议先用 curl 做一次最小请求。目的是隔离掉代码层面的干扰,确认网络和鉴权没有问题。
curl https://api.anthropic.com/v1/messages \ -H "x-api-key: $ANTHROPIC_API_KEY" \ -H "anthropic-version: 2023-06-01" \ -H "content-type: application/json" \ -d '{ "model": "<填入你账号可用的模型ID>", "max_tokens": 1024, "messages": [ {"role": "user", "content": "输出一段 JSON,包含 name 和 difficulty 两个字段"} ] }'这里几个点要说清楚。x-api-key是鉴权头,anthropic-version是接口版本协商头,缺少版本头在不同环境下的行为可能不一样。max_tokens要设置得够大,否则输出容易在 JSON 还没结束时被截断。
先跑通 curl,再进入 SDK 调用。这样一旦后面出错,你能快速判断问题出在网络层还是代码层。
3.3 Python 示例:拿到响应后先校验再使用
跑通 curl 之后,可以做一次最小 Python 调用。示例代码故意把校验写在最前面,因为能解析 JSON 不代表内容合格。
import json import os from anthropic import Anthropic client = Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY")) response = client.messages.create( model="<填入你账号可用的模型ID>", max_tokens=1024, system="你是一个只输出 JSON 的助手,不要输出任何解释。", messages=[ {"role": "user", "content": "请把这句话整理成 JSON,包含 name、type、steps 三个字段。"} ], ) text = response.content[0].text.strip() data = json.loads(text) assert {"name", "type", "steps"}.issubset(data.keys()), "字段缺失" print(data)注意两点。一是system参数是否单独传,不同 SDK 版本可能有差异,落地前先用官方文档确认。二是断言只是最基础的校验,实际项目里可以根据业务定义更严格的结构,比如字段类型、枚举值、嵌套层级。
这一步跑通后,你才算真正拿到“程序能直接消费的数据”,而不是一段人工阅读的文字。
4. 从单次脚本到可复用模块:把异常处理补上
4.1 单次脚本为什么不够用
复制示例代码只能证明 API 通了。认证任务和真实项目通常要求可复现的结果。比如连续跑 20 个输入,有的字段返回不对,有的请求超时,有的输出被截断。如果没有重试、日志和错误收集,你无法判断是模型问题还是程序问题。
单次脚本还有一个问题:所有信息都打印到终端。一旦任务跑多,终端刷新后现场就没了。可复用模块会把输入、输出、错误和原始响应都留下来,方便复盘。
4.2 一个最小可用封装
下面这个封装不复杂,但包含了四个关键设计:环境变量注入密钥、重试机制、日志记录、JSON 解析加校验。
import json import logging import os import time from anthropic import Anthropic client = Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY")) logging.basicConfig(level=logging.INFO) def call_claude_json(prompt: str, retries: int = 3): last_exc = None for attempt in range(retries): try: resp = client.messages.create( model="<模型ID>", max_tokens=1024, system="只输出 JSON。", messages=[{"role": "user", "content": prompt}], ) text = resp.content[0].text.strip() data = json.loads(text) logging.info("attempt %s ok, keys=%s", attempt + 1, list(data.keys())) return data except Exception as exc: last_exc = exc logging.warning("attempt %s failed: %s", attempt + 1, exc) time.sleep(2 ** attempt) raise RuntimeError(f"repeated failure: {last_exc}") if __name__ == "__main__": result = call_claude_json("请输出一个 JSON 配置示例") print(result)这里有几个细节值得解释。
- 重试间隔用
2 ** attempt,意思是第一次失败等 1 秒,第二次等 2 秒,第三次等 4 秒。避免瞬时故障时快速打爆网关。 - 每次失败都记录日志,不静默吞掉异常。
- 最终失败时抛出
RuntimeError,调用方才知道任务没有成功。如果直接返回空值,后续程序会误以为拿到了有效数据。
注意:重试不是万能的。如果是请求体格式错误、鉴权失败这类问题,重试再多次也没有意义。所以模块里通常要先判断异常类型,再决定是否重试。常见做法是:只有网络超时、5xx 错误、限流错误才走重试。
4.3 批量任务还要单独想输出命名和失败收集
进入批量任务后,不要把所有输出写到终端。建议按任务 ID 写文件,错误单独写日志,保留原始 prompt 和响应原文。
一个简单的输出目录结构可以长这样:
tasks/ input/ task_001.json task_002.json output/ task_001.result.json task_002.result.json error/ task_001.error.log这样跑完一批任务后,一眼就能看出哪些成功、哪些失败、失败在哪一步。如果直接把所有输出打到一个文件里,排查时得人工对着行号猜,非常低效。
单次脚本和可复用模块的差别可以用一张表概括:
| 维度 | 单次示例脚本 | 可复用模块 |
|---|---|---|
| 鉴权 | key 硬编码或写死路径 | 环境变量加统一配置 |
| 错误处理 | 报错就退出 | 重试、日志、异常抛出 |
| 输出校验 | 只看文本 | 解析 JSON 加字段校验 |
| 批量行为 | 手动改输入 | 读取任务列表、输出命名 |
| 复盘能力 | 不保留现场 | 保留请求、响应和错误日志 |
5. 本地环境验证顺序:不要把隐患留在写代码之前
5.1 建议按这个顺序跑一遍
本地安装和配置阶段,很多人喜欢直接启动交互式客户端,结果遇到报错也不知道从哪查起。我更建议按下面的顺序走一遍。
- 确认基础环境版本。Python 或 Node 版本太老,SDK 可能直接装不上。
- 配置环境变量。确保 API key、base_url、证书变量都已注入当前终端。
- 先用 curl 做最小请求,验证网络和鉴权。
- 跑一次 SDK 单次调用,确认代码环境正常。
- 跑一次结构化输出,确认 JSON 能稳定解析。
- 最后再启动 Claude Code 这类交互式工具,做端到端对话。
这样做的原因是:curl 最快把故障缩小到网络层;SDK 失败通常是版本、参数或依赖问题;交互式工具又在上面加了一层配置和权限逻辑。一层一层验证,出错时能快速定位,不用把网络、SDK、工具配置混在一起猜。
5.2 一张排查表
把常见现象和排查方向整理成一张表,遇到问题时先对着表看一下,比自己从头试高效很多。
| 现象 | 先看哪里 | 常见原因 | 建议 |
|---|---|---|---|
| 证书报错 | 环境变量、CA 文件 | 网关证书未被信任 | 配置 NODE_EXTRA_CA_CERTS 或写入系统信任链 |
| 长时间等待响应 | 网络连通性、请求体大小 | 上下文过长、网关限流、超时太短 | 先缩小请求体,再逐步增加内容 |
| 401/403 | API key、base_url | 环境变量没加载、令牌过期 | 检查 env 注入位置和令牌有效期 |
| 输出不是合法 JSON | 响应原文、max_tokens | 输出截断、提示词不收敛 | 调大 max_tokens,强化格式说明 |
| 同一输入结果不稳定 | 重试策略、校验逻辑 | 参数波动、缺少字段校验 | 增加校验,必要时降低随机性参数 |
5.3 Claude Code 这类交互工具要注意什么
Claude Code 不是只用 API key 就行。它会读取本地配置、工作目录、工具权限和输出令牌上限。如果一直显示 waiting for API response,去查它的日志目录,看有没有网络超时、认证失败或长上下文被截断的记录。
排查顺序仍然建议固定为:输入 -> 环境 -> 参数。先看是不是请求体太大,再看环境变量是否生效,最后看参数配置。不要一上来就改超时,那样可能掩盖真正的问题。
6. 备考建议:把这条链路做到“换个机器也能跑”
6.1 主线任务是什么
如果备考时间有限,只练一条主线就好:单次请求 -> 结构化输出 -> 错误重试 -> 小批量任务。这四件事看起来普通,但每一件都卡过不少刚起步的人。
你可以给自己安排一个模拟任务:准备 10 条输入文本,写一个脚本批量请求 Claude API,要求每条都输出指定字段的 JSON,然后统计成功率和失败原因。这个小任务能把本篇文章涉及的大部分知识点串起来。
做完之后,你会发现真正花时间的不是写请求代码,而是处理模型输出不稳定的情况。
6.2 什么时候算准备到位
我一般用三个标准自测。
第一,换一台干净机器,照着你的 README 能跑通完整流程,不需要口头补充。第二,能解释每个参数为什么这么设,而不是只会贴文档。第三,遇到错误时,能按网络、认证、请求体、输出校验四层定位问题。
达到这三点,后续做工具调用、多步智能体、系统集成都会舒服很多。
6.3 几个容易忽略的边界
模型 ID 会变化,不要把写死的模型名当成永恒。不同账号可用的模型列表可能不一样,落地时以账号实际可见的模型为准。
低配置机器能跑通,不代表适合跑长上下文。先用小样本验证,再逐步加大输入,同时观察内存和等待时间。
本地能跑通,也不代表生产环境能跑通。网关限流、并发策略、超时控制、敏感信息脱敏,都要在生产化时重新设计。
最后说一句实在话。Claude Certified Architect 考的不只是 API 的字符拼写,而是你在真实环境里能不能把一个模型能力安全、稳定、可维护地交出去。前置准备阶段这些琐碎问题,恰恰是最值钱的练习。