Live data from Hacker News

The Problem with LangChain

minimaxir.com

71–80 of 97 posts

Re: The Problem with LangChain

#71
post #3

I added a Python library API to my LLM CLI tool recently which offers a very lightweight way to call models: https://llm.datasette.io/en/stable/python-api.html import llm model = llm.get_model("gpt-3.5-turbo") model.key = 'YOUR_API_KEY_HERE' response = model.prompt( "Five surprising names for a pet pelican" ) print(response.text()) Or you can stream the responses like this: response = model.prompt( "Five diabolical n…

This looks wonderful, a similar breath of fresh air to using the requests library for the first time. Really impressed by the amount of documentation too.

Is support for embedding and querying a corpus of custom text planned at all? 99% of what I wanted to use langchain for was building a chatbot that can answer questions about my own documents.

Re: The Problem with LangChain

#72
post #18

I'm in the exact same spot as the author just a few days in instead of months. Frankly I could see langchain is garbage software just by looking at the code. It still helps me get shit done fast to figure out how things are supposed to work. Sort of a cookbook of AI recepies. Once I have an approach narrowed down I'll rewrite everything on top of stuff langchain is supposedly wrapping. For now it's faster than tracki…

Yes! This is why I started working on AIPL. The scripts are much more like recipes (linear, contained in a single-file, self-evident even to people who don't know the language). For instance, here's a multi-level summarizer of a webpage: https://github.com/saulpw/aipl/blob/develop/examples/summari... The goal is to capture all that knowledge that langchain has, into consistent legos that you can combine and parameter…

This looks pretty rad. It is very expressive.

After scoffing at your shameless plug I read some of the code and was surprised to find it was not written in perl. Maybe some other options for the acronym could be:

* LASI (Language Artificial Specific Intelligence) * LLMML (Large Language Model Markup Language) * LLMMA (Large Language Model Metalinguistic Abstraction [this one is a stretch])

Re: The Problem with LangChain

#73

I use lambda over let over lambda (lolol)[1] like this (Clojure): (def chatgpt (-> (endpoint :chat "gpt-4" auth) (chat/set-opts [:endpoint] {:stream true}) chat/retry chat/catch-unkown-commands ;; chat/history chat/string-input (chat/file-io "file.txt" :stream true) #_(chat/preserve-ctx chatgpt-ctx))) These higher-level functions take as input the next function in the chain, and return a function that is responsible…

Would you mind explaining what's going on here? I know CLJ and read let over lambda, but not sure what your code is doing exactly without function definitions. I assume the first expr returns a context hashmap?

I was thinking about doing something similar with dynamic scoping in Emacs Lisp.

Re: The Problem with LangChain

#75
It is so trivial that it even gives me a headache to see the docs. People use it ‘because it’s easy’; it’s not, it’s quite badly done. And copilot can do the same from scratch for the stuff you want to use.

Re: The Problem with LangChain

#76
post #3

I added a Python library API to my LLM CLI tool recently which offers a very lightweight way to call models: https://llm.datasette.io/en/stable/python-api.html import llm model = llm.get_model("gpt-3.5-turbo") model.key = 'YOUR_API_KEY_HERE' response = model.prompt( "Five surprising names for a pet pelican" ) print(response.text()) Or you can stream the responses like this: response = model.prompt( "Five diabolical n…

Nice. Now all we need is a vector database atop SQLite.

Re: The Problem with LangChain

#77
What I'm most interested in is their long list of integrations.

If one can somehow reuse those integrations without even care about/use langchain, it's a massive time saver.

I haven't looked at the code so not sure how reusable they really are.

Re: The Problem with LangChain

#78
post #76
post #3

I added a Python library API to my LLM CLI tool recently which offers a very lightweight way to call models: https://llm.datasette.io/en/stable/python-api.html import llm model = llm.get_model("gpt-3.5-turbo") model.key = 'YOUR_API_KEY_HERE' response = model.prompt( "Five surprising names for a pet pelican" ) print(response.text()) Or you can stream the responses like this: response = model.prompt( "Five diabolical n…

Nice. Now all we need is a vector database atop SQLite.

Just implemented pgvector in an existing psql db, works quite well

Re: The Problem with LangChain

#79

I use lambda over let over lambda (lolol)[1] like this (Clojure): (def chatgpt (-> (endpoint :chat "gpt-4" auth) (chat/set-opts [:endpoint] {:stream true}) chat/retry chat/catch-unkown-commands ;; chat/history chat/string-input (chat/file-io "file.txt" :stream true) #_(chat/preserve-ctx chatgpt-ctx))) These higher-level functions take as input the next function in the chain, and return a function that is responsible…

Would you mind explaining what's going on here? I know CLJ and read let over lambda, but not sure what your code is doing exactly without function definitions. I assume the first expr returns a context hashmap? I was thinking about doing something similar with dynamic scoping in Emacs Lisp.

This is basically the middleware pattern except that each function is responsible for calling the next function in the chain. As a consequence, and contrary to the classic middleware pattern, the chain goes both ways, up to thhe api call, and down returning the result. The first expr is indeed special. It is in this context a level 0 function: it takes a context, does stuff, and returns the context. The other functions in the threading/-> expression are level 1 function: they return a level-0 function, in short they act like a factory. That returned function will be then threaded into the following level 1 function and so on. In the end the defined 'chatgpt' element is the whole chain. Call order is to be read from bottom to top.

Here's how level-1 functions are defined. 'ctx-fn' is just an indirection macro for 'fn' I haven't really used yet.

    (defn preserve-ctx [f & [at]]
      (let [mem (or at (atom {:ctx true}))]
        (ctx-fn
         :preserve-ctx [ctx]
         (if (->> ctx :it (cmd? :preserve-ctx))
           (do (case (:it ctx)
                 :preserve-ctx/get   @mem
                 :preserve-ctx/reset (doto {:ctx true}
                                       (->> (reset! mem))))
               (println (-> ctx :it) "done."))
           (-> ctx
               (when-not-> (-> :states :preserved)
                           (as-> $ (ctx-it (merge @mem $) (-> $ :it))))
               f
               (assoc-in [:states :preserved] true)
               (doto (->> (reset! mem))))))))

Edit: reading what I wrote, 'endpoint' is in fact a function returning function, except that since it's the "end" of the chain, it doesn't take a function to call next as argument.

Re: The Problem with LangChain

#80

Earlier quoted context omitted.

Would you mind explaining what's going on here? I know CLJ and read let over lambda, but not sure what your code is doing exactly without function definitions. I assume the first expr returns a context hashmap? I was thinking about doing something similar with dynamic scoping in Emacs Lisp.

This is basically the middleware pattern except that each function is responsible for calling the next function in the chain. As a consequence, and contrary to the classic middleware pattern, the chain goes both ways, up to thhe api call, and down returning the result. The first expr is indeed special. It is in this context a level 0 function: it takes a context, does stuff, and returns the context. The other functio…

Thanks. Have you found good libraries for working with openai api's in clj?
Post reply on HN