將 LangGraph Agent 託管為 Foundry 託管的 Agent

使用 langchain_azure_ai.agents.hosting 套件,透過 Microsoft Foundry hosted agents 的協定,公開編譯後的 LangGraph 圖。 主機套件讓你能在程式碼中保留 LangChain 和 LangGraph 代理邏輯,而 Foundry 則管理託管的執行時、會話、擴展、身份和協定端點。

在本文中,你將建立一個最精簡的 LangGraph 代理,透過 Responses 或 Invocations 通訊協定將其公開,透過 HTTP 進行測試,然後使用 Azure Developer CLI 或 Foundry Toolkit 的 Visual Studio Code 擴充功能將其部署至 Foundry。

你也會學會如何在不更改程式碼或設定的情況下遷移現有的 LangGraph 專案。

先決條件

  • Azure 訂用帳戶。 免費創建一個。
  • Foundry 專案。
  • 一個已部署的聊天模型,例如 gpt-4.1 或 gpt-5-mini。
  • Python 3.10 或更新版本。
  • Azure CLI已登入(az login),所以 DefaultAzureCredential 可以進行認證。

安裝套件

安裝 langchain-azure-ai 版本 1.2.9 或更新版本,並附帶主機附加功能:

pip install -U "langchain-azure-ai[hosting]>=1.2.9" azure-identity

hosting額外安裝選項會安裝供主機伺服器使用的 Foundry 通訊協定庫:

  • azure-ai-agentserver-responses 適用於 OpenAI 相容的 /responses 端點。
  • azure-ai-agentserver-invocations 用於通用 /invocations 端點。

選擇主機協定

託管代理可以暴露一個或多個協定。 大多數對話式代理程式都應先從 Responses 開始。

通訊協定 主機類別 終點 何時使用
回應 ResponsesHostServer /responses 你想要的是支援 OpenAI 的聊天、串流、回應歷史和對話串程。
祈禱 InvocationsHostServer /invocations 你需要自訂的 JSON 形狀、類似 webhook 的端點,或是非對話式處理。

關於協定行為與會話的背景,請參見「託管代理」及「管理託管代理會話」。

設定環境變數

設定專案端點及本地開發的模型部署名稱:

export FOUNDRY_PROJECT_ENDPOINT="https://<resource>.services.ai.azure.com/api/projects/<project>"
export FOUNDRY_MODEL_NAME="gpt-4.1"

當同一程式碼在 Foundry 中以 Hosted 代理執行時,平台會注入 FOUNDRY_PROJECT_ENDPOINT。 如果你將 azd ai agent init 與範例 azure.yaml 搭配使用,產生的專案也會針對所選的模型部署使用 FOUNDRY_MODEL_NAME。

回應協定

當你想要一個支援 OpenAI 的聊天端點,具備串流功能、回應歷史和對話串程時,請使用 Responses 協定。

建立回應主機

建立一個名為 main.py 的檔案,其中包含一個使用 Foundry 模型的最精簡 LangGraph 代理。 此模式與原始資料庫中 langchain-azure-ai 的基本回應樣本相符。

import os

from azure.ai.projects import AIProjectClient
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI

from langchain_azure_ai.agents.hosting import ResponsesHostServer

_AZURE_AI_SCOPE = "https://ai.azure.com/.default"


def build_chat_model() -> ChatOpenAI:
    project_endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"].rstrip("/")
    deployment = os.environ.get("FOUNDRY_MODEL_NAME", "gpt-4.1")
    credential = DefaultAzureCredential()
    project = AIProjectClient(endpoint=project_endpoint, credential=credential)
    openai_client = project.get_openai_client()
    token_provider = get_bearer_token_provider(credential, _AZURE_AI_SCOPE)

    return ChatOpenAI(
        model=deployment,
        base_url=str(openai_client.base_url),
        api_key=token_provider,
    )


def main() -> None:
    graph = create_agent(build_chat_model(), tools=[])
    port = int(os.environ.get("PORT", "8088"))
    ResponsesHostServer(graph).run(port=port)


if __name__ == "__main__":
    main()

這段內容 :建立一個包含 LangChain 的 create_agentLangGraph 代理,並將其連接到 Foundry 專案的 OpenAI 相容模型端點,並將編譯後的圖傳給 ResponsesHostServer。 主機啟動 HTTP 伺服器,並透過 POST /responses公開該圖。 根據預設,伺服器會繫結至連接埠8088,或如果已設定PORT環境變數的值,則會改用其值。

Note

深度代理的託管方式與其他 LangGraph 代理相同。 直接將代理程式傳遞至 ResponsesHostServer。

agent = create_deep_agent(...)
ResponsesHostServer(agent).run(port=port)

在本地執行應用程式:

python main.py

測試回覆端點

向本地伺服器發送一個非串流的回應請求。

Bash:

curl -sS -H "Content-Type: application/json" \
  -X POST http://localhost:8088/responses \
  -d '{"input":"Give me one practical tip for testing hosted agents.","stream":false}'

PowerShell:

$body = @{
  input = "Give me one practical tip for testing hosted agents."
  stream = $false
} | ConvertTo-Json

Invoke-RestMethod `
    -Uri http://localhost:8088/responses `
    -Method Post `
    -Body $body `
    -ContentType "application/json"

串流回應時,設 stream 為 true。 主機會發出回應 API 伺服器發送的事件,例如 response.created、 response.output_text.delta和 response.completed。

對話

ResponsesHostServer 支援兩種對話狀態模式。 它使用的模式取決於你編譯的圖是否有 LangGraph 檢查點。

圖表設定 對話來源 主機在後面回合傳送到圖的內容
沒有檢查點的圖形 協定執行時的回應歷史 先前的回應紀錄加上目前的請求輸入
使用檢查點器編譯的圖 LangGraph 檢查點狀態由對話或回應線程鍵控 僅限目前的要求輸入

當您的圖需要在多個回合之間保留 LangGraph 的執行階段狀態、中斷資訊或節點的本機狀態時,請使用檢查點機制。 本地測試時,您可以使用記憶體中的檢查指標:

from langgraph.checkpoint.memory import MemorySaver

graph = create_agent(
    build_chat_model(),
    tools=[],
    checkpointer=MemorySaver(),
)

對於正式執行環境託管的 Agent,請使用持久性檢查點,而不是記憶體內檢查點,這樣圖狀態才能在容器重啟時保持不變。

客戶透過傳遞 previous_response_id 或 conversation ID 繼續回應對話。 在本地測試時,下一次請求中可連結先前的回應 ID:

POST http://localhost:8088/responses
Content-Type: application/json

{
  "input": "Can you make that more concise?",
  "previous_response_id": "<previous-response-id>",
  "stream": false
}

當代理在 Foundry 中執行時,相同的模式也會透過託管代理回應端點運作。 如果後續回合也需要相同的託管沙盒檔案系統,請包含 agent_session_id 或使用 conversation ID。 詳情請參閱 管理託管代理會話。

人機互動

如果您的圖使用 LangGraph interrupt()呼叫,ResponsesHostServer會透過標準回覆 API 輸出項目呈現待處理的中斷:

  • 一個名為 function_call 的 __hosted_agent_adapter_interrupt__ 項目。
  • 一個已將mcp_approval_request設定為server_label的langgraph項目。

用戶端可以透過傳送其function_call_output與中斷識別碼相符的call_id項目,或傳送其mcp_approval_response與中斷 ID 相符的approval_request_id項目,來繼續執行圖。 當您需要傳送包含 function_call_output、Command 或 resume 欄位的豐富 LangGraph update 酬載時,請使用 goto。 使用 mcp_approval_response 建立簡單的核准或拒絕流程。

呼叫協定

當呼叫者無法使用 Responses API 請求表單,或是你的情境不是聊天對話時,才會使用 InvocationsHostServer 。 預設的 Invocations 主機接受 message 字串和選用的 stream 旗標。

建立召喚主機

使用與回應範例相同的模型建構函數,但 開始 InvocationsHostServer 而非 ResponsesHostServer。

import os

from langchain.agents import create_agent
from langgraph.checkpoint.memory import MemorySaver

from langchain_azure_ai.agents.hosting import InvocationsHostServer


def main() -> None:
    graph = create_agent(
        build_chat_model(),
        tools=[],
        checkpointer=MemorySaver(),
    )
    port = int(os.environ.get("PORT", "8088"))
    InvocationsHostServer(graph).run(port=port)


if __name__ == "__main__":
    main()

這段程式碼片段的作用:透過 POST /invocations 託管 LangGraph 代理。 MemorySaver檢查點會為特定工作階段識別碼提供本機多回合連續性。 在正式執行環境中,請使用持久性檢查點,讓狀態在容器重新啟動後仍能保留不變。

Note

深度代理的託管方式與其他 LangGraph 代理相同。 直接將代理程式傳遞給 InvocationsHostServer。

agent = create_deep_agent(...)
InvocationsHostServer(agent).run(port=port)

測試 Invocations 端點

發送非串流請求:

curl -i -X POST http://localhost:8088/invocations \
  -H "Content-Type: application/json" \
  -d '{"message":"My name is Alice.","stream":false}'

非串流請求會以以下形式回傳 JSON:

{
  "response": "Assistant text"
}

對於多回合對話,請在下一個請求中重複使用 x-agent-session-id 回應標頭作為 agent_session_id 查詢參數:

curl -X POST "http://localhost:8088/invocations?agent_session_id=<session-id>" \
  -H "Content-Type: application/json" \
  -d '{"message":"What is my name?"}'

串流要求傳回帶有權杖酬載的text/event-stream事件:

curl -N -X POST http://localhost:8088/invocations \
  -H "Content-Type: application/json" \
  -d '{"message":"Count to 5.","stream":true}'

該串流包含代幣事件,接著是終端 done 事件:

data: {"token": "..."}

event: done
data: {}

自訂請求結構

若要自訂請求主體,請建立 InvocationsHostServer 的子類別並覆寫 parse_request。 你也可以覆寫 build_input ,將解析後的資料映射到自訂的圖形狀態。

from starlette.requests import Request

from langchain_azure_ai.agents.hosting import InvocationsHostServer


class TicketHostServer(InvocationsHostServer):
    async def parse_request(self, request: Request) -> tuple[str, bool]:
        data = await request.json()
        ticket_id = data["ticket_id"]
        description = data["description"]
        stream = bool(data.get("stream", False))
        return f"Summarize ticket {ticket_id}: {description}", stream


if __name__ == "__main__":
    TicketHostServer(graph).run()

這段程式碼片段的功能:接受自訂票證承載資料,並在主機叫用圖形前,將其轉換為單一使用者訊息。 對於更複雜的圖狀態,請覆寫build_input而不是扁平化要求到文字。

Deploy

你可以使用 Azure Developer CLI 或 Foundry Toolkit 的 Visual Studio Code 擴充功能來部署。 Azure 開發者 CLI 流程使用範例azure.yaml檔案和 Docker。 擴充流程提供 Visual Studio Code 的引導式部署體驗。

託管的 Agent 部署需要具備專案中的 Foundry 專案管理者角色。 詳情請參見 部署託管代理。

使用 Azure 開發人員 CLI 進行部署

langchain-azure-ai原始碼儲存庫包含可透過 Azure 開發者 CLI 執行與部署的託管代理範例。 流程使用每個樣本的 azure.yaml、Dockerfile 和 main.py。 如需 azure.yaml 中託管代理程式設定的詳細資訊,請參閱 Author azure.yaml for hosted agents。

安裝 AI 代理擴充功能並在初始化樣本前登入:

azd ext install azure.ai.agents
azd auth login

Docker 必須在本地執行,因為 azd ai agent run 它建置的是範例 Dockerfile 中宣告的容器映像。 關於指令細節,請參閱 Azure 開發者 CLI 參考。

從範例 azure.yaml 檔案初始化

建立一個新資料夾,並從範例 azure.yaml開始初始化。 將 azure.yaml URL 替換成你想使用的範例。

mkdir my-langchain-agent
cd my-langchain-agent

azd ai agent init -m https://github.com/langchain-ai/langchain-azure/blob/main/samples/hosting/langgraph-hosted-agents/responses/01_basic/azure.yaml

請依照 azd ai agent init 的提示。 如果你還沒有 Foundry 專案和模型部署,初始化流程可以引導你建立它們。

在本機執行容器

透過以下方式在 azd本地執行代理主機:

azd ai agent run

主機在 http://127.0.0.1:8088 上提供服務。 在另一個終端機中,直接呼叫本地協定端點:

curl -X POST http://127.0.0.1:8088/responses \
  -H "Content-Type: application/json" \
  -d '{"input": "Hello!"}'

PowerShell 等價物:

(Invoke-WebRequest -Uri http://127.0.0.1:8088/responses `
  -Method POST -ContentType 'application/json' `
  -Body '{"input": "Hello!"}').Content

您也可以透過 azd以下方式呼叫當地代理人:

azd ai agent invoke --local "Hello!"

部署至鑄造廠

若初始化專案使用新的 Foundry 專案與模型部署,請先配置 Azure 資源:

azd provision

部署代理:

azd deploy

部署時會將代理程式打包成容器映像,推送到已配置的容器登錄檔,然後推送到 Foundry Hosted 代理執行環境。

Foundry 的託管基礎設施會將執行時環境變數注入代理程式,包括:

  • FOUNDRY_PROJECT_ENDPOINT:已部署代理程式的 Foundry 專案端點 URL。
  • FOUNDRY_MODEL_NAME:在 azd ai agent init 期間所選取的模型部署名稱。
  • APPLICATIONINSIGHTS_CONNECTION_STRING:專案應用洞察實例的連接字串。

欲了解完整的部署概念、權限及管理細節,請參閱 「部署託管代理」 及 「管理託管代理生命週期」。

使用 Foundry Toolkit Visual Studio Code 擴充套件部署

關於基於擴充功能的部署,請參見 快速入門:部署你的第一個託管代理。

託管現有的代理程式

如果你的應用程式已經能支援 LangSmith 或 LangGraph CLI,請使用該 langchain_azure_ai.agents.hosting.run 模組無縫地在 Foundry 上架設代理,無需更改程式碼或設定。

從專案根源開始,啟動一個回應主機:

python -m langchain_azure_ai.agents.hosting.run --protocol responses

若要透過 Invocations 協定暴露同一圖,請設 --protocol 為 invocations。 如果 langgraph.json 定義多個圖,第一個參數是傳圖名稱。 如果設定檔不在預設langgraph.json路徑,就用--config <path>它。 例如:

python -m langchain_azure_ai.agents.hosting.run agent --protocol invocations

部署現有應用程式到 Foundry 時,使用與容器入口相同的模組指令。

例如,在 azure.yaml 中設定指令。 關鍵設定是入口點。

services:
  my-agent:
    host: azure.ai.agent
    kind: hosted
    codeConfiguration:
      runtime: python_3_13
      entryPoint: '-m langchain_azure_ai.agents.hosting.run --protocol responses'
      ...
    ...

Troubleshooting

使用此檢查清單來診斷開發帶有 langchain_azure_ai.agents.hosting的託管代理時常見的問題。

圖結構驗證失敗

預設主機期望一個已編譯的 LangGraph 圖,其狀態有一個欄位 messages ,例如 MessagesState。 如果您的圖使用自訂狀態結構描述,請子類化主機並覆寫build_input。 對於回應,當你需要完全控制請求解析、圖形執行及發出回應事件時,請覆蓋 handle_create 。

對話狀態不再繼續

對於 Responses 通訊協定,在後續輪次中傳入 previous_response_id 或 conversation ID。 如果你的圖表使用檢查點,請確保檢查點是針對代理執行環境設定且耐用的。

對於 Invocations 協定,平台不會儲存對話紀錄。 使用 agent_session_id 查詢參數將後續呼叫路由到同一託管沙盒,並用自己的狀態儲存庫或 LangGraph 檢查指標來處理對話狀態。

無法在代管容器中連線到模型

確認託管代理版本包含 FOUNDRY_MODEL_NAME,且代理身份有權限呼叫 Foundry 專案。 平台設定 FOUNDRY_PROJECT_ENDPOINT;你的程式碼在 Foundry 執行時應該會讀取這個變數。

後續步驟