跳至内容

实验 01 — 环境配置

目标: 设置 Python 技术路线用于 GitHub Copilot SDK,使用 Agent HQ 演示应用作为 SDK 会话、流式传输和示例的可执行车辆。

用时: ~15 分钟

前置条件

只需要一个实施路线来完成实验。此页面使用了src/AgentOrchestrator-python/下的Python子项;.NET路线仍然保留在src/AgentOrchestrator/下。

安装这些内容之前:

  • Python 3.11 或更高版本
  • uv 用于依赖管理和命令执行
  • GitHub Copilot CLI, 已登录
  • git, curl,和 jq

⚠️ 对于本技术路线,您 不需要 .NET SDK。Python SDK 包名为 github-copilot-sdk 版本 1.0.9,导入时使用 copilot,项目在 pyproject.toml 中锁定。

步骤 1 — 克隆并检查

git clone https://github.com/vicperdana/aigenius-copilotsdk-s5ep2.git
cd aigenius-copilotsdk-s5ep2

The Python 实现与 .NET 实现并存:

src/AgentOrchestrator-python/

阅读 Python 技术路线概览,以获取完整的地图:

src/AgentOrchestrator-python/README.md

它镜像了 .NET 应用的每个功能:相同的 API 契约、相同的种子数据、相同的故意代码异味,以及相同的 GitHub Copilot SDK 学习路径。

⚠️ 选择一个技术路线。 您可以单独工作于 Python 或 .NET 而无需安装两者。它们也可以同时运行,因为端口不重叠:.NET 使用 5050 和 5051,而 Python 使用5070 用于 API 和 UI。

步骤 2 — 恢复依赖

从仓库根目录:

cd src/AgentOrchestrator-python
uv sync

uv sync 创建虚拟环境并安装应用程序依赖项、开发依赖项、FastAPI、SQLModel、pytest、ruff 和 GitHub Copilot SDK。

⚠️ 除非命令明确要求你改变目录,否则请在 src/AgentOrchestrator-python 中运行 Python 命令。没有解决方案文件,也没有根级别的 Python 包可以运行。

步骤 3 — 运行测试

uv run pytest

为了紧凑的 CI 风格检查:

uv run pytest -q

预期结果:30个测试通过。一个验证运行产生了:

..............................                                           [100%]
30 passed in 0.61s

这是14个领域测试和12个MCP服务器测试——两者一一对应.NET套件——再加上4个仅限Python的契约测试,以保护浏览器/API请求的结构。

记得那个数字。后面的实验会要求你在不破坏这30个测试的情况下扩展行为。

第 4 步 — 运行 代码检查器

uv run ruff check .

预期结果:

All checks passed!

The linter 配置位于 pyproject.toml

步骤 5 — 启动 API 和 UI

In你的第一个终端:

uv run uvicorn app.main:app --port 5070

打开 http://localhost:5070。你应该看到空的聊天界面:

零售分析助手的聊天界面在空状态时:一个带有模型下拉菜单(设置为Claude Haiku 4.5)、欢迎标题、五个建议的零售问题以及位于底部的消息输入框的暗色头部。

⚠️ 与 .NET 路线不同,没有 单独的 UI 服务器。FastAPI 从同一个进程的端口 5070 上提供 REST API、聊天流、静态 HTML 和 JavaScript。

💡 为什么不是5060,而是5070? Chrome、Edge 和 Firefox 拒绝打开端口5060 — 这是SIP端口,并且位于浏览器禁止访问的端口列表中,因此页面 ERR_UNSAFE_PORT 即使 curl 也能够正常工作。如果更改端口,请避免使用5060、5061和6000。

对于编辑刷新开发,添加 --reload:

uv run uvicorn app.main:app --port 5070 --reload

⚠️ 端口已被占用? 之前的运行可能仍然在监听5070端口并提供过期代码。在重启之前,请先停止监听5070端口的进程。

第 6 步 — 验证健康端点

In另一个终端,仍然来自src/AgentOrchestrator-python

curl http://localhost:5070/api/chat/health

预期结果:

{"status":"healthy","service":"CopilotChat","availableModels":["claude-haiku-4.5","gpt-4.1","gpt-5","claude-sonnet-4.5","claude-opus-4.5","gemini-2.5-pro"]}

这个端点不会调用模型。它证明了应用程序是可用的,并展示了如果实时模型发现失败使用的静态恢复目录。

第 7 步 — 验证 REST API

The Python API 保持与 .NET 一样的驼峰式 JSON 契约。这意味着 customerId, productCategory, 和 topFeatures, 不是 Python 内部的 customer_id, product_category, 和 top_features

运行:

curl -s http://localhost:5070/api/transactions | jq 'length'
curl -s http://localhost:5070/api/segments | jq 'length'
curl http://localhost:5070/api/segments/predict/C003

预期事实:

  • GET /api/transactions 返回 10 行
  • GET /api/segments 返回4行数据
  • 预测调用返回:
{"customerId":"C003","predictedSegment":"High Value","confidence":0.89,"topFeatures":["high_total_spend","multi_category","total_1700"]}

那个驼峰格式的契约已经在 app/models.py 所以相同的 curl 示例适用于所有技术路线。

第 8 步 — 验证流式传输工作

This证明了Copilot SDK已连接,CLI已登录,并且API可以将模型输出流式传输回浏览器或终端。

curl -sN -X POST http://localhost:5070/api/chat/stream \
  -H 'Content-Type: application/json' \
  -d '{"prompt":"Reply with exactly: streaming works","model":"claude-haiku-4.5"}'

预期的流式传输结构:

data: {"content": "streaming works"}

data: [DONE]

三件事情很重要:每个事件开始时都有data:,每个事件后面跟着一个空行,流结束时以data: [DONE]结尾。

⚠️ 该字段是 prompt,而不是 message。未识别的键会被忽略,因此一个拼写错误会导致发送一个空的提示,你将收到一个通用的问候而不是一个错误。

⚠️ 如果您看到 data: {"error": "..."} ,服务器已经接收到 SDK,但 SDK 无法完成请求。常见的原因包括未登录到 Copilot CLI 或选择了您账户无法使用的模型。

步骤 9 — 验证 SDK 实验样本

每个后来的 Python SDK 实验都使用该模块。现在运行一个真实的示例: sdk_labs 模块。Run one real sample now:

uv run python -m sdk_labs tools

预期结果:

== Lab 03: tools ==

Model: claude-haiku-4.5
Prompt: How much has customer C003 spent in total?

  [tool] get_customer_total(C003) -> $1,700.00

Assistant: Customer C003 has spent a total of **$1,700.00** across 2 transactions.

命令分发器位于 sdk_labs/__main__.py. 后续实验使用 uv run python -m sdk_labs events, uv run python -m sdk_labs sessions以及 uv run python -m sdk_labs mcp.

第 10 步 —— 测试 UI

在浏览器中打开http://localhost:5070,打开模型下拉菜单并发送一条消息以观看SSE渲染路径。

💡 产品请求体使用了 prompt,匹配 ChatRequest。一个早期版本在这里发布的是 message;由于 Pydantic 漏失了未知的键,UI 流式传输了一个空提示的回复,并且没有任何内容大声失败。现在 tests/test_chat_contract.py 断言字段 app.js 发送的是 API 读取的字段。

✅ 检查点

你现在应该已经拥有:

  • [x] Python依赖恢复完成 uv sync
  • [x] 30/30 测试通过
  • [x] 通过摇晃
  • [x] API 和 UI 在端口 5070 上一起运行
  • [x] REST endpoints 返回 seeded camelCase 数据
  • [x] 一个来自真实模型的真实流式传输响应
  • [x] The SDK 实验样本可通过 uv run python -m sdk_labs ...

💡 拓展练习

查询模型端点,并统计您的账户提供的内容:

curl -s http://localhost:5070/api/chat/models | jq 'length'

然后检查 fallback catalog 在 app/routers/chat.py. The live list 是真相的来源;Lab 02 解释了为什么静态列表只是 fallback。