Skip to content

Why Archytas over LangChain

David-Andrew Samson edited this page Apr 26, 2023 · 15 revisions

Langchain's ReAct process does not work reliably with GPT-4 (or GPT-3.5)

langchain defaults to GPT-3 (Davinci), but GPT-3 has limited planning capacity and frequently fails to accomplish mildly complex tasks. GPT-4 is much more capable, and quite necessary to have a chance at doing most of the things that are useful but complex

langchain supports the GPT-3.5/GPT-4 chat-style API interface, but the prompting is not good enough. Frequently both fail models will fail to follow the expected langchain format (which would be parsed into thoughts/actions/input/etc.), causing langchain to crash.

Archytas is purpose built around GPT-4, and properly prompts it to generate output in the desired format. On the rare occasions GPT-4 fails to follow the format, archytas feeds the LLM sensible error messages that allow the agent to recover and continue using the correct format.

GPT-3.5-turbo support

unfortunately it seems GPT-3.5-turbo is a lost cause in any sort of ReAct loop:

  • No amount of prompting can convince it to output a valid json without any extra text outside the json body
  • handling the spurious text (e.g. via dirtyjson) allows it's responses to be parsed by Archytas, but it frequently gets stuck in infinite loops of repeating the same thing over and over, rather than continuing the ReAct process until the task is solved

Archytas has better tool ergonomics

Tools created in langchain must be a function that take a single string as input, and then return a single string as output. If the tool wants to use a different type or have multiple inputs, it must explicitly handle parsing the input string into the desired shape. And same for any output which must be manually converted to a string format so the LLM can understand it. Additionally, it is up to the tool developer to explain to the LLM any expectations for the input so that it can be parsed accordingly. This is pretty ad-hoc if you're doing anything more complex than string in, string out.

Archytas has a consistent interface for all tools it presents to the LLM: JSON values. Tools can take any number of arguments, that may be any valid python-equivalent of JSON objects

  • dict
  • list
  • int/float
  • bool
  • str
  • None

When the LLM is interacting with tools, Archytas will automatically parse/convert the LLM string into the specified signature for calling the tool. Then when the tool returns it's response (if any), archytas will convert it back into a string the LLM can understand. This means that your tool functions can look much more like regular functions with multiple arguments, typing, etc. and aren't forced to conform to the def mytool(s:str) -> str interface required by langchain

Archytas effortlessly works with stateful tools

If your python-fu is strong then yes you can certainly create a langchain tool that has state (e.g. by making a class instance, and then pulling one of the bound methods out to be the tool). However Archytas can handle Class tools/toolsets, i.e. tools that maintain some sort of internal state.

Graceful error handling

archytas tools can raise exceptions, which then get caught and shown to the LLM in a consistent manner. In the Archytas ReAct loop, the LLM can then seamlessly recover from errors encountered while using tools, based on the exceptions. (TODO: lookup how langchain handles exceptions during tool usage)

Archytas generates better prompts

(in langchain, when making a tool, you had to explain in detail how your tool worked so the llm could use it. but it wasn't really obvious how to explain the precise format that inputs/outputs should take.)(archytas has a very clear paradigm that is responses are parsed as json, tool input arguments are extracted from fields in the json. prompt for this is generated automatically assuming the tool is type annotated and has a matching docstring)

Archytas is simpler+easier to peek inside

Clone this wiki locally