如何使用LangGraph、LangServe和AWS构建和部署AI代理

2024年10月28日 由 alex 发表 122 0

人工智能代理代表了人工智能的下一个进化阶段,超越了传统AI聊天机器人的能力。虽然聊天机器人在管理简单对话方面表现出色,但人工智能代理通过利用多个大型语言模型(LLM)来执行复杂、多步骤的任务,从而更进一步。这些代理可以在交互过程中保持上下文,动态适应新信息,并实时做出决策,提供更复杂和智能的解决方案。LangGraph作为LangChain库的扩展,通过引入循环工作流,使这些高级代理能够不断发展,从而使代理能够根据对话或流程的不断变化状态持续调整其操作。


在本文中,我将指导你使用LangGraph、LangServe和AWS Copilot构建和部署一个人工智能代理。我们将创建一个实际用例:一家太阳能板公司的客户支持聊天机器人,它不仅回答客户咨询,还根据用户输入计算节能情况。最后,你将拥有一个可完全部署的人工智能代理,该代理集成了多个AI模型,并可通过AWS无缝扩展。


接下来,让我们开始设置环境并准备将AI代理部署到实际应用中。


环境设置

为了开始构建和部署你的AI代理,第一步是在Visual Studio Code中设置环境。为此,我们将创建一个Python虚拟环境,以确保项目内所有依赖项都被整齐地包含。


# create virtual environment
python -m venv env
# activate virtual environment
source env/bin/activate
# install required dependencies
pip install -r requirements.txt


这将安装与LangGraph、LangServe、AWS以及其他相关包一起工作所需的所有库。


启动LangServe应用程序

首先,我们需要设置LangServe应用程序,它将负责将你的AI代理部署为API。LangServe是一个专为将LangChain可运行文件和链部署为REST API而设计的工具。它与FastAPI集成,并使用Pydantic进行数据验证,提供有效处理请求的端点。


步骤1:创建LangServe应用

在你的项目目录中,通过运行以下命令来初始化一个新的LangServe应用:


langchain serve new .


这个命令为你的LangServe应用创建了基本结构,包括必要的文件和目录。在继续之前,重要的是要确保所有必需的依赖项都已正确安装。由于LangServe使用Poetry进行依赖管理,我们将使用它来配置和安装必要的包。


步骤2:设置Poetry依赖项

Poetry通过确保所有包都以结构化的方式正确安装和维护,从而简化了依赖管理。在你的项目目录的根目录下,你会找到pyproject.toml文件。更新它以包含以下依赖项:


[tool.poetry]
name = "ai-agent-deploy"
version = "0.1.0"
description = ""
authors = ["Your Name <you@example.com>"]
readme = "README.md"
packages = [
    { include = "app" },
]
[tool.poetry.dependencies]
python = ">=3.11,<3.13"
uvicorn = "^0.23.2"
langserve = {extras = ["server"], version = ">=0.0.30"}
pydantic = ">=2,<3"
langchain-core = ">=0.3.12,<0.4.0"
langgraph = ">=0.2.28,<0.3.0"
langchain = ">=0.3.3,<0.4.0"
langchain-aws = ">=0.2.2,<0.3.0"
langchain-community = ">=0.3.2,<0.4.0"
langchain-pinecone = ">=0.2.0,<0.3.0"
boto3 = ">=1.35.43,<1.36.0"
langchain-cli = ">=0.0.31,<0.1.0"

[tool.poetry.group.dev.dependencies]
langchain-cli = ">=0.0.15"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"


然后,运行以下命令来安装依赖项:


poetry install


随着基本的LangServe设置完成且必要的包已安装,我们现在可以继续使用LangGraph构建AI代理,并将其集成到LangServe应用程序中。


构建AI代理

在这一步中,我们将构建一个作为太阳能板公司客户支持聊天机器人的AI代理,它能够回答用户咨询并计算潜在的节能效果。


定义LangGraph工作流

在server.py文件中,我们将使用LangGraph来创建为AI代理提供动力的逻辑。LangGraph使用节点、边和状态来构建其工作流:

  • 节点:每个节点代表工作流中的一个步骤,如回应用户咨询或计算节能效果。
  • 边:这些边连接节点,定义对话或决策过程的流程。
  • 状态:状态维护对话的上下文,跟踪用户输入和之前的回复,以确保代理能够在交互过程中提供相关且连贯的回答。


初始化FastAPI应用程序

我们将首先初始化FastAPI应用程序,它将处理AI代理的传入请求。


# initiate FastAPI
app = FastAPI()


这设置了FastAPI应用程序,并准备将其用作用户和AI代理之间的接口。


定义根重定向到API文档

接下来,我们将添加一条路由,该路由将自动将访问API根目录(/)的用户重定向到FastAPI文档页面(/docs),从而更容易地浏览可用的端点。


@app.get("/")
async def redirect_root_to_docs():
    return RedirectResponse("/docs")


这确保了用户能够轻松找到并与API文档进行交互。


初始化内存并编译LangGraph

为了处理对话上下文,我们将为AI代理初始化内存。这使得代理能够记住之前的交互,并在多步对话中做出更智能的回应。然后,我们将编译LangGraph工作流,集成内存以在交互过程中保留上下文。


memory = MemorySaver()
graph = builder.compile(checkpointer=memory)


通过这种设置,AI代理现在可以处理请求,同时保留必要的对话上下文,从而确保在整个交互过程中提供有意义且连贯的回复。


使用Pydantic定义请求模型

为了确保传入的请求遵循特定的结构,我们将使用Pydantic来定义预期的数据格式。这有助于API自动验证输入,确保只有符合正确类型的数据(例如,问题为字符串类型,线程ID为整数类型)才会被接受。如果输入不符合定义的标准,则会生成清晰的错误消息。


class QuestionRequest(BaseModel):
    question: str
    thread_id: int


通过定义这个模型,我们确保了每个请求都是结构良好的,从而使API更加健壮和用户友好。


添加运行AI代理的主路由

现在结构和组件已经就绪,是时候通过定义主要的API路由来实现核心功能了。这个路由将处理用户请求,通过AI代理处理输入,并返回适当的响应。


这是通过为/generate端点设置一个POST请求处理程序来完成的。请求中提供的数据(如用户的问题和线程ID)将使用我们之前定义的Pydantic模型进行验证。验证后的输入被传递给AI代理,AI代理使用其LangGraph工作流进行处理。最终的输出以JSON格式返回。


它的工作原理如下:


@app.post("/generate")
async def generate_route(request: QuestionRequest):
    print(request)
    state = {"messages": [HumanMessage(content=request.question)]}
    config = {"configurable": {"thread_id": request.thread_id}}
    try:
        outputs = []
        for output in graph.stream(state, config):
            print(output)
            for key, value in output.items():
                outputs.append({key: value})
        return {"result": outputs}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


/generate路由接受POST请求,请求体根据QuestionRequest Pydantic模型(即question和thread_id)进行结构化。

  • 状态(State):创建状态对象,其中包含从请求输入中获取的用户问题,并将其传递到AI代理的工作流中。这确保了AI代理正确处理用户的输入。
  • 配置(Config):配置对象包含thread_id,允许AI代理使用内存跟踪对话上下文。


接下来,AI代理使用LangGraph工作流处理状态和配置:

  • 处理(Processing):graph.stream方法实时流式传输AI代理工作流的输出,并将每个输出追加到outputs列表中。
  • 返回(Return):处理完成后,将输出作为JSON响应返回给用户。如果在执行过程中遇到任何问题,将抛出一个带有详细错误消息的500 HTTP错误。


此路由是与AI代理交互的主要入口点。一旦部署,用户可以发送他们的查询,AI代理将根据LangGraph中定义的工作流进行响应。


使用LangServe在本地测试AI代理

现在我们已经设置了代码,我们将运行LangServe应用程序以在本地测试AI代理。LangServe提供了通过REST API为基于LangChain的代理提供服务的基础设施。以下是如何在本地运行它并确保在部署之前一切正常工作的步骤。


运行LangServe

首先,确保Docker正在运行,因为LangServe依赖于它进行部署。


在项目目录中,运行以下命令以启动LangServe应用程序:


langchain serve


这条命令将启动一个托管你的AI代理API的本地服务器。LangServe将自动使用Docker启动一个环境,你将能够通过http://localhost:8000访问你的API。


访问API

一旦服务器运行,你可以打开浏览器并访问http://localhost:8000/docs。在这里,你将看到用于与AI代理交互的POST /generate路由。你可以通过点击该路由,然后点击“Try it out(试一下)”并填写所需字段(如问题和线程ID)来直接从此页面测试API。


31


既然你已经在本地测试了AI代理并确认一切按预期工作,下一步就是将其部署到云端。


使用AWS Copilot部署AI代理

既然我们已经成功地在本地测试了AI代理,现在是时候将其部署,以便可以公开访问。在本节中,我们将使用AWS Copilot来部署AI代理。AWS Copilot通过自动设置必要的基础设施,简化了部署像我们的AI代理(与LangServe一起运行)这样的容器化应用程序的过程。


第一步:设置AWS凭证

在部署应用程序之前,请确保你的AWS凭证已在本地计算机上正确设置。你需要AWS访问密钥,可以通过遵循AWS文档中的说明进行配置。为了确认,请检查你的主目录中是否有一个.aws文件夹,其中包含credentials和config文件。这些文件应安全地存储你的访问密钥ID和秘密访问密钥。


第二步:初始化AWS Copilot

在你的项目目录中,运行以下命令来初始化AWS Copilot:


copilot init \
--app ai-agent \
--name ai-agent \
--type 'Load Balanced Web Service' \
--dockerfile './Dockerfile' 


AWS Copilot将为你的AI代理创建几个关键组件:

  • 弹性负载均衡器(ELB):负载均衡器将传入流量分配到你的服务的多个实例上,以确保高可用性和容错性。这意味着随着流量的增长,ELB可以分散负载,防止任何单个实例过载,从而确保你的AI代理的平稳性能和可扩展性。
  • ECS(弹性容器服务):ECS是AWS用于部署和管理容器化应用程序的完全托管的容器编排服务。在这种情况下,ECS将在Docker容器内处理你的AI代理的运行、扩展和监控。它与ELB无缝协作,确保你的服务可以根据需求自动向上或向下扩展。


运行此命令后,AWS Copilot将开始为你的AI代理创建必要的基础设施。


在初始化过程中,AWS Copilot会要求你提供一个环境名称。通常,你会从开发环境开始,然后可以扩展到生产环境。一旦你设置了环境名称,Copilot就会开始为你的环境创建所有必要的资源。这可能需要几分钟时间,因为Copilot需要设置VPC(虚拟私有云)、负载均衡器和ECS集群。


第三步:修改manifest.yml文件

在这一步中,我们将修改manifest.yml文件,为你的AWS Copilot部署配置一些额外的设置。具体来说,我们将设置一个健康检查路径,并为Tavily API密钥添加一个环境变量。manifest.yml文件位于copilot/ai-agent文件夹中,定义了你的服务如何部署和配置。


要进行的修改:

  1. 健康检查路径:我们将健康检查端点更改为/docs。这样,AWS就可以通过检查这个特定路由来验证你的应用程序是否运行正常。
  2. Tavily API密钥:添加一个环境变量用于Tavily API密钥,该密钥将在部署期间传递给你的服务。这确保了API密钥能够安全地提供给你的应用程序。


以下是更新后的manifest.yml文件:


# The manifest for the "ai-agent" service.
# Read the full specification for the "Load Balanced Web Service" type at:
#  https://aws.github.io/copilot-cli/docs/manifest/lb-web-service/
# Your service name will be used in naming your resources like log groups, ECS services, etc.
name: ai-agent
type: Load Balanced Web Service
# Distribute traffic to your service.
http:
  # Requests to this path will be forwarded to your service.
  # To match all requests you can use the "/" path.
  path: "/"
  # You can specify a custom health check path. The default is "/".
  healthcheck: "/docs"
# Configuration for your containers and service.
image:
  # Docker build arguments. For additional overrides: https://aws.github.io/copilot-cli/docs/manifest/lb-web-service/#image-build
  build: Dockerfile
  # Port exposed through your container to route traffic to it.
  port: 8080
cpu: 256 # Number of CPU units for the task.
memory: 512 # Amount of memory in MiB used by the task.
platform: linux/x86_64 # See https://aws.github.io/copilot-cli/docs/manifest/lb-web-service/#platform
count: 1 # Number of tasks that should be running in your service.
exec: true # Enable running commands in your container.
network:
  connect: true # Enable Service Connect for intra-environment traffic between services.
# storage:
# readonly_fs: true       # Limit to read-only access to mounted root filesystems.
# Optional fields for more advanced use-cases.
#
variables: # Pass environment variables as key value pairs.
  TAVILY_API_KEY: "<YOUR API KEY>"
#secrets:                      # Pass secrets from AWS Systems Manager (SSM) Parameter Store.
#  GITHUB_TOKEN: GITHUB_TOKEN  # The key is the name of the environment variable, the value is the name of the SSM parameter.
# You can override any of the values defined above by environment.
#environments:
#  test:
#    count: 2               # Number of tasks to run for the "test" environment.
#    deployment:            # The deployment strategy for the "test" environment.
#       rolling: 'recreate' # Stops existing tasks before new ones are started for faster deployments.


第四步:添加Bedrock策略

为了让你的AI代理能够与AWS Bedrock模型(如Anthropic的模型)进行交互,你需要为你的服务附加适当的权限。在这一步中,我们将在copilot/ai-agent/addons文件夹中创建一个名为bedrock-policy.yml的策略文件。此策略授予AI代理调用AWS Bedrock模型所需的权限。


在copilot/ai-agent/addons文件夹中,创建一个新文件,命名为bedrock-policy.yml,并添加以下内容:


# You can use any of these parameters to create conditions or mappings in your template.
Parameters:
  App:
    Type: String
    Description: Your application name
  Env:
    Type: String
    Description: The environment name your service, job, or workflow is being deployed to
  Name:
    Type: String
    Description: Your workload name
Resources:
  BedrockAccessPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Sid: BedrockActions
            Effect: Allow
            Action:
              - bedrock:InvokeModel
              - bedrock:InvokeModelWithResponseStream
            Resource:
              - arn:aws:bedrock:*::foundation-model/anthropic.*

Outputs:
  # You need to output the IAM ManagedPolicy so that Copilot can add it
  # as a managed policy to your ECS task role.
  BedrockAccessPolicyArn:
    Description: "The ARN of the ManagedPolicy to attach to the task role."
    Value: !Ref BedrockAccessPolicy


第五步:部署AI代理

在环境配置完成且必要策略已经就绪后,现在是时候将AI代理部署到AWS上了。使用以下命令开始部署过程:


copilot deploy


此命令将启动将你的应用程序部署到AWS的过程。在此过程中,Copilot将执行以下操作:

  1. 构建并上传容器:你的应用程序将被打包为Docker容器并上传到Amazon Elastic Container Registry(ECR)。
  2. 启动服务:Copilot随后将创建在Amazon Elastic Container Service(ECS)上运行你的服务所需的基础设施。ECS负责管理容器化应用程序的部署、扩展和运行。
  3. 配置网络和负载均衡:Copilot将设置一个弹性负载均衡器(ELB),以将传入流量路由到你的服务,确保高可用性和容错性。
  4. 附加权限:任何所需的策略,如Bedrock访问策略,都将附加到你的ECS任务角色上,确保你的服务拥有与AWS Bedrock模型交互所需的权限。


这个部署过程可能需要几分钟时间,因为AWS Copilot需要配置和提供底层服务,如ECS、负载均衡器和安全组,以确保你的应用程序在生产环境中平稳运行。


如果在部署过程中遇到任何问题,你可以使用以下命令来检查日志并调试错误:


copilot svc log


此命令将显示来自已部署服务的日志,使你能够排查部署过程中出现的任何问题。此外,如果需要,你还可以访问AWS CloudFormation日志来调查底层基础设施的部署情况。


第六步:测试你的API

部署完成后,AWS Copilot将为你的AI代理提供一个公共URL。你现在可以打开浏览器并访问该URL,以访问FastAPI文档,网址为:https://<your-app-url>.aws.com/docs


在这里,你会看到POST /generate路由,它允许你与AI代理进行交互。你可以通过点击该路由,选择“尝试一下”,并填写所需字段(如问题和线程ID)来直接测试API。


或者,你也可以通过使用curl向/generate端点发送POST请求来测试API:


curl -X POST "https://<your-app-url>.aws.com/generate" \
-H "Content-Type: application/json" \
-d '{
    "question": "What are solar panels?",
    "thread_id": 1
}'


如果一切运行正常,你将会收到一个类似这样的JSON响应:


{
  "result": [
    {
      "assistant": {
        "messages": {
          "content": "Solar panels are devices that convert sunlight directly ..... ctricity from panels work!",
          "additional_kwargs": {
            "usage": {
              "prompt_tokens": 508,
              "completion_tokens": 272,
              "total_tokens": 780
            },
            "stop_reason": "end_turn",
            "model_id": "anthropic.claude-3-sonnet-20240229-v1:0"
          },
          "response_metadata": {
            "usage": {
              "prompt_tokens": 508,
              "completion_tokens": 272,
              "total_tokens": 780
            },
            "stop_reason": "end_turn",
            "model_id": "anthropic.claude-3-sonnet-20240229-v1:0"
          },
          "type": "ai",
          "name": null,
          "id": "run-b10e6c9e-832e-4fb2-92e9-c335cb2a07f2-0",
          "example": false,
          "tool_calls": [],
          "invalid_tool_calls": [],
          "usage_metadata": {
            "input_tokens": 508,
            "output_tokens": 272,
            "total_tokens": 780
          }
        }
      }
    }


结论

通过AWS Copilot成功部署AI代理后,现在可以从任何类型的前端应用程序(如Web或移动应用)无缝访问该AI代理。此API完全能够处理实时请求,并在各种平台上提供智能响应。该部署允许灵活集成,确保AI代理可以扩展并适应不同的用例。这一基础使得AI代理具有多功能性,并准备好在多样化的实际应用中使用。

文章来源:https://medium.com/ai-advances/how-i-built-deployed-an-ai-agent-with-langgraph-langserve-aws-54c4eb04c640
欢迎关注ATYUN官方公众号
商务合作及内容投稿请联系邮箱:bd@atyun.com
评论 登录
写评论取消
回复取消