MCP - черный ящик
MCP-серверы могут сбоить – возвращать ошибки или работать слишком медленно. В нашем случае MCP-сервер с некоторой вероятностью возвращает ошибку.
Вы можете сами убедиться в этом, увидев спаны с пометкой ERROR в трейсе.
Добавление retry вызовов MCP
В случае ошибки метода MCP, мы можем повторно вызывать его, чтобы повысить общие шансы на успех.
В файле mcp-client.py в функциях list_tools и call_tool добавьте цикл со счетчиком попыток.
Для лучшей наблюдаемости стоит записывать неудачные попытки в метаданные спана.
Общая структура:
for attempt in range(MAX_RETRIES):
try:
# вызов MCP
tool.update(output=result)
return result
except Exception as e:
tool.update(metadata={attempt: e})
if attempt < MAX_RETRIES - 1:
continue
else:
raise e
Полный код:
MAX_RETRIES = 3
def list_tools():
with langfuse.start_as_current_observation(as_type="tool", name="list-tools") as tool:
r = requests.post(
f"{MCP_URL}",
headers=_build_base_headers(),
json=_build_base_request("tools/list"),
timeout=5,
)
for attempt in range(MAX_RETRIES):
try:
r.raise_for_status()
result = [_create_llm_tool_definition(t) for t in r.json()["result"]["tools"]]
tool.update(output=result)
return result
except Exception as e:
tool.update(metadata={attempt: e})
if attempt < MAX_RETRIES - 1:
continue
else:
raise e
def call_tool(name, arguments):
with langfuse.start_as_current_observation(as_type="tool", name="call-tool", input=arguments) as tool:
tool.update(input={"name": name, "arguments": arguments})
payload = _build_base_request("tools/call")
payload["params"] = {
"name": name,
"arguments": arguments,
}
for attempt in range(MAX_RETRIES):
try:
r = requests.post(
f"{MCP_URL}",
headers=_build_base_headers(),
json=payload,
timeout=5,
)
r.raise_for_status()
result = r.json()["result"]
tool.update(output=result)
return result
except Exception as e:
tool.update(metadata={attempt: e})
if attempt < MAX_RETRIES - 1:
continue
else:
raise e
Не забудьте объявить константу MAX_RETRIES с ограничением на число итераций:
MAX_RETRIES = 3
Перезапустите агент:
docker compose up -d --force-recreate cookbook-agent
Попробуйте запросить агент снова.
Задача
Добиться работы агента даже при ошибках MCP
Неудачные ошибки должны логироваться в метаданных спана call-tool:
