Python AI 项目:uv 与阿里云百炼

AI Agent 工程实践教程 · 第 01 章

搭建 Python AI 工程环境,理解 uv 项目管理和百炼 API 的最小接入方式。

返回系列目录

Python AI 项目实战:使用 uv 和阿里云百炼调用大模型

1. 为什么 AI 适合用 Python

学习 AI 应用开发,很多项目都会从 Python 开始。

原因不是 Python 语法最特别,而是它在 AI 领域的生态比较成熟。

可以从三个角度理解:

原因 说明
大模型平台支持多 百炼、OpenAI、Claude、Gemini、DeepSeek 等平台通常都提供 Python SDK 或 Python 调用示例
AI 开发生态完整 数据处理、向量数据库、RAG、Agent、模型评测等方向都有大量 Python 工具
适合做 AI 项目原型 可以先用 Python 跑通模型调用、知识库问答、工具调用等核心流程,再接入 Web 或后台系统

所以这节课会先用 Python 做一个最小 AI 项目:

Python 程序 + 百炼 API + 一个可运行的 AI 对话 Demo。


2. uv 是什么

uv 是一个 Python 项目和依赖管理工具。

先用大白话理解:

做 Python 项目时,经常要安装很多第三方库。不同项目需要的库不一样,如果都装在同一个地方,很容易互相影响。uv 就是帮我们把“项目环境”和“项目依赖”管理清楚的工具。

比如:

  • 这个 AI 项目需要 openai
  • 另一个数据分析项目需要 pandas
  • 还有一个老项目可能需要旧版本的库

如果不管理环境,后面很容易出现:

  • 明明昨天能跑,今天装了别的库就报错
  • 同一个库,不同项目需要不同版本
  • 换一台电脑后,不知道应该安装哪些依赖

Python 里常见的环境和依赖管理方式有这些:

| 工具/方式 | 通俗理解 | 常见用途 | | --- | --- | | pip | Python 最基础的安装工具 | 安装第三方库,比如 pip install openai | | venv | Python 自带的虚拟环境工具 | 给每个项目单独建一个环境 | | requirements.txt | 传统依赖清单 | 记录项目需要安装哪些库 | | conda | 更偏数据科学/机器学习的一套环境管理工具 | 常用于 Anaconda、数据分析、深度学习环境 | | uv | 新一代 Python 项目和依赖管理工具 | 创建项目、管理环境、安装依赖、运行代码 |

如果学过 Java,可以把 uv 粗略类比成 Python 项目里的 Maven。

这个类比不完全一样,但能帮助理解:

Java 项目 Python + uv 项目 类比理解
pom.xml pyproject.toml 记录项目配置和依赖
Maven 下载依赖 uv add 安装依赖 把项目需要的库加进来
Maven 管理项目构建 uv 管理项目环境和运行 让项目更容易被别人复现
mvn test / mvn package uv run 运行命令 在项目环境里执行代码或工具

区别是:Maven 主要服务 Java 项目的构建和依赖管理;uv 主要服务 Python 项目的虚拟环境、依赖安装和命令运行。

这节课选择 uv,是因为它把很多步骤合在了一起:

过去可能要分开做 使用 uv 后
创建虚拟环境 uv 自动处理
安装依赖 uv add
记录依赖 写入 pyproject.toml
在项目环境里运行代码 uv run

课堂上先记住三个命令:

uv init 项目名
uv add 依赖名
uv run python Python文件

3. 创建第一个 Python AI 项目

如果使用 PyCharm,可以按下面的方式创建项目。

3.1 使用 PyCharm 创建项目

现在新版 PyCharm 已经可以直接用 uv 创建 Python 项目。

打开 PyCharm 后:

  1. 打开 PyCharm
  2. 选择 New Project
  3. 左侧选择 Pure Python
  4. Location 选择项目位置,项目名填写 YanQue-AI
  5. Interpreter type 选择 uv
  6. Python version 先保持 Default
  7. Path to uv 显示绿色对勾,说明 PyCharm 已经找到 uv
  8. 点击 Create

创建完成后,PyCharm 会在项目目录下创建 .venv 虚拟环境。

可以把它理解成:

  • PyCharm 负责创建项目
  • uv 负责创建和管理 Python 环境
  • 后面安装依赖、运行程序,都可以继续在 PyCharm 下面的 Terminal 里完成

如果不用 PyCharm,也可以用命令创建同样的项目:

uv init YanQue-AI

然后再用 PyCharm 打开这个 YanQue-AI 文件夹。

3.2 项目目录长什么样

用 PyCharm 直接选择 uv 创建项目后,项目里一般会看到这些内容:

YanQue-AI/
├── .venv/
├── pyproject.toml
└── main.py

其中:

文件 作用
.venv/ 当前项目自己的 Python 虚拟环境,依赖包会安装到这里
pyproject.toml 项目配置和依赖
main.py 默认入口代码,刚开始可以先不写业务逻辑

这里先知道两个文件:

  • main.py:项目默认入口,后面真正做完整项目时再用
  • pyproject.toml:记录项目依赖和项目配置

.venv 一般不用手动修改,知道它是项目环境就可以。

3.3 在 PyCharm 里运行项目

如果 main.py 里有默认示例代码,可以在 PyCharm 终端里执行:

uv run python main.py

如果能正常输出内容,说明项目环境已经能跑起来。

后面所有 uv adduv run 命令,都可以直接在 PyCharm 下方的 Terminal 里执行。


4. 安装项目依赖

使用 OpenAI 兼容方式调用百炼模型。

阿里云百炼支持 OpenAI 兼容接口,也就是说:我们可以使用 Python 的 openai SDK 调用百炼模型。

安装依赖:

uv add openai python-dotenv

这两个依赖分别负责:

依赖 作用
openai 用 OpenAI 兼容方式调用百炼接口
python-dotenv .env 文件读取环境变量

安装完成后,pyproject.toml 里会出现这些依赖。


5. 准备阿里云百炼 API Key

打开百炼控制台:

阿里云百炼 API 页面

在控制台里需要关注三个信息:

信息 用途
API Key 程序调用模型时的身份凭证
Base URL 接口地址
Model 要调用的模型名称

不要把 API Key 写死在代码里。

推荐新建一个 .env 文件:

touch .env

.env 里写入:

BAILIAN_API_KEY=你的百炼API_KEY
BAILIAN_BASE_URL=your_placeholder
BAILIAN_MODEL=your_placeholder

说明:

  • BAILIAN_API_KEY:换成你自己的百炼 API Key
  • BAILIAN_BASE_URL:OpenAI 兼容接口地址
  • BAILIAN_MODEL:可以先用 qwen-plus

6. 第一个模型调用测试

这一步先写一个简单的测试文件,确认百炼接口能正常调用。

在项目里新建一个 test 目录,再新建一个 bailian_api_test.py 文件:

YanQue-AI/
└── test/
    └── bailian_api_test.py

test/bailian_api_test.py 写成下面这样:

import os

from dotenv import load_dotenv
from openai import OpenAI


load_dotenv()


api_key = your_placeholder"BAILIAN_API_KEY")
base_url = os.getenv("BAILIAN_BASE_URL")
model = os.getenv("BAILIAN_MODEL", "qwen-plus")


if not api_key:
    raise RuntimeError("请先在 .env 文件中配置 BAILIAN_API_KEY")


client = OpenAI(
    api_key=your_placeholder
    base_url=base_url,
)


response = client.chat.completions.create(
    model=model,
    messages=[
        {"role": "system", "content": "你是一个耐心的 AI 课程助教。"},
        {"role": "user", "content": "用一句话解释什么是大模型。"},
    ],
)


answer = response.choices[0].message.content
print("AI 回复:")
print(answer)

运行:

uv run python test/bailian_api_test.py

如果配置正确,终端会输出模型回答。


7. 这段代码做了什么

先不要急着背代码。

可以把这段程序理解成 5 步:

步骤 代码做的事
1 .env 读取 API Key、接口地址和模型名
2 创建一个 OpenAI 兼容客户端
3 准备 system 和 user 消息
4 调用百炼大模型接口
5 取出模型回复并打印

这里最重要的是 messages

messages=[
    {"role": "system", "content": "你是一个耐心的 AI 课程助教。"},
    {"role": "user", "content": "用一句话解释什么是大模型。"},
]

可以先这样理解:

role 含义
system 给模型设定身份、规则和边界
user 用户提出的问题
assistant 模型之前的回答

后面做多轮对话时,会把历史消息继续放进 messages


8. 加入多轮对话

第一个测试程序只能问一次。

现在可以再建一个测试文件:

test/chat_loop_test.py

这个文件用来测试“多轮对话”。

test/chat_loop_test.py 写成下面这样:

import os

from dotenv import load_dotenv
from openai import OpenAI


load_dotenv()


api_key = your_placeholder"BAILIAN_API_KEY")
base_url = os.getenv("BAILIAN_BASE_URL")
model = os.getenv("BAILIAN_MODEL", "qwen-plus")


if not api_key:
    raise RuntimeError("请先在 .env 文件中配置 BAILIAN_API_KEY")


client = OpenAI(
    api_key=your_placeholder
    base_url=base_url,
)


messages = [
    {
        "role": "system",
        "content": "你是一个 AI 课程助教,回答要清楚、简洁,适合零基础学生。",
    }
]


print("AI 助手已启动,输入 exit / quit / 退出 都可以结束。")


while True:
    user_input = input("\n你:")

    if user_input.strip().lower() in {"exit", "quit", "退出"}:
        print("已退出。")
        break

    messages.append({"role": "user", "content": user_input})

    response = client.chat.completions.create(
        model=model,
        messages=messages,
    )

    answer = response.choices[0].message.content
    messages.append({"role": "assistant", "content": answer})

    print("\nAI:")
    print(answer)

运行:

uv run python test/chat_loop_test.py

可以连续输入:

什么是大模型?
那它和普通程序有什么区别?
能不能举一个客服系统的例子?

这个版本已经具备最基础的多轮对话能力。


9. 加入流式输出

真实 AI 产品里,模型通常不是等全部生成完再显示,而是一边生成一边显示。

这叫流式输出。

把多轮对话里的调用部分改成:

stream = client.chat.completions.create(
    model=model,
    messages=messages,
    stream=True,
)

answer_parts = []

print("\nAI:", end="")
for chunk in stream:
    delta = chunk.choices[0].delta.content
    if delta:
        print(delta, end="")
        answer_parts.append(delta)

answer = "".join(answer_parts)
messages.append({"role": "assistant", "content": answer})

流式输出的体验更接近 ChatGPT、通义、豆包这类产品。


10. FastAPI 是什么

前面我们已经能在 Python 文件里调用大模型了。

但真实项目里,AI 能力通常不会只在命令行里运行,而是会做成一个接口,让网页、后台系统、小程序或其他服务来调用。

这时候就可以用 FastAPI

FastAPI 是一个 Python Web 框架,可以用来快速开发接口。

可以先这样理解:

内容 作用
Python 函数 写具体业务逻辑
FastAPI 接口 把 Python 函数变成可以被外部访问的 HTTP 接口
浏览器或前端 通过接口调用后端能力

比如:

  • Python 代码负责调用百炼大模型
  • FastAPI 负责提供 /chat 接口
  • 前端页面或其他系统向 /chat 发送问题
  • 后端调用大模型后,把回答返回给前端

FastAPI 里常见两个对象:

对象 作用
FastAPI() 创建整个 Web 应用
APIRouter() 创建一组接口,方便把接口按模块管理

可以先这样理解:

  • app = FastAPI():整个后端服务
  • router = APIRouter():某一组接口
  • app.include_router(router):把这组接口挂到整个服务上

11. 安装 FastAPI

继续在 PyCharm 终端里安装依赖:

uv add fastapi uvicorn

这两个依赖分别负责:

依赖 作用
fastapi 用来编写 Web 接口
uvicorn 用来启动 FastAPI 服务

安装完成后,pyproject.toml 里会出现 fastapiuvicorn


12. 方式一:写一个最简单的 FastAPI 接口

先用最简单的方式演示。

在项目根目录新建一个 app.py 文件:

YanQue-AI/
├── .env
├── app.py
├── pyproject.toml
└── test/
    └── bailian_api_test.py

app.py 里写入:

import os

from dotenv import load_dotenv
from fastapi import FastAPI
from openai import OpenAI
from pydantic import BaseModel


load_dotenv()


api_key = your_placeholder"BAILIAN_API_KEY")
base_url = os.getenv("BAILIAN_BASE_URL")
model = os.getenv("BAILIAN_MODEL", "qwen-plus")


if not api_key:
    raise RuntimeError("请先在 .env 文件中配置 BAILIAN_API_KEY")


client = OpenAI(
    api_key=your_placeholder
    base_url=base_url,
)


app = FastAPI()


class ChatRequest(BaseModel):
    question: str


@app.get("/")
def index():
    return {"message": "YanQue AI 服务已启动"}


@app.post("/chat")
def chat(request: ChatRequest):
    response = client.chat.completions.create(
        model=model,
        messages=[
            {"role": "system", "content": "你是一个耐心的 AI 课程助教。"},
            {"role": "user", "content": request.question},
        ],
    )

    answer = response.choices[0].message.content
    return {"answer": answer}

这段代码里有两个接口:

接口 作用
GET / 测试服务是否启动
POST /chat 接收用户问题,调用大模型并返回回答

这个版本最适合第一次上课演示,因为代码都在一个文件里。

启动命令:

uv run uvicorn app:app --reload

这里的 app:app 可以拆成两部分:

app : app
  • 前面的 app:表示 app.py 这个文件
  • 后面的 app:表示文件里的 app = FastAPI() 这个对象

13. 方式二:多个 API 文件用 APIRouter 管理

项目稍微大一点时,通常会把代码放到 src 目录下。

如果有多个 API 文件,可以让每个 API 文件定义自己的 router,再在 main.py 里统一加载。

目录可以这样放:

YanQue-AI/
├── .env
├── app.py
├── pyproject.toml
├── src/
│   └── yanque_ai/
│       ├── main.py
│       └── api/
│           ├── chat_api.py
│           └── health_api.py
└── test/
    └── bailian_api_test.py

可以先这样理解:

文件 作用
src/yanque_ai/main.py FastAPI 主入口,统一加载所有 router
src/yanque_ai/api/health_api.py 健康检查接口,比如 /
src/yanque_ai/api/chat_api.py AI 对话接口,比如 /chat

src/yanque_ai/api/health_api.py 里写入:

from fastapi import APIRouter


router = APIRouter()


@router.get("/")
def index():
    return {"message": "YanQue AI 服务已启动"}

src/yanque_ai/api/chat_api.py 里写入:

import os

from dotenv import load_dotenv
from fastapi import APIRouter
from openai import OpenAI
from pydantic import BaseModel


load_dotenv()


api_key = your_placeholder"BAILIAN_API_KEY")
base_url = os.getenv("BAILIAN_BASE_URL")
model = os.getenv("BAILIAN_MODEL", "qwen-plus")


if not api_key:
    raise RuntimeError("请先在 .env 文件中配置 BAILIAN_API_KEY")


client = OpenAI(
    api_key=your_placeholder
    base_url=base_url,
)


router = APIRouter()


class ChatRequest(BaseModel):
    question: str


@router.get("/")
def index():
    return {"message": "YanQue AI 服务已启动"}


@router.post("/chat")
def chat(request: ChatRequest):
    response = client.chat.completions.create(
        model=model,
        messages=[
            {"role": "system", "content": "你是一个耐心的 AI 课程助教。"},
            {"role": "user", "content": request.question},
        ],
    )

    answer = response.choices[0].message.content
    return {"answer": answer}

src/yanque_ai/main.py 里统一加载这些 router:

from fastapi import FastAPI

from yanque_ai.api.chat_api import router as chat_router
from yanque_ai.api.health_api import router as health_router


app = FastAPI()


app.include_router(health_router)
app.include_router(chat_router)

其中:

  • health_api.py 负责健康检查相关接口
  • chat_api.py 负责 AI 对话相关接口
  • 每个 API 文件都有自己的 router = APIRouter()
  • main.py 通过 app.include_router(...) 把多个 router 加到同一个 FastAPI 应用里

启动命令:

uv run uvicorn yanque_ai.main:app --reload

这里的 yanque_ai.main:app 可以拆成两部分:

yanque_ai.main : app
  • 前面的 yanque_ai.main:表示 src/yanque_ai/main.py 这个模块
  • 后面的 app:表示文件里的 app = FastAPI() 这个对象

14. 访问 FastAPI 服务

无论使用方式一还是方式二,只要服务启动成功,终端都会看到类似这样的地址:

http://127.0.0.1:8000

打开浏览器访问:

http://127.0.0.1:8000

如果看到下面的内容,说明服务已经启动:

{"message":"YanQue AI 服务已启动"}

FastAPI 还会自动生成接口文档。

打开:

http://127.0.0.1:8000/docs

找到 POST /chat,点击 Try it out,输入:

{
  "question": "用一句话解释什么是大模型"
}

点击 Execute,就可以看到大模型返回的回答。