from __future__ import annotations import asyncio import os import sys from typing import Any from langgraph_sdk import get_client BASE_URL = os.getenv("LANGGRAPH_URL", "http://192.168.0.100:2026") ASSISTANT_ID = "student_score" QUESTION = "帮我看看白若耶同学的信息" CONTEXT = { "team_id": "19", "env": "dev", } if hasattr(sys.stdout, "reconfigure"): sys.stdout.reconfigure(encoding="utf-8") def event_data(event: Any) -> Any: if isinstance(event, dict): return event.get("data") return getattr(event, "data", None) def event_name(event: Any) -> str: if isinstance(event, dict): return str(event.get("event") or "") return str(getattr(event, "event", "")) def pick_final_answer(data: Any) -> str: if not isinstance(data, dict): return "" render_answer = data.get("render_answer") if isinstance(render_answer, dict) and isinstance(render_answer.get("answer"), str): return render_answer["answer"] answer = data.get("answer") return answer if isinstance(answer, str) else "" def pick_answer_source(data: Any) -> str: if not isinstance(data, dict): return "" render_answer = data.get("render_answer") if isinstance(render_answer, dict) and isinstance(render_answer.get("answer_source"), str): return render_answer["answer_source"] answer_source = data.get("answer_source") return answer_source if isinstance(answer_source, str) else "" async def main() -> None: client = get_client(url=BASE_URL) thread = await client.threads.create() answer_parts: list[str] = [] final_answers: list[str] = [] print("=== LangGraph updates + messages-tuple 流式调用 ===", flush=True) print("[updates] 节点进度;[messages] 最终 Markdown token。", flush=True) print("", flush=True) async for event in client.runs.stream( thread_id=thread["thread_id"], assistant_id=ASSISTANT_ID, input={"question": QUESTION}, context=CONTEXT, stream_mode=["updates", "messages-tuple"], ): name = event_name(event) data = event_data(event) if name == "updates": final_answer = pick_final_answer(data) answer_source = pick_answer_source(data) if isinstance(data, dict): print(f"\n[updates] {', '.join(data.keys())}", flush=True) render_answer = data.get("render_answer") if isinstance(render_answer, dict): print(f"[render_answer.keys] {', '.join(render_answer.keys())}", flush=True) else: print(f"\n[updates] {data}", flush=True) if answer_source: print(f"[answer_source] {answer_source}", flush=True) if final_answer: final_answers.append(final_answer) print("\n[final.answer]", flush=True) print(final_answer, flush=True) continue if name == "messages": if isinstance(data, list) and data: message_chunk = data[0] content = message_chunk.get("content") if isinstance(message_chunk, dict) else "" if isinstance(content, str) and content: answer_parts.append(content) print(content, end="", flush=True) continue print("\n\n=== 最终 Markdown 长度 ===", flush=True) print(len(final_answers[-1] if final_answers else "".join(answer_parts)), flush=True) if __name__ == "__main__": asyncio.run(main())