Add LangGraph Foundry hosted-agent example with Adaptive Eval - #250
Conversation
Adds examples/langgraph-foundry-hosted: a LangGraph travel planner deployed as a Microsoft Foundry hosted agent (Responses protocol) and evaluated with assert-ai via a callable target. Endpoints are read from environment variables; only placeholder values are committed.
There was a problem hiding this comment.
I took a pass and I think we should tighten a few things before merging, mostly because #252 landed now and this sample is still using the callable-wrapper path.
- Can we add a short note in the README explaining when to use this path vs the new native
target.model: azure_ai/agents/<id>path from #252? My understanding is this example is still the right path for the Responses/v2/custom hosted-agent case, whileazure_ai/agents/<asst_id>is now native for the v1 Assistants surface. Without that note, it may look like ASSERT still requires a wrapper for all Foundry hosted agents. - The eval config uses
azure/gpt-5.4for systematize/test generation/tester/judge, so the README/env template should also document the ASSERT model auth required for those calls (AZURE_API_BASEplus key or AAD setup, depending on what was validated). Right now the README only lists the Foundry project/model/agent endpoint vars, while.env.examplehas an unexplainedAZURE_API_BASE=. - There are a few stale/mismatched sample values:
agent.manifest.yamlstill saysget_current_timeandcalculator, the model default isgpt-5.1in README/agent.py/manifest butgpt-5.4in.env.example/azure.yaml/eval_config, and the viewer command should becd ../../viewer && npm run devif the user is following the previouscd examples/langgraph-foundry-hosted. - The PR body points to a validation comment, but I don't see a comment or checks on the PR. Can you move that output into the PR body or add the comment so the validation is visible?
I did a local sanity pass: YAML loads, the Python files compile, the example deps install, the LangGraph/ResponsesHostServer imports and graph construction work, and the callable target resolves with history support. I didn't run the live end-to-end path since that needs a deployed Foundry agent endpoint.
+1 to Jake's point. To add context: Responses v2 isn't supported by the native AAD path that landed in #252. I've filed issue #253 to track that gap. I would still like to see this PR (#250) land because it gives users an escape hatch for hosted agents: when the native target doesn't fit (Responses v2 today, other shapes tomorrow), they can always drop in a thin callable wrapper and keep evaluating. |
…, clarify callable-vs-native target, fix viewer path
|
Thanks for the thorough pass, Jake , Yeming! Addressed all four in 12fbffa:
Re-requesting your review. |
jakepresent
left a comment
There was a problem hiding this comment.
Original comments are addressed. I re-ran the static pass: YAML loads, Python compiles, config loading works, the agent imports/graph construction work, and the callable resolves with history support.
One small PR-body cleanup before merge would be to remove export_foundry_traces.py from the validation line since that file is not in this PR, but that is not blocking from me.
|
Thanks Shilpa for the iteration and for contributing this example! All comments are addressed, merging now. |
What this PR adds
A new self-contained example:
examples/langgraph-foundry-hosted/— a LangGraph travel-planner agent deployed as a Microsoft Foundry hosted agent (Responses protocol) and evaluated with Adaptive Eval (assert-ai).It demonstrates the end-to-end loop for a hosted agent:
StateGraphtravel planner (intent classification → research → itinerary optimization / clarification) with simulated tools.azd(azure.yaml,agent.yaml,agent.manifest.yaml,Dockerfile).auto_trace.py) that calls the live deployed agent over the Responses protocol, with the endpoint read from an environment variable.eval_config.yamlthat runs the Adaptive Eval pipeline (systematize → test_set → inference → judge) against the deployed agent.Why
Existing examples cover local/callable and Prompt Agent targets. This adds a worked example for evaluating an agent that is already deployed as a Foundry hosted agent, which is a common production shape.
Notes / safety
.env.exampleplaceholders are included, and.envis gitignored.Validation
Static sanity pass (deterministic)
agent.manifest.yaml,agent.yaml,azure.yaml,eval_config.yaml)agent.py,main.py,auto_trace.py,export_foundry_traces.py)py_compilecleanrequirements.txt)langgraph,langchain_azure_ai,azure-ai-projects,httpx, …)agent.get_graph())CompiledStateGraph, nodes:intent_classifier,research,itinerary_optimizer,clarificationResponsesHostServerimport (main.py)auto_trace:chat_sync)historyparam present (multi-turn support)Live end-to-end run (deployed Foundry hosted agent)
Ran
assert-ai run --config eval_config.yaml --force-stage inference --force-stage judgeagainst the deployed hosted agent over the Responses protocol (endpoint viaFOUNDRY_AGENT_ENDPOINT, AAD auth).travel-planner-langgraph-v1/demo-1Artifacts written to
artifacts/results/travel-planner-langgraph-v1/demo-1/(scores.jsonl,inference_set.jsonl,metrics.json).Known caveats (honest notes)
HTTPStatusError,stop_reason=target_error) on a prompt case (demographic-stereotyping probe) — appears transient from the deployed agent, not a sample/code defect; rerunning that case is recommended.scores.jsonl, not a harness failure.artifacts.jsonwrite withPermissionError [WinError 5].