- 人工智能
- 大模型
- AI Agent
- Agent 框架
- 多智能体
- 工具调用
- MCP 服务
【免费下载链接】harness-sdk
Build an agent harness and control it end-to-end. Open-source SDK for production AI agents in Python & TypeScript - any model, any cloud.
导读
本篇技术指南以仓库根目录的 AGENTS.md 为主体,系统讲解 Strands Agents 单仓库(monorepo)为 AI 编程助手(Agent)设计的一整套协作开发规范:从仓库布局与"为什么"文档体系,到认知复杂度度量、跨 SDK(Python 与 TypeScript)一致性约定、测试红线、PR 全流程与社区协作姿态。读完本文,你将理解这个双语言 Agent SDK 仓库如何让"编写代码、开 PR、协助贡献者"三类不同目标的 Agent 在同一个仓库内高效、低冲突地并行工作,并能直接照着这些规范在仓库内定位源码、运行检查命令与参与贡献。
一、Monorepo 布局:进入仓库先定位自己
AGENTS.md 开篇即给出明确的定位策略:这是一份"按任务组织"的共享指南,同一文件被不同目标的 Agent(写代码、开 PR、协助贡献者)共用,因此第一步永远是确定你所在的子项目,并遵循该子项目自己的AGENTS.md。
仓库顶层结构如下:
strands-agents/ ├── strands-py/ # Python SDK(hatch 管理)— 见 strands-py/AGENTS.md ├── strands-ts/ # TypeScript SDK(npm workspace)— 见 strands-ts/AGENTS.md ├── site/ # 文档站点(Astro)— 见 site/AGENTS.md ├── team/ # 治理 + 跨 SDK 流程(tenets、decisions、API bar、PR 与兼容性指南、designs/ 提案) ├── test-infra/ # 需要预置 AWS 基础设施的集成测试 CDK 栈 ├── .agents/ # Agent 技能(skills)与参考资料(references) ├── package.json # npm workspace 根 └── .github/workflows/ # CI(ci.yml 是合并门禁)对应的生产代码分布可以从根 README.md 一览:strands-py/是 Python SDK(agent loop、模型提供商、工具),strands-ts/是 TypeScript SDK,harness-py/与harness-ts/是通过create_harness()/createHarness()一行组装出完整 Agent 的 harness 包,strands-cli/是终端里的strandsCLI,site/是文档站点源码。子项目的代码结构在各自的AGENTS.md中另有详解:例如 strands-py/AGENTS.md 给出src/strands/下agent/、models/、tools/、multiagent/、session/、telemetry/等子系统目录;strands-ts/AGENTS.md 则对应src/下的agent/、models/、conversation-manager/、hooks/等目录。两个 SDK 的单元测试布局也遵循各自惯例:Python 在tests/下严格镜像src/strands/结构,TypeScript 则将测试与源码同目录放置于src/**/__tests__/。
二、"为什么"沉淀在 team/:动手设计前先读决策文档
AGENTS.md 强调:在设计新功能或改动 API 之前,应先阅读team/下的相关上下文。代码本身不记录"为什么",team/才是推理过程的载体:
team/designs/—— RFC 风格的重要功能提案(编号为NNNN-*.md),是架构上下文最丰富的来源:包含问题框定、方案选择、备选方案与后果分析。要动某个大型子系统,先找它的设计文档;team/DECISIONS.md—— 较轻量的架构决策记录(ADR),用于小规模决策;team/TENETS.md—— 贡献应遵循的原则;team/API_BAR_RAISING.md与team/FEATURE_LIFECYCLE.md—— API 变更的准入门槛与功能弃用的流程。
这一设计与仓库实际的团队目录一一对应:team/下确实存放着从 0001-plugins.md、0005-state-machine.md 到 0018-shared-agent-model-types.md 等 18 份编号提案,以及 DECISIONS.md、TENETS.md、API_BAR_RAISING.md、FEATURE_LIFECYCLE.md 等流程文档。从源码结构看,这套"先读决策文档再动手"的约定,是仓库维持双语言一致演进的关键治理机制。
三、写代码:复杂度标签、分支与提交规范
3.1 认知复杂度:每个 PR 都要贴标签
AGENTS.md 规定:每个 PR 都必须以其触及的最复杂函数的认知复杂度(cognitive complexity)打上标签,并且嵌套(nesting)是驱动分数的关键因素。具体要求写平的控制流——守卫子句(guard clauses)、提取辅助函数、用查找表替代分支阶梯——并把重构单独放进自己的 PR。分数的分级与本地检查命令,在根 package.json 与 team/COMPLEXITY.md 中均有落地:
- 分级阈值:
complexity/low(≤ 10)、complexity/medium(11–25)、complexity/high(> 25)。两个 SDK 的函数复杂度中位数在 1–2 分,low覆盖约九成现有函数; - 计分规则:线性流程的每次打断记 1 分(
if、else、循环、catch/except、三元表达式、switch/match、递归、混用布尔运算符的每一段);嵌套会放大代价——每层嵌套再各记 1 分,函数顶层的一个if是 1 分,三层嵌套就是 4 分; - 贴标签的公平性:标签基于你的 diff,只针对实际触动的函数计算;相对于合并基线(merge base)分数没有增加的函数不计入,所以"给一个本就复杂的函数穿线式地加小改动"会落在
complexity/low,而加深该函数则按全额计分——这再次鼓励"提取而非加深"; - 本地预检命令:
npm run complexity(仓库根)或hatch run complexity(strands-py/内)。从 .github/scripts/pr-metrics/run-analysis.mjs 的实现看,它由 CI 调用同一个入口,因此本地看到的标签与 CI 打出的完全一致:脚本通过git diff --numstat -z计算改动文件、用merge-base取基线、Python 侧用 complexipy 输出 SARIF、TypeScript 侧加载专用分析引擎,且全程只解析不执行源码,对不受信任的 PR 也安全。标签是建议性的,从不阻塞合并——协议事件转换器、状态机等"领域本身就有这么多分支"的代码落在high是诚实的,在 PR 描述里说明一句即可。
3.2 分支、提交与合并门禁
- 分支命名:
git checkout -b agent-tasks/{ISSUE_NUMBER}; - 提交规范:使用 conventional commits ——
feat:、fix:、refactor:、docs:等; - CI:
ci.yml合并门禁会检测改动了哪些路径,只运行相关的检查(这与.agents/skills/pre-push技能的"按区域运行检查"逻辑一致); - Skills(仓库级可复用工作流):
.agents/skills/下按域组织——PR 流程(pr-create、pr-writer、pr-feedback)、文档(docs-writer、docs-reviewer、docs-audit、docs-planner)、代码评审(strands-review)与本地预检(pre-push),各技能用途详见 .agents/skills/README.md。新增技能时在.agents/skills/<skill-name>/下建目录,至少包含带 frontmatter 与指令的SKILL.md,技能命名遵循{domain}-{action},且涉及不可靠 CLI 的工作流应打包已测试过的脚本而非内联命令; sourceLinks追踪源文件:site/下的文档页面通过 frontmatter 中的sourceLinks指向其实现源码(仓库相对路径,指向strands-py/与strands-ts/)。重命名或移动源文件时,必须在同一改动里更新所有引用旧路径的sourceLinks——站点构建只会在路径格式错误或扩展名无法映射时失败,不会因路径指向已不存在的文件而失败,过时引用会静默腐烂;可用grep -rn "<old/path>" site/src/content/docs查找受影响页面。
四、跨 SDK 约定:让两套实现永不漂移
AGENTS.md 明确:这些规则同时适用于 Python 与 TypeScript 两个 SDK,各子指南(strands-py/AGENTS.md、strands-ts/AGENTS.md)只展示语言惯用形态,共享意图集中在根文档,避免两者漂移。两个 SDK 追求的是概念与名称的对等(parity),而非逐行相同的代码。
4.1 命名:按"做什么"命名构造,而不是按接口命名
- 构造(construct)按功能命名:
AgentSkills、ContextOffloader、GoalLoop——绝不用…Plugin后缀。Python 的vended_plugins/与 TS 的vended-plugins/目录已经遵循此规则; - 目录命名用语言惯用分隔符,但词干逐词对应、可机械互转:
vended_plugins/↔vended-plugins/、conversation_manager/↔conversation-manager/。
4.2 奇偶性(parity):标识符、字面量与 wire 字段
- 标识符逐一对应,按语言惯用重新转大小写(
snake_case↔camelCase); - 单词型字符串字面量值字节级一致(
'user'、'success'); - 多词字符串字面量值:Python 用
snake_case、TypeScript 用camelCase(tool_use↔toolUse),必须通过显式映射转换,绝不直接输出另一种语言的写法(TS 侧由STOP_REASON_MAP/snakeToCamel承载,见 strands-ts/AGENTS.md); - wire 字段名(与模型提供商 API 交换的键)在两个 SDK 中保持 wire 格式,即使违反语言的大小写惯例(如
inputSchema、tool_use_id); - 钩子(hook)事件名跨 SDK 共享(除后缀约定外):在一个 SDK 新增 hook 事件时,另一个也要加上同名事件。Python 侧的事件命名规则(
Event后缀、Before{Action}Event/After{Action}Event配对、每个Before都有逆注册顺序调用的After)见 strands-py/AGENTS.md 与 strands-py/docs/HOOKS.md。
4.3 公共 API 与内部 API 的标记
- Python:内部符号不进
__all__,且模块应以_前缀命名;公共包在__init__.py中声明显式__all__,可选或重量级模型提供商通过模块级__getattr__懒加载,避免导入包时拉入每个提供商的第三方依赖(见 strands-py/AGENTS.md); - TypeScript:内部符号不放进
index.ts桶文件(barrel),并打@internalTSDoc 标签——TS 没有_前缀文件名的惯例,CancelledError在index.ts中的有意省略注释即是范例;仅使用命名导出,仓库内零个export default(见 strands-ts/AGENTS.md)。
4.4 结构化日志格式
统一格式为:field=<value>, field=<value> | 小写人类可读消息,不加标点,多条语句用管道符分隔:
- Python用
%s插值(禁用 f-string,由 ruffG规则强制),这样在日志级别关闭时跳过插值开销:logger.debug("user_id=<%s>, action=<%s> | user performed action", user_id, action); - TypeScript用模板字符串(禁用 printf 风格
%s/%d):logger.warn(\stop_reason=<${stopReason}>, fallback=<${fallback}> | unknown stop reason, converting to camelCase`)`。
此外 Python 侧还区分warnings.warn与logger.warning的受众(按受众而非严重级别选择):warnings.warn(...)面向开发者——配置字段被忽略/无效、参数被弃用等"SDK 被如何使用"的提示,需显式传stacklevel指向调用方(参考 models/_validation.py 中validate_config_keys的stacklevel=4);logger.warning(...)面向运维诊断——运行期出错(MCP 服务器启动失败、工具加载失败、存储写入失败),供日志聚合使用。
4.5 常青注释(evergreen comments)
注释只陈述无法从代码推断的内容(约束、不变量、非显而易见的"为什么"),并保持简短;向评审者解释或辩护改动的推理属于 PR 描述,不属于源码。禁止叙述代码如何变化或过去是什么样("improved"、"previously"、"used to"、"which would previously have crashed")。这条同样适用于测试:为已发现 bug 写的回归测试要链接其防护的问题并说明保证的行为;作为功能开发一部分写的测试不携带 issue 引用。("deprecated"/"legacy" 在描述稳定的 API 表面或运行期状态时是允许的,仅在叙述代码自身如何变化时被禁止。)
4.6 语言惯用的其他关键规范
两个子指南还给出了各自语言内 lint 无法覆盖的约定,可作为写代码时的检查清单:
- Python(strands-py/AGENTS.md):可选类型一律写 PEP 604 联合
X | None,禁用Optional[X];类型抑制必须带代码(# type: ignore[code],裸 ignore 在warn_unused_ignores下会自我清理);数据结构按角色选型——wire/消息/配置形状用TypedDict(total=False+Required/NotRequired),拥有行为/默认值/序列化助手的运行时对象用@dataclass,只有模型读写的 schema 才用 pydanticBaseModel;公共函数抛错作为契约的一部分时必须写Raises:段;错误处理抛具体类型并用from链上原因,模型提供商要把厂商错误翻译成 SDK 类型化异常(如ContextWindowOverflowException、ModelThrottledException);可扩展接口用带**kwargs的Protocol而非Callable;工具引用用tool.tool_name属性而非硬编码字符串。 - TypeScript(strands-ts/AGENTS.md):对象形状用
interface(组合用extends),type别名只用于联合/交叉/函数/映射类型;exactOptionalPropertyTypes下优先写裸prop?: T;函数签名必须有显式返回类型但局部变量交由推断;供应商错误翻译成类型化错误并保留{ cause };导出的可抛错函数/方法用@throws标注,@example只保留给入口类(如BedrockModel、Agent),不给类型定义;依赖若跨 API 边界则必须是peerDependencies。
五、测试:子项目指引 + test-infra 红线
写测试时遵循各子项目的测试文档——Python SDK 看 strands-py/docs/TESTING.md,TypeScript SDK 看 strands-ts/docs/TESTING.md。两个子指南进一步细化:Python 单元测试在tests/严格镜像src/strands/结构、用tests/fixtures/的共享夹具、每个 async 测试标注@pytest.mark.asyncio;TS 测试与源码同目录(src/**/__tests__/)、遵循嵌套describe模式与批量策略。
test-infra/的红线必须牢记。test-infra/的 CDK 栈会部署真实的 AWS 资源(Bedrock 知识库、EC2 实例),只有一小部分集成测试依赖它;绝大多数测试不需要预置基础设施即可运行:
- 除非你在专门维护测试基础设施本身,或迭代从该栈解析 SSM 参数的测试,否则不要部署这个栈;
- 绝不在非内部账号设置
STRANDS_TEST_INFRA_INTERNAL=true——它附加了宽泛的内部策略与 GitHub OIDC 信任,在内部账号之外毫无意义且浪费资源; - 要运行依赖基础设施的集成测试而无需部署任何东西:直接开 PR,CI 会自动对预置资源运行它们。
六、创建 PR:小而聚焦,作者全程负责
开 PR 时遵循 team/PR.md,并可用.agents/skills/下的pr-create与pr-writer技能起草与提交。若你代表贡献者开 PR,人是作者,对提交的一切负责——小而聚焦、作者完全理解的改动,是快速评审与被接受的最大预测因子。AGENTS.md 列出的关键纪律:
- 提交前先理解:贡献者必须能解释每一行为何工作、能捍卫设计;写不出就能解释的代码,先简化再提交;
- 保持小而聚焦:一个 PR 一个逻辑变更;同时触碰多个子项目(
strands-py/、strands-ts/、site/)的分支几乎总是应该拆成多个 PR; - 重要改动先开 issue,让维护者在投入时间前对齐方案;
- 不灌水:不要顺手的重新格式化、无关重构或投机性抽象,它们让 diff 难评审、让改动难信任;
- 提交前验证:运行相关子项目的检查(见 CONTRIBUTING.md 的 Development Environment 或子项目自己的
AGENTS.md),确保改动在本地能通过ci.yml合并门禁,绝不在已知 lint/类型/测试失败的情况下开 PR; - 真正演练改动,而不只依赖门禁:自动化检查确认代码有效,不代表功能可用。端到端跑一遍行为(手写脚本、REPL 片段、CLI 或示例),确认它做到了 PR 声称的事(含边界情况);若无法演练(如需要预置基础设施),就在 PR 里明说,而不是暗示已测试;对评审有帮助时附上你运行的脚本或命令;
- 以评审者视角通读 diff 做自审,并诚实勾选 PR 模板中的每一项——包括"已评审并理解 PR 中每一行代码(含 AI 生成的代码)"那一项,然后用
pr-writer技能让描述讲清为什么。
从 .agents/skills/README.md 看,这套流程已被技能化:pr-writer按 Conventional Commits、PR 模板与team/PR.md生成标题与描述,并从对话中捕获设计决策;pr-create编排完整流程(描述生成、CONTRIBUTING.md 预检、条件式 push、gh pr create --draft),预防"非 draft PR""不兼容 flag"等 Agent 常见错误;pr-feedback通过打包脚本用 GitHub GraphQL 拉取所有未解决评论,用反应数据与作者回复区分"同意修复"与"开放讨论"。
七、评审:文档改动需要专用技能
当改动涉及site/下的文档时,除标准代码评审外还要应用.agents/skills/中的文档技能:
.agents/skills/docs-reviewer/SKILL.md—— 检查语气一致性、结构、术语与代码示例质量;.agents/skills/docs-audit/SKILL.md—— 对照实时 SDK 源码核对技术准确性(导入路径、方法签名、API 正确性)。
评审前必须对照 .agents/references/terminology.md 核对术语、对照 .agents/references/mdx-authoring.md 核对 MDX 写作模式。AGENTS.md 特别强调:必须真正阅读这些被引用的源文件再评审——只浏览摘要,它们的标准就不适用。
八、与社区协作:是向导,不是守门人
协助他人贡献时,你是向导——不是守门人,也不是代笔人。贡献属于贡献者本人;帮助它变好、让贡献者学到东西,才是目标。好贡献的标准见 CONTRIBUTING.md,而这一节是关于"人"的:
- 把真实问题引向社区:真正的疑问与设计讨论属于人——Discord 与 GitHub Discussions;
- 假定善意:大多数贡献者都在学习,要接住他们当前的水平;good first issues 是带新人进来的入口,不只是要关闭的工单;
- 与贡献者"对话"而非"说教":温暖、平实、简洁;一次只问一个问题,不长篇大论,绝不居高临下;解释为什么,让解释成为教学而非命令。
总结:从根 AGENTS.md 出发的协作闭环
纵观全文,根 AGENTS.md 构建了一个完整闭环:进入仓库先按子项目定位 → 动手前先读team/决策文档 → 写代码时以认知复杂度标签为量化纪律、以跨 SDK 奇偶性约定防止双语言漂移 → 测试时严守test-infra/红线 → 开 PR 时坚持小而聚焦、以pr-create/pr-writer等技能辅助 → 评审文档改动时调用专用技能 → 面向社区时保持向导姿态。这套规范不只是给人看的,更是为 AI Agent 设计的可执行契约——配合.agents/skills/下的技能化工作流与npm run complexity、hatch run complexity等可本地复现的检查命令,任何 Agent 都能在进入仓库后快速对齐预期、产出高质量且可被快速评审的改动。对希望深入参与 Strands Agents 双语言 SDK 开发的工程师与 Agent 而言,AGENTS.md 就是那张"如何使用这个仓库"的地图。
- 人工智能
- 大模型
- AI Agent
- Agent 框架
- 多智能体
- 工具调用
- MCP 服务
【免费下载链接】harness-sdk
Build an agent harness and control it end-to-end. Open-source SDK for production AI agents in Python & TypeScript - any model, any cloud.
相关推荐
VoltAgent 仓库开发指南:从 AI Agent 协作规范到 Monorepo 验证工作流
VoltAgent 仓库开发指南:从 AI Agent 协作规范到 Monorepo 验证工作流 VoltAgent 是一个开源的 TypeScript AI
人工智能AI AgentAgent 框架后端多智能体RAG工具调用Agent 记忆Agent 工作流AI 评测MCP 服务MCP Clients语音Composio 仓库导航指南:SDK Monorepo 布局、分支工作流与 Agent Skills 维护规范
Composio 仓库导航指南:SDK Monorepo 布局、分支工作流与 Agent Skills 维护规范 本指南围绕 Composio SDK 仓库内的
人工智能AI Agent工具调用MCP 服务MCP Clientsdoocs/md 仓库开发指南:从 Monorepo 结构到 Agent 协作规范的完整解读
doocs/md 仓库开发指南:从 Monorepo 结构到 Agent 协作规范的完整解读 导读 本文以 doocs/md(微信 Markdown 编辑器)仓
前端AI 应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考