不论我们采用那种形式的开发方式(LangChain、LangGraph和Deep Agents),最终创建的Agent都体现为一个CompiledStateGraph对象,CompiledStateGraph派生于Pregel类型。我们最终需要利用LangSmith对它进行部署,它提供Agent在生产环境中大规模可靠运行所需的托管基础​​架构,支持从本地开发到部署的完整生命周期。LangSmith不仅仅限于针对自家开发框架的支持,它可以用来部署LangGraph和其他框架构建的Agent。所谓针对Agent部署,本质上就是创建一个Web Server,并对外暴露一系列RESTful API使我们可以通过HTTP请求与Agent进行交互。

这个系列旨在通过一系列具体的实例演示介绍客户端如何以Web的形式与部署的Agent Server进行交互,但在这之前,我们得有一个可供调用的Agent Server。为了让读者朋友们如何与Agent Server之间的交互有一个总体的认识,我们会先部署一个简单的Agent Server,然后演示利用LangGraph SDK来调用Agent Server暴露出来的RESTful API。

1. 定义和部署Graph

为了我们构建了一个极简的Agent服务器,根目录下只有如下所示的几个必要的文件:

root/
├── .env            # 存放环境变量
├── langgraph.json  # 配置Graph
├── agent.py        # 定义Graph
└── pyproject.toml  # 项目配置文件

从部署的角度来说,我们之前所谓的Agent在这里被统一称为Graph,虽然它是StateGraph编译后的产物,自身是一个Actor模型。但是我们依然习惯称之为Graph,毕竟从图的角度去理解Agent的执行流程比从Actor模型的角度更为直观。

我们在agent.py中定义了一个Graph用来提供指定城市实时的天气信息,并在此基础上提供着装建议。我们调用的是“和风天气”提供的API,相应的URL和API Key等信息我们都放在了.env文件中,该文件中也存放了与模型和LangSmith相关的环境变量。agent.py文件的内容如下所示:利用create_agent函数创建了一个Agent注册了两个工具,get_weather根据指定的位置编码查询实时天气信息,指定城市的地理位置编码则由look_up_location工具查询获得。

from typing import Callable,Any
from langchain.agents import create_agent
from langchain.tools import tool
from langchain_openai import ChatOpenAI
from requests import Response
import requests,os

def invoke(url:str, params:dict, extract_result:Callable[[Response], Any]) -> Any:
    response = requests.get(
        headers={"X-QW-Api-Key" : os.getenv("QW_API_KEY")},
        url = url, 
        params=params)
    if response.status_code == 200:
        return extract_result(response)
    else:
        raise Exception(f"请求失败,状态码:{response.status_code}")

@tool
def look_up_location(city: str) -> str:
    """查询指定城市的地理位置
    Args:
        city (str): 城市名称,例如 "北京" 或 "beijing"
    """

    return invoke(
        url=os.getenv("QW_LOCATION_LOOKUP_URL",""), 
        params={"location": city},
        extract_result=lambda response: response.json()["location"][0]["id"]
    )     

@tool
def get_weather(location: str) -> dict:
    """获取指定位置的实时天气信息
    
    Args:
        location (str): 工具look_up_location返回的指定城市的地理位置
    """

    return invoke(
        url=os.getenv("QW_WEATHER_URL",""), 
        params={"location": location},
        extract_result=lambda response: response.json()["now"]
    )

graph = create_agent(
    model=ChatOpenAI(model="gpt-5.2-chat"),
    tools=[look_up_location, get_weather],
    system_prompt=("作为一个出行Assistant,提供指定程序实时天气和着装建议"),
)

上面定义的这个Graph以如下的形式配置在langgraph.json文件中,Graph ID被命名为test_agent

{
  "dependencies": ["."],
  "graphs": {
    "test_agent": "./agent.py:graph"
  },
  "env": ".env"
}

我们执行命令行langgraph dev以dev模式部署我们定义的Agent,并启动作为宿主的Web服务器。

Alternative Text

Langgraph Server启动成功后会输出相关的访问信息,包括API的URL、Studio UI的URL以及API文档的URL等:

  • 🚀 API: http://127.0.0.1:2024
  • 🎨 Studio UI: https://smith.langchain.com/studio/?baseUrl=http://127.0.0.1:2024
  • 📚 API Docs: http://127.0.0.1:2024/docs

2. 利用Studio UI测试

我们也可以直接访问Studio UI来测试我们部署的Agent,Studio UI提供了一个可视化的界面来与Agent进行交互,非常适合我们在开发阶段进行调试和测试。Studio UI提供了Graph和Chat两种模式,前者以图形化的方式展示Agent的执行流程,后者则以对话的形式展示Agent的输入输出和工具调用等信息。我们可以根据自己的需求选择不同的模式来观察Agent的行为。为了测试我们部署的Agent是否能够正常工作,我们可以在Studio UI中输入如下的测试指令:

Alternative Text

3. 编写客户端程序测试

我们也可以利用LangGraph SDK编写客户端程序来测试我们部署的Graph。下面是一个简单的客户端程序示例:我们将LangGraph服务器的URL作为参数调用get_client函数来创建一个LangGraphClient对象,然后调用runs.wait方法调用部署的Agent。虽然LangGraphClient.runs.wait方法返回的数据结构与CompiledStateGraph.ainvoke方法返回的数据结构基本一致。但是返回的消息是一个单纯的字典,而不是BaseMessage对象。所以我们需要定义一个辅助函数as_message来将字典转换为BaseMessage对象,以便我们能够利用BaseMessage提供的pretty_print方法来更友好地展示消息内容。

from typing import Any
from langgraph_sdk import get_client
from langchain_core.messages import HumanMessage,AIMessage,ToolMessage
import asyncio

client = get_client(url="http://localhost:2024")

def as_message(message:dict[str,Any]) -> HumanMessage | AIMessage | ToolMessage:
    type = message.get("type")
    cls = HumanMessage if type == "human" else AIMessage if type == "ai" else ToolMessage
    return cls(**message)

async def main():
    result = await client.runs.wait(
        thread_id=None, 
        assistant_id= "test_agent",
        input={
            "messages": [
                {
                    "role": "user",
                    "content": "苏州目前天气如何?我该穿什么?"
                }
            ]
        }
    )
    for message in result["messages"]: # type: ignore
        as_message( message).pretty_print()

asyncio.run(main())

上面的演示程序将整个流程生成的消息都打印了出来,我们可以清晰地看到Agent的执行流程,包括工具调用和工具返回的结果等信息。

================================ Human Message =================================

苏州目前天气如何?我该穿什么?
================================== Ai Message ==================================
Tool Calls:
  look_up_location (call_kHtMWKQVws3zkPEnXREn0sOb)
 Call ID: call_kHtMWKQVws3zkPEnXREn0sOb
  Args:
    city: 苏州
================================= Tool Message =================================
Name: look_up_location

101190401
================================== Ai Message ==================================
Tool Calls:
  get_weather (call_8MFOH4LlTsFTHCi56bbpMwLF)
 Call ID: call_8MFOH4LlTsFTHCi56bbpMwLF
  Args:
    location: 101190401
================================= Tool Message =================================
Name: get_weather

{"obsTime": "2026-04-25T19:40+08:00", "temp": "19", "feelsLike": "16", "icon": "150", "text": "晴", "wind360": "91", "windDir": "东风", "windScale": "3", "windSpeed": "19", "humidity": "54", "precip": "0.0", "pressure": "1014", "vis": "29", "cloud": "91", "dew": "8"}
================================== Ai Message ==================================

苏州**目前实时天气**(更新时间:4月25日 19:40)如下:

🌤 **天气状况**:晴  
🌡 **气温**:19℃  
🤔 **体感温度**:16℃  
💨 **风**:东风 3级,风速约19 km/h  
💧 **湿度**:54%  
☔ **降水**:无  
👀 **能见度**:29 km  

---

### 👕 穿衣建议
现在是**傍晚偏凉**,而且有风,建议:

- ✅ **上身**:长袖衬衫 / 薄卫衣 / 薄针织衫  
- ✅ **外搭**:轻薄外套或风衣(防风很重要)  
- ✅ **下身**:长裤(牛仔裤、休闲裤都合适)  
- ✅ **鞋子**:运动鞋或休闲鞋  

👉 **怕冷的人**:可以选择稍厚一点的外套  
👉 **夜间外出**:温度还可能再降1–2℃,不建议穿短袖

如果你是**通勤、旅游还是夜跑**,我也可以帮你更具体地搭配 😊
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐