使用 AgentScope 将智能体应用部署为 Knative 服务

更新时间:
复制 MD 格式

AgentScope 框架开发的智能体应用一键式部署到ACK Knative 环境中后,可利用 Knative 的自动扩缩容(缩容至0)、版本管理等 Serverless 能力,实现 AI 智能体的快速、弹性与低成本托管。

工作原理

agentscope deploy knative 命令封装了将智能体应用容器化并部署到集群的复杂流程。其核心工作流程如下:

  1. 打包应用:将指定的 Python 智能体应用代码、依赖项(requirements.txt)和环境变量打包。

  2. 构建镜像:基于指定的基础镜像,在本地 Docker 环境中构建一个包含智能体应用的容器镜像。

  3. 推送镜像:将构建好的镜像推送到指定的容器镜像仓库,如ACR

  4. 部署服务:在目标集群中,生成并应用一个 Knative Service(ksvc)资源清单。Knative 会根据此清单创建 Deployment 和 Pod,并自动配置网络路由、负载均衡和自动伸缩策略。

准备工作

  • 已在集群中部署Knative组件

  • 本地已安装并运行 Docker,用于构建容器镜像。

  • 已通过 pip 命令安装 AgentScope Runtime。

    # 基础安装
    pip install agentscope-runtime>=1.1.0
    # Kubernetes部署依赖
    pip install "agentscope-runtime[ext]>=1.1.0"

步骤一:创建智能体项目

如当前未准备智能体应用,可参见下方示例文件结构和代码。

  1. 创建项目目录结构:

    my-agent-project/
    ├── app_agent.py          # 智能体应用主文件
    ├── requirements.txt      # Python 依赖(可选)
    └── .env                  # 环境变量(可选)
  2. app_agent.py 文件中编写智能体代码。

    下方代码创建了一个使用千问模型,具备代码执行和多轮对话能力的智能体。
    # -*- coding: utf-8 -*-
    import os
    from contextlib import asynccontextmanager
    from fastapi import FastAPI
    from agentscope.agent import ReActAgent
    from agentscope.formatter import DashScopeChatFormatter
    from agentscope.model import DashScopeChatModel
    from agentscope.pipeline import stream_printing_messages
    from agentscope.tool import Toolkit, execute_python_code
    from agentscope.memory import InMemoryMemory
    from agentscope.session import JSONSession
    from agentscope_runtime.engine.app import AgentApp
    from agentscope_runtime.engine.schemas.agent_schemas import AgentRequest
    @asynccontextmanager
    async def lifespan(app: FastAPI):
        """初始化服务。"""
        app.state.session = JSONSession(
            save_dir="./",  # 保存所有session文件的目录
        )
        try:
            yield
        finally:
            print("AgentApp is shutting down...")
    # 创建 AgentApp
    agent_app = AgentApp(
        app_name="MyAssistant",
        app_description="A helpful assistant agent",
        lifespan=lifespan,
    )
    @agent_app.query(framework="agentscope")
    async def query_func(
        self,
        msgs,
        request: AgentRequest = None,
        **kwargs,
    ):
        """处理用户查询。"""
        session_id = request.session_id
        user_id = request.user_id
        # Create toolkit with Python execution
        toolkit = Toolkit()
        toolkit.register_tool_function(execute_python_code)
        # Create agent
        agent = ReActAgent(
            name="MyAssistant",
            model=DashScopeChatModel(
                "qwen-turbo",
                api_key=os.getenv("DASHSCOPE_API_KEY"),
                enable_thinking=True,
                stream=True,
            ),
            sys_prompt="You're a helpful assistant.",
            toolkit=toolkit,
            memory=InMemoryMemory(),
            formatter=DashScopeChatFormatter(),
        )
        agent.set_console_output_enabled(False)
        await agent_app.state.session.load_session_state(
            session_id=session_id,
            user_id=user_id,
            agent=agent,
        )
        async for msg, last in stream_printing_messages(
            agents=[agent],
            coroutine_task=agent(msgs),
        ):
            yield msg, last
        await agent_app.state.session.save_session_state(
            session_id=session_id,
            user_id=user_id,
            agent=agent,
        )
    if __name__ == "__main__":
        agent_app.run()

步骤二:部署智能体应用

使用 agentscope deploy 命令将本地的智能体应用一键部署为 Knative 服务。

  1. 执行部署命令。

    进入 my-agent-project 目录,参见以下示例部署服务。

    DASHSCOPE_API_KEY替换为实际值。
    agentscope deploy knative app_agent.py \
      --image-name agent_app \
      --env DASHSCOPE_API_KEY=sk-xxx \
      --image-tag linux-amd64-18 \
      --registry-url registry.cn-hangzhou.aliyuncs.com \
      --base-image registry.cn-hangzhou.aliyuncs.com/knative-sample/python:3.10-slim-bookworm \
      --registry-namespace knative-sample \
      --namespace default \
      --push

    展开查看命令语法说明

    agentscope deploy knative SOURCE [OPTIONS]
    • SOURCE:Python 文件路径,如 app_agent.py

    • [OPTIONS]:常用参数如下:

      更多参数,可执行 agentscope deploy knative --help 查看。

      参数

      类型

      默认值

      说明

      --namespace

      string

      agentscope-runtime

      指定部署智能体的命名空间。

      --kube-config-path-c

      path

      None

      指定连接集群的 KubeConfig 文件路径。若不指定,则使用默认路径。

      --port

      integer

      8080

      指定智能体应用在容器内监听的端口。

      --image-name

      string

      agent_app

      为智能体应用构建的容器镜像名称。

      --image-tag

      string

      linux-amd64

      为智能体应用构建的容器镜像标签。

      --registry-url

      string

      localhost

      推送镜像的目标容器镜像仓库地址,例如 registry.cn-hangzhou.aliyuncs.com

      --registry-namespace

      string

      agentscope-runtime

      在容器镜像仓库中使用的命名空间(或项目)。

      --push

      flag

      False

      添加此标志以将构建的镜像推送到远程仓库。部署到远程集群时通常需要开启。

      --base-image

      string

      python:3.10-slim-bookworm

      用于构建应用的基础镜像,需包含 Python 环境。

      --requirements

      string

      None

      指定应用的 Python 依赖。可以是一个 requirements.txt 文件路径,或用逗号分隔的包列表。

      --cpu-request

      string

      200m

      设置 Pod 的 CPU 资源请求。单位为 m(千分之一核)或整数核,例如 200m1

      --cpu-limit

      string

      1000m

      设置 Pod 的 CPU 资源限制。例如 1000m2

      --memory-request

      string

      512Mi

      设置 Pod 的内存资源请求。单位通常为 Mi 或 Gi,例如 512Mi1Gi

      --memory-limit

      string

      2Gi

      设置 Pod 的内存资源限制。例如 2Gi4Gi

      --image-pull-policy

      choice

      IfNotPresent

      设置 Pod 的镜像拉取策略。可选值为 AlwaysIfNotPresentNever

      --deploy-timeout

      integer

      300

      等待 Knative 服务部署成功的超时时间,单位为秒。

      --health-check

      flag

      None

      添加此标志以在 Knative 服务中启用健康检查。

      --platform

      string

      linux/amd64

      指定构建镜像的目标硬件平台,例如 linux/amd64 或 linux/arm64

      --pypi-mirror

      string

      None

      指定安装 Python 包时使用的 PyPI 镜像源,例如 https://pypi.tuna.tsinghua.edu.cn/simple

  2. 查看部署结果。

    部署成功后,终端将输出服务的访问 URL 等信息。记录此处的URL信息,供下一步访问服务。

    Deployment successful!
    Deployment ID: d4b4a54d-9976-443c-a1da-a77643******
    Resource Name: agent-d4b4*****
    URL: http://agent-03e*****.default.example.com
    Namespace: default

步骤三:访问已部署的智能体

  1. 获取访问网关。

    1. ACK集群列表页面,单击目标集群名称,在集群详情页左侧导航栏,选择应用 > Knative

    2. 服务管理组件管理页面,获取访问网关

      页面底部显示访问网关的 IP 地址(例如 120.xxx.159)。服务访问前,需将访问服务的域名与访问网关进行 Host 绑定。

  2. 通过 curl 命令向智能体服务发送请求。

    将下文中 115.29.xxx.xxx 替换为 Knative 访问网关;将 Host 替换为此前获取的访问 URL。
    curl -i -X POST "http://115.29.xxx.xxx:80/process" \
      -H "Content-Type: application/json" \
      -H "Host: agent-03e*****.default.example.com" \
      -d '{
        "input": [
          {
            "role": "user",
            "content": [
              {
                "type": "text",
                "text": "Hello, how are you?"
              }
            ]
          }
        ],
        "session_id": "123"
      }'
  3. 查看返回结果,包含智能体思考过程和最终计算结果的流式响应。

步骤四:观察自动扩缩容

  • 自动缩容:在一段时间没有请求后,Knative 会自动将该服务的 Pod 数量缩减为 0,以节省资源。可通过以下命令观察 Pod 的变化。

    # 持续观察指定命名空间下的 Pod
    kubectl get pods -n default -w

    也可在Knative页面单击服务管理,然后单击服务名称,在页面下方查看当前版本的 Pod 运行情况。

    修订版本信息页签下,当前修订版本的 Ready/requested pods 列显示为 0/0,确认 Pod 已缩容到零。

  • 自动扩容:当有新请求到达时,Knative 会在数秒内自动启动新的 Pod 来处理请求。

生产环境使用建议

  • 状态持久化:示例代码中的 InMemoryStateServiceInMemorySessionHistoryService 会在 Pod 重启后丢失所有状态和对话历史,不适用于生产环境。生产部署时,应切换为基于 Redis 或其他持久化存储的实现方案。

  • 密钥管理:避免在命令行中直接传递或在代码中硬编码 API_KEY 等敏感信息。推荐使用 Kubernetes Secrets,并通过 Knative Service 的配置将其作为环境变量挂载到容器中。

  • 资源规划:根据业务负载,通过压力测试评估并合理配置 --cpu-request--cpu-limit--memory-request--memory-limit 等参数,确保服务的性能和稳定性。

  • 可观测性:配置日志收集(如 ACK 的日志服务)和监控告警(如 ARMS),以便于排查问题和掌握服务运行状况。

相关操作

  • 更新智能体:修改代码后,使用新的镜像标签(例如 --image-tag v1.1)重新执行 agentscope deploy knative 命令即可实现滚动更新。

  • 卸载智能体:

    # 将 resource-name 和 namespace 替换为您的实际值
    kubectl delete ksvc <resource-name> -n <namespace>
    此操作仅删除 Kubernetes 中的服务,不会删除推送至镜像仓库的容器镜像。