Marcin Bunsch

Marcin Bunsch

Code Mechanic at at Synthesis

Simple chat bot using custom documents with langchain

With the ChatGPT and LLM craze going on, I set out to build a simple question answering bot, however the flavor I was interested in was a chatbot that can answer questions about a custom dataset that I point it to. Additionally, I wanted to try langchain - it turned out to be a great idea. Langchain is fantastic for exploratory and prototype work, and I highly recommend it. You can easily connect different solutions. In my example, I needed:

  1. A dataset composed of text files with information I want to query
  2. A way to narrow down the context for the LLM model to answer the question
  3. A way to feed the LLM model with the context and query and get the answer

Langchain basically provides all the necessary building blocks to do this. I’ll go through the steps I took to build a simple question answering bot.

Continue reading >

Incident management in tech startups

Working in tech is great, until you get called at 3am to fight a fire because something in the tech you built just broke. These situations are stressful, tiring and in general - not fun. Ideally, they would never happen, but that’s not how the world works.

Over the course of my career, I’ve been in more than a few of these crisis situations, and I’ve learned a few things about how to prepare and deal with them. I kept building up notes, and I thought I’d share them with you.

I’m breaking up this process into 3 parts:

  • Preparation
  • Response
  • Recovery

We’re going to go over each of these parts, and I’ll give you some examples of tools that you can use to help you in each of these phases. I’m also going to share learnings from my own experience and tips on how to improve the process.

Continue reading >

C is truth

In a recent article, provocatively named Death to C, Jon Evans proclaimed that we should no longer use C, rather move to Rust for our low level needs.

The author proposes replacing C with Rust, which looks like a great tool to get awesome performance in a production application and sleep well at night not worrying about a segfault, which a tremendous advantage. He also wants to put C and C++ to rest:

Those old warhorses have served us well, but today they are cavalry in an era of tanks. Let us put them out to pasture and move on.

I understand not wanting to hand-write C code in production to minimise risk, but not abandoning it completely. Studying C gives you - as a developer - enormous benefits and skipping it is a mistake. In the introduction to Learn C The Hard Way, Zed Shaw has brilliantly explained why C:

The C programming language’s only failing is giving you access to what is really there, and telling you the cold hard raw truth. C gives you the red pill. C pulls the curtain back to show you the wizard. C is truth.

Of this quote, I especially like the “truth” bit - three words, with which Zed has captured the essence of C. It is a simple and elegant language, so simple that you hit the walls of gigantic complexity very early on, because you need to do the basic things yourself. It’s extremely difficult to write good, secure C code, which makes it very dangerous, and to quote Zed again:

Why use C then if it’s so dangerous? Because C gives you power over the false reality of abstraction and liberates you from stupidity.

C is the sharp, hurtful reality of how a computer really works, how memory is manipulated and how you’re really just moving bits around. Instead of avoiding it, let’s embrace it. C is difficult, because C is truth.

Refactoring with SOLID principles in mind

One of the reasons I built Dotz was to see how it would survive change. The first release was simple exactly for this reason - I planned to return to add more features and see how simple or difficult it would be. I managed to add a new feature to Dotz recently - when you connect the dots so that the lines form a shape (like a rectangle or square), all dots of the same color will disappear, adding to your score. As I introduced this feature, I reflected on this refactoring exercise and SOLID principles.

Step 1: Make it work

My initial approach was to take the easy road by modifying the Move class directly. I realized that it was missing some core functionality, such as getUniqueDotCount or getGroupedDots methods. I’ve also fixed an issue in destroyDots which appeared only after it was forced to remove a lot of dots from the screen.

At the end, I’ve expanded it to check if a square was present and schedule more dots of the same color for removal.

I coded, tested and released it. And that’s when it hit me. I did two things: I fixed issues within the Move class and I’ve modified its behavior. Now, fixing issues is fine. Modifying existing behavior in the same class has short legs - what if I want to add more functionality? What if I wanted to give a choice between game modes?

Continue reading >

Wrangling Service Objects with method_struct

Service Object is a pattern of extracting business logic into a separate “service”. It has gotten considerable traction in the Ruby ecosystem and is worth exploring. Steve Lorek described Service Objects in the following way:

A ‘service’ describes system interactions. Usually, these will involve more than one business model in our application.

As an example; we have a User model and this encapsulates a password. If a user has forgotten their password, the business rules dictate that we have to send them an e-mail with a link to reset it. This functionality is a service.

The CodeClimate blog post on refactoring fat models has a good rulebook on when to use this pattern:

  • The action is complex (e.g. closing the books at the end of an accounting period)
  • The action reaches across multiple models (e.g. an e-commerce purchase using Order, CreditCard and Customer objects)
  • The action interacts with an external service (e.g. posting to social networks)
  • The action is not a core concern of the underlying model (e.g. sweeping up outdated data after a certain time period).
  • There are multiple ways of performing the action (e.g. authenticating with an access token or password). This is the Gang of Four Strategy pattern.

I see Service Objects as a mutation of the Command pattern. They allow separation of business logic from models and controllers, but have further benefits in testing and composition.

Hello method_struct

At Base Lab, we’re implementing Service Objects using the method_struct gem. Let’s go through an example which illustrates the benefits of this approach.

Continue reading >