forked from lingyuzeng/agent
add mcp use method
This commit is contained in:
61
examples/mcp_modes/plan_and_execute.py
Normal file
61
examples/mcp_modes/plan_and_execute.py
Normal file
@@ -0,0 +1,61 @@
|
||||
# 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())
|
||||
Reference in New Issue
Block a user