Hi there, im new to the ecosystem and am trying to play with agentic systems with Langchain agents. I’m on my company system and only has access to LLM models hosted on SnowFlake, so I tried using ChatSnowflake with Langchain agents. However, it seems as long as tools are provided to the agent, the agent will not work due to HTTPError 400 (see the attached sample code).
I wonder if ChatSnowflake works with Langchain agents? I dont see any examples other than on Snowflake website, and it doesnt utilize Langhcain agents.
import snowflake.snowpark as snowpark
from langchain_snowflake import ChatSnowflake
from langchain.agents import create_agent
from langchain.messages import SystemMessage, HumanMessage, AIMessage
from langchain.tools import tool
@tool
def get_weather(city: str) -> str:
"""Get weather for a given city."""
return f"It's always sunny in {city}!"
connection_parameters = {
"account": ...
"user": ...
"authenticator": "externalbrowser",
"role": ...
"warehouse": ...
"database": ...
"schema": ...
}
session = snowpark.Session.builder.configs(connection_parameters).create()
llm = ChatSnowflake(model="llama3.1-8b", session=session, max_tokens=8000,
verify_ssl=False)
messages = [
SystemMessage("You are a helpful assistant"),
HumanMessage("What's the weather in Singapore?")]
agent = create_agent(llm, name='test')
agent.invoke({'messages': messages})
### works fine, returns something like AIMessage(content="However, I'm a large language model, I don't have real-time access to current weather conditions. But I can suggest some ways fo.....)
agent = create_agent(llm, name='test', tools=[get_weather])
agent.invoke({'messages': messages})
### throws HTTPerror 400
Here’s the full error stack
---------------------------------------------------------------------------
HTTPError Traceback (most recent call last)
Cell In[1], line 61
57 messages = [
58 # SystemMessage("You are a helpful assistant"),
59 HumanMessage("What's the weather in Singapore?")]
---> 61 agent.invoke({'messages': messages})
File c:\envs\py312_streamlit\.venv\Lib\site-packages\langgraph\pregel\main.py:3365, in Pregel.invoke(self, input, config, context, stream_mode, print_mode, output_keys, interrupt_before, interrupt_after, durability, version, **kwargs)
3362 chunks.append(chunk)
3363 else:
3364 # v1: collect interrupts from updates stream
-> 3365 for chunk in self.stream(
3366 input,
3367 config,
3368 context=context,
3369 stream_mode=(
3370 ["updates", "values"] if stream_mode == "values" else stream_mode
3371 ),
3372 print_mode=print_mode,
3373 output_keys=output_keys,
3374 interrupt_before=interrupt_before,
3375 interrupt_after=interrupt_after,
3376 durability=durability,
3377 **kwargs,
3378 ):
3379 if stream_mode == "values":
3380 if len(chunk) == 2:
File c:\envs\py312_streamlit\.venv\Lib\site-packages\langgraph\pregel\main.py:2759, in Pregel.stream(self, input, config, context, stream_mode, print_mode, output_keys, interrupt_before, interrupt_after, durability, subgraphs, debug, version, **kwargs)
2757 for task in loop.match_cached_writes():
2758 loop.output_writes(task.id, task.writes, cached=True)
-> 2759 for _ in runner.tick(
2760 [t for t in loop.tasks.values() if not t.writes],
2761 timeout=self.step_timeout,
2762 get_waiter=get_waiter,
2763 schedule_task=loop.accept_push,
2764 ):
2765 # emit output
2766 yield from _output(
2767 stream_mode,
2768 print_mode,
(...) 2774 _state_mapper,
2775 )
2776 loop.after_tick()
File c:\envs\py312_streamlit\.venv\Lib\site-packages\langgraph\pregel\_runner.py:167, in PregelRunner.tick(self, tasks, reraise, timeout, retry_policy, get_waiter, schedule_task)
165 t = tasks[0]
166 try:
--> 167 run_with_retry(
168 t,
169 retry_policy,
170 configurable={
171 CONFIG_KEY_CALL: partial(
172 _call,
173 weakref.ref(t),
174 retry_policy=retry_policy,
175 futures=weakref.ref(futures),
176 schedule_task=schedule_task,
177 submit=self.submit,
178 ),
179 },
180 )
181 self.commit(t, None)
182 except Exception as exc:
File c:\envs\py312_streamlit\.venv\Lib\site-packages\langgraph\pregel\_retry.py:126, in run_with_retry(task, retry_policy, configurable)
124 task.writes.clear()
125 # run the task
--> 126 return task.proc.invoke(task.input, config)
127 except ParentCommand as exc:
128 ns: str = config[CONF][CONFIG_KEY_CHECKPOINT_NS]
File c:\envs\py312_streamlit\.venv\Lib\site-packages\langgraph\_internal\_runnable.py:656, in RunnableSeq.invoke(self, input, config, **kwargs)
654 # run in context
655 with set_config_context(config, run) as context:
--> 656 input = context.run(step.invoke, input, config, **kwargs)
657 else:
658 input = step.invoke(input, config)
File c:\envs\py312_streamlit\.venv\Lib\site-packages\langgraph\_internal\_runnable.py:400, in RunnableCallable.invoke(self, input, config, **kwargs)
398 run_manager.on_chain_end(ret)
399 else:
--> 400 ret = self.func(*args, **kwargs)
401 if self.recurse and isinstance(ret, Runnable):
402 return ret.invoke(input, config)
File c:\envs\py312_streamlit\.venv\Lib\site-packages\langchain\agents\factory.py:1317, in create_agent.<locals>.model_node(state, runtime)
1305 request = ModelRequest(
1306 model=model,
1307 tools=default_tools,
(...) 1313 runtime=runtime,
1314 )
1316 if wrap_model_call_handler is None:
-> 1317 model_response = _execute_model_sync(request)
1318 return _build_commands(model_response)
1320 result = wrap_model_call_handler(request, _execute_model_sync)
File c:\envs\py312_streamlit\.venv\Lib\site-packages\langchain\agents\factory.py:1289, in create_agent.<locals>._execute_model_sync(request)
1286 if request.system_message:
1287 messages = [request.system_message, *messages]
-> 1289 output = model_.invoke(messages)
1290 if name:
1291 output.name = name
File c:\envs\py312_streamlit\.venv\Lib\site-packages\langchain_core\language_models\chat_models.py:471, in BaseChatModel.invoke(self, input, config, stop, **kwargs)
457 @override
458 def invoke(
459 self,
(...) 464 **kwargs: Any,
465 ) -> AIMessage:
466 config = ensure_config(config)
467 return cast(
468 "AIMessage",
469 cast(
470 "ChatGeneration",
--> 471 self.generate_prompt(
472 [self._convert_input(input)],
473 stop=stop,
474 callbacks=config.get("callbacks"),
475 tags=config.get("tags"),
476 metadata=config.get("metadata"),
477 run_name=config.get("run_name"),
478 run_id=config.pop("run_id", None),
479 **kwargs,
480 ).generations[0][0],
481 ).message,
482 )
File c:\envs\py312_streamlit\.venv\Lib\site-packages\langchain_core\language_models\chat_models.py:1749, in BaseChatModel.generate_prompt(self, prompts, stop, callbacks, **kwargs)
1740 @override
1741 def generate_prompt(
1742 self,
(...) 1746 **kwargs: Any,
1747 ) -> LLMResult:
1748 prompt_messages = [p.to_messages() for p in prompts]
-> 1749 return self.generate(prompt_messages, stop=stop, callbacks=callbacks, **kwargs)
File c:\envs\py312_streamlit\.venv\Lib\site-packages\langchain_core\language_models\chat_models.py:1556, in BaseChatModel.generate(self, messages, stop, callbacks, tags, metadata, run_name, run_id, **kwargs)
1553 for i, m in enumerate(input_messages):
1554 try:
1555 results.append(
-> 1556 self._generate_with_cache(
1557 m,
1558 stop=stop,
1559 run_manager=run_managers[i] if run_managers else None,
1560 **kwargs,
1561 )
1562 )
1563 except BaseException as e:
1564 if run_managers:
File c:\envs\py312_streamlit\.venv\Lib\site-packages\langchain_core\language_models\chat_models.py:1896, in BaseChatModel._generate_with_cache(self, messages, stop, run_manager, **kwargs)
1894 result = generate_from_stream(iter(chunks))
1895 elif inspect.signature(self._generate).parameters.get("run_manager"):
-> 1896 result = self._generate(
1897 messages, stop=stop, run_manager=run_manager, **kwargs
1898 )
1899 else:
1900 result = self._generate(messages, stop=stop, **kwargs)
File c:\envs\py312_streamlit\.venv\Lib\site-packages\langchain_snowflake\chat_models\base.py:334, in ChatSnowflake._generate(self, messages, stop, run_manager, **kwargs)
332 """Generate a chat response using either REST API (for tools) or SQL function (for basic chat)."""
333 if self._should_use_rest_api():
--> 334 return self._generate_via_rest_api(messages, stop, run_manager, **kwargs)
335 else:
336 return self._generate_via_sql(messages, stop, run_manager, **kwargs)
File c:\envs\py312_streamlit\.venv\Lib\site-packages\langchain_snowflake\chat_models\base.py:529, in ChatSnowflake._generate_via_rest_api(self, messages, stop, run_manager, **kwargs)
526 payload["stream"] = False
528 # Make the REST API call using RestApiClient
--> 529 response_data = self._make_rest_api_request(payload)
531 # Parse the response and handle tool calls
532 return self._parse_rest_api_response(response_data, messages)
File c:\envs\py312_streamlit\.venv\Lib\site-packages\langchain_snowflake\chat_models\base.py:485, in ChatSnowflake._make_rest_api_request(self, payload)
475 session = self._get_session()
477 request_config = RestApiRequestBuilder.cortex_complete_request(
478 session=session,
479 method="POST",
(...) 482 verify_ssl=self.verify_ssl,
483 )
--> 485 return RestApiClient.make_sync_request(request_config, "Cortex Complete")
File c:\envs\py312_streamlit\.venv\Lib\site-packages\langchain_snowflake\_connection\rest_client.py:137, in RestApiClient.make_sync_request(request_config, operation_name)
134 return response_data
136 except Exception as e:
--> 137 SnowflakeErrorHandler.log_and_raise(e, f"sync {operation_name}")
File c:\envs\py312_streamlit\.venv\Lib\site-packages\langchain_snowflake\_error_handling.py:65, in SnowflakeErrorHandler.log_and_raise(error, operation, logger_instance)
63 log = logger_instance or logger
64 log.error(f"Error in {operation}: {error}")
---> 65 raise error
File c:\envs\py312_streamlit\.venv\Lib\site-packages\langchain_snowflake\_connection\rest_client.py:116, in RestApiClient.make_sync_request(request_config, operation_name)
114 # Use requests for sync HTTP
115 response = getattr(requests, method.lower())(**request_config, timeout=timeout, verify=verify)
--> 116 response.raise_for_status()
118 # Log response details for debugging
119 logger.debug(f"Response status: {response.status_code}")
File c:\envs\py312_streamlit\.venv\Lib\site-packages\requests\models.py:1026, in Response.raise_for_status(self)
1021 http_error_msg = (
1022 f"{self.status_code} Server Error: {reason} for url: {self.url}"
1023 )
1025 if http_error_msg:
-> 1026 raise HTTPError(http_error_msg, response=self)
HTTPError: 400 Client Error: Bad Request for url: *****************************************api/v2/cortex/inference:complete
During task with name 'model' and id '***********************************************'