mcpField
P
python-development

python-development

github.com/microsoft开发14.5k60 次安装今天更新
代码仓库

关于 python-development

为 Python 项目提供编码规范,面向维护 agent_framework 代码的开发者,涵盖类型、文档、导出、性能与命名约定。

主要功能

  1. 01类型标注与参数规范
  2. 02Google 风格 API 文档字符串
  3. 03公共 API 导出规则
  4. 04性能与代码风格约定

适用场景

  1. 01为 Python 模块补充类型与文档
  2. 02调整 agent_framework 公共 API
  3. 03审查连接器及辅助函数命名

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/microsoft/agent-framework --skill python-development

安装后在 Claude Code 中输入/python-development确认已加载。

详细介绍

Python 开发规范

文件头

每个 .py 文件都必须以以下内容开头:

# Copyright (c) Microsoft. All rights reserved.

类型注解

  • 始终指定返回类型和参数类型
  • 使用 Type | None,而不是 Optional[Type]
  • 使用 from __future__ import annotations 启用延迟求值
  • TypeVar 名称使用后缀 T:ChatResponseT = TypeVar("ChatResponseT", bound=ChatResponse)
  • 对只读输入参数使用 Mapping,而不是 MutableMapping
  • 对内部调用并执行的方法,优先使用 # type: ignore[...],而不是不必要的类型转换或 isinstance 检查 但请确保忽略标记同时指定 mypy 和 pyright 的具体规则,以免遗漏其他错误
  • 有意在 agent_framework* 模块之间使用内部私有辅助函数是可以的;使用有针对性的 # pyright: ignore[reportPrivateUsage],不要仅为了满足 pyright 而将辅助函数公开。
  • 不要仅为满足类型检查而添加简单的透传函数或单行辅助函数。与其在没有设计收益的情况下增加运行时开销,不如使用有针对性的忽略标记、类型转换或更清晰的注解。

函数参数

  • 位置参数:最多 3 个明确预期的参数
  • 可选参数使用仅限关键字参数(放在 * 之后)
  • 提供基于字符串的覆盖方式,避免要求额外导入:
def create_agent(name: str, tool_mode: Literal['auto', 'required', 'none'] | ChatToolMode) -> Agent:
    if isinstance(tool_mode, str):
        tool_mode = ChatToolMode(tool_mode)
  • 避免遮蔽内置名称(使用 next_handler,而不是 next)
  • 除非子类可扩展性有此需要,否则避免使用 **kwargs;优先使用具名参数

文档字符串

所有公共 API 都使用 Google 风格的文档字符串:

def equal(arg1: str, arg2: str) -> bool:
    """Compares two strings and returns True if they are the same.

    Args:
        arg1: The first string to compare.
        arg2: The second string to compare.

    Returns:
        True if the strings are the same, False otherwise.

    Raises:
        ValueError: If one of the strings is empty.
    """
  • 始终记录 Agent Framework 特有的异常
  • 适用时明确使用 Keyword Args
  • 仅当触发条件不明显时,才记录 Python 标准异常

导入结构

# Core
from agent_framework import Agent, Message, tool

# Components
from agent_framework.observability import enable_sensitive_telemetry

# Connectors (lazy-loaded)
from agent_framework.openai import OpenAIChatClient
from agent_framework.foundry import FoundryChatClient

公共 API 和导出

在定义包级公共 API 的 __init__.py 文件中,使用直接重新导入,并显式声明 __all__。避免使用 from ._agents import Agent as Agent 这类身份别名,也避免使用 from module import *。

不要在内部的非 __init__.py 模块中定义 __all__。例外:有意作为公共导入入口的模块(例如 agent_framework.observability)应定义 __all__。

__all__ = ["Agent", "Message", "ChatResponse"]

from ._agents import Agent
from ._types import Message, ChatResponse

特殊情况:根目录下的 agent_framework/__init__.py 使用延迟运行时导出。对根目录公共 API 进行更改时:

  • 将符号添加到 _LAZY_MODULE_EXPORTS,并确保 _LAZY_EXPORTS 仍由其派生。
  • 保持显式运行时 __all__ 同步;from agent_framework import * 仍需要它。
  • 将相同的公共符号添加到 agent_framework/__init__.pyi,以便 pyright、mypy 和编辑器能够识别类型化接口。
  • 在所属模块中通过该模块的 __getattr__ 实现运行时弃用行为;避免在根目录为单个已弃用导出添加特殊分支。
  • .pyi 存根中的身份别名是合适的,因为它们会向类型检查器标记重新导出的名称;除非有特定的兼容性原因,否则应避免在运行时 .py 模块中使用。

性能指南

  • 缓存开销较大的计算(例如 JSON Schema 生成)
  • 在热点路径中,优先根据 .type 属性使用 match/case,而不是 isinstance()
  • 避免重复序列化——计算一次并重复使用

风格

  • 行长度:120 个字符
  • 仅格式化更改过的文件,不要格式化整个代码库
  • 参数大多相同时,优先使用属性而不是继承
  • 默认使用异步——假定所有操作都是异步的

Connector 命名约定

  • 用于为外部服务准备数据的方法,使用 _prepare_<object>_for_<purpose> 格式
  • 用于处理来自外部服务的数据的方法,使用 _parse_<object>_from_<source> 格式

评论

支持 Markdown