Files
agent/examples/mcp_modes/plan_and_execute.py
2025-09-01 11:59:17 +08:00

62 lines
2.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# examples/mcp_modes/plan_and_execute.py
import os, asyncio
from typing import List
from langchain_core.messages import HumanMessage, ToolMessage
from langgraph_qwen.chat_model import ChatQwenOpenAICompat
from langgraph_qwen.mcp import load_mcp_tools
async def plan(task: str) -> List[str]:
planner = ChatQwenOpenAICompat(temperature=0)
ai = await planner.ainvoke([HumanMessage(content=f"把任务拆成可执行步骤(每行一步):\n{task}")])
steps = [s.strip() for s in str(ai.content).splitlines() if s.strip()]
return steps[:8]
async def tools_for_step(step_idx: int):
# ★ 示例:偶数步用 weather奇数步用 play/test 工具;也可来自文件
if step_idx % 2 == 0:
return await load_mcp_tools(servers={
"weather": {"url":"http://127.0.0.1:8000/mcp/","transport":"streamable_http"}
})
else:
cfg = os.getenv("MCP_CONFIG_PATH") # 比如 ./mcp_servers.yaml
return await load_mcp_tools(config_path=cfg)
async def execute(steps: List[str], max_tool_steps_per_step: int = 4):
msgs = []
for i, step in enumerate(steps, 1):
tools = await tools_for_step(i)
tool_map = {t.name: t for t in tools}
model = ChatQwenOpenAICompat(temperature=0).bind_tools(tools).bind(tool_choice="auto")
msgs.append(HumanMessage(content=f"执行第{i}步:{step}"))
for _ in range(max_tool_steps_per_step):
ai = await model.ainvoke(msgs)
msgs.append(ai)
calls = getattr(ai, "tool_calls", []) or ai.additional_kwargs.get("tool_calls", [])
if not calls:
break
for call in calls:
name, args, call_id = call.get("name"), call.get("args", {}), call.get("id") or ""
tool = tool_map.get(name)
if not tool:
msgs.append(ToolMessage(tool_call_id=call_id, content=f"Unknown tool: {name}"))
continue
try:
out = await tool.ainvoke(args) if hasattr(tool, "ainvoke") else tool.invoke(args)
msgs.append(ToolMessage(tool_call_id=call_id, content=str(out)))
except Exception as e:
msgs.append(ToolMessage(tool_call_id=call_id, content=f"Error: {e}"))
final = await ChatQwenOpenAICompat(temperature=0).ainvoke(
msgs + [HumanMessage(content="请汇总执行结果,简洁给出结论。")]
)
print("=== Final ===")
print(final.content)
async def main():
steps = await plan("在巴塞罗那找一个带游泳池的民宿,然后搜索附近的餐厅和景点")
await execute(steps, max_tool_steps_per_step=4)
if __name__ == "__main__":
asyncio.run(main())