Knight Technologies LLC

The misadventures of a veteran technology professional.

  • Welcome to my first post on the newly establish site for Knight Technologies LLC. In the coming days, I will begin regularly posting blogs on topics that are fresh on my mind and relevant.

    Stayed tuned!

    3/13/2024

    It has been nearly a year since, I wrote the first blog post on Knight Technologies LLC. Many things have changed since then and honestly, I got terribly distracted by searching for full-time employment, finding it, and then leaving it because I found myself in another toxic environment. Fortunately, through networking I was able to secure a new position in a very large tech company which will afford me more time to devote to our cause.

    Here are a few things that I have neglected to blog about:

    [starbox]

    +
  • We are very excited to announce that we have launched an AI side of our technology consulting business. We call it Knight Tech AI and you can find out more by visiting –> knight-tech.ai.

    + , ,
  • I see a lot of mixed emotions when it comes to incorporating AI into the workflow of a software developer. Although I am not worried about Generative or Agentic AI taking my job (have you seen Devin in action?), I decided a couple of years ago to embrace it and make AI another tool in my toolkit. On my current project, we’ve been given access to GitHub Copilot which I use both in Visual Studio Code and Visual Studio 2022. It’s been a fun ride thus far. 

    Here are the 7 ways I use Generative AI daily: 

    1. Code completion and suggestions – This feature somewhat existed before I started using AI, however, it is much more sophisticated nowadays. Although I’ve been writing code for over 30 years, I love the fact that suggestions are given, and I don’t have to rummage around on Stack Overflow to find just the right syntax. Make no mistake, sometimes Copilot gets it wrong, but that’s why you need an experienced developer to oversee code generation by LLMs. 

    2. Training – I’ve been a C# developer for the last 25 years and have been building web-based solutions since the days of classic ASP (VBScript). React and Angular are not new to me but sometimes I need to better understand syntax or a concept when something isn’t working as expected. The fact that I can highlight syntax and ask for help right in the codebase is fantastic. I no longer need to spend a lot of time reading countless articles or posts to get the answers I need. 

    3. Creating T-SQL statements – At this point in my career, I would consider myself an expert in SQL. I’m a huge fan of using ORM’s whenever I can but sometimes one just needs some good old-fashioned T-SQL to get the job done especially with using things like Dapper. Being able to copy the needed columns right from a Jira story, creating a simple prompt explaining table structure and joins, pasting in the columns, and then hitting enter is instrumental and a huge time saver. 

    4. Translations – One of the requirements for the application I’ve been working on for the last several months, is the UI must be available in English and in Spanish. Obviously React takes care of switching between the two languages by way of translation files on the front-end and the back end will emit data in both languages as needed. Another area where Generative AI shines, is handling the translations. I can choose any text that will be displayed in the UI, highlight it, and prompt with “use a translation here” and Copilot will create the proper syntax. Then I simply switch over the English translation file, create the entry, and Copilot will typically suggest the correct message. I copy that and then drop that into the Spanish translation file and then prompt Copilot to translate the English message to Spanish. Voila! Just for fun one day, I asked for a translation from English to Klingon. Copilot deftly honored my request with a perfect translation. Worf, son of Mogh, would approve! 

    5. Documenting code – I am a huge proponent of documenting code especially on the C# side of the house. A simple prompt produces excellent documentation. I think back to the many times I’ve been refactoring entire codebases and had to hand type every XML comment. Now I can use a prompt to have an entire class file documented in my preferred style. 

    6. Creating class files – This is another huge time saver especially if one is using models and DTOs in a project. I will typically copy and paste documentation if available to provide the properties and then have Copilot do the heavy lifting with not only creating a model but also the DTO and conversion methods for each class type. And yes, I ask for documentation to be created, too. 

    7. Creating fluent migrations – Finally another area that has been a huge time saver for me on this project is having Copilot create the syntax for fluent migrations. If you aren’t using FluentMigrator, I would encourage you to check it out. FluentMigrator makes creating SQL Server assets such as tables, columns, and constraints in code incredibly simple. Couple that with having Copilot write the syntax including defensive programming techniques like checking for the existence of a table or column before making changes and you have a well-oiled machine so to speak. 

    The list above demonstrates a few ways that I use Generative AI daily to make my job as a Senior Software Engineer easier. I don’t feel like AI will replace my job as I see it just being another tool in my vast coding arsenal. Will it replace junior developers? I don’t see that happening either because in many ways it behaves much better than a junior developer and does what it’s told. 

  • I am a firm believer in leveraging patterns and practices when I write code. Actually, I am fanatical about it. In my current role, I have had to refactor the worst code I have ever seen in my 27 years of software development. The code has been so bad at times, I nearly have gone code blind. During my many refactoring passes, I had to overcome several bouts of severe mental anguish to the point I wanted to walk away from it all. I am being a bit overly dramatic, but the experience really sucked.

    Fortunately, I survived the pain and torture of refactoring what I call extreme functional spaghetti coding. Some of the methods I refactored were over 1000 lines of code. Nested “if” statements, abbreviated variable names, and pseudo business logic were everywhere. Best practices like DRY (Don’t Repeat Yourself) and SOLID (more on that in a minute) must have been completely foreign concepts to the so-called developers who had been touching the code. And then there was the constant copying and pasting of really bad code. Just when I thought I had finished refactoring, I would find more things to address.

    Then there was the heavy use of try/catch statements. Instead of leveraging try/catches for true error handling, these were used to swallow the errors generated by the horrendously sh*tty code. Yes, I said it. I couldn’t help myself.

    Here’s a contrived example:

    try
    {
        // Really bad code that throws random errors.
         string ABC = null;
         string DEF = "";
         ABC = GetABCData();
         if (ABC.Contains("Something_"))
         { 
           // Do something with ABC value
           DEF = ABC.Substring(0, ABC.IndexOf("_"));
         }
    }
    catch
    {
        // Swallow the error because our logs are filling up with errors.
    }
    

    I’m a C# developer by default which is truly a wonderful language to code in. Granted I’ve been using JavaScript for just as long including just about every framework that’s out there. I’m actually fairly adept at React and Angular using TypeScript. However, my true passion is object-oriented programming in C#. After many months of refactoring this particular solution, which by the way is a Dynamics 365 plugin that provisions SharePoint Online infrastructure, I finally had things in order. Now when I need to find and correct defects (yes, I have a defect or two every now and then) I know exactly where to go and what layer of the solution architecture things reside in.

    What does SOLID mean to me?

    Interestingly enough, with the many software developer interviews I have had the term SOLID rarely comes up. When I do the interviewing, however, it is one of the fundamental concepts I hope a candidate is very familiar with. And I don’t mean reciting what the acronym stands for which is Single responsibility principle, Open-closed principal, Liskov substitution principal, Interface segregation principle, and Dependency inversion principle. I won’t go into each one, but I will explain how I apply these 5 principles in a practical way when I code solutions. I would encourage the reader to check out this Wikipedia article.

    Single Responsibility Principle

    For me, the first principal could also be called separation of concerns. When I create classes and write methods, I keep this in the forefront of my mind. Each method should do one thing, this even includes the way I handle accessors to my classes. A public method should call a private member which supports one of the four pillars of object-oriented programming principles called Encapsulation. This principal also translates to layers of a solution and the patterns that support it. I am a huge fan of having a service layer that uses a repository pattern for data access. Each service and repository only handle one type and one responsibility.

    Open-closed Principle

    The second principal, Open-closed, for me describes using inheritance and interfaces to establish base or core behaviors of a class. The base classes are not open to modification if a child class needs new behaviors. However, one might encounter a situation where the behavior should bubble up to the interface and the base class. Think DRY (Don’t Repeat Yourself).

    Liskov Substitution Principle

    This principle is just as fun to say as it is to implement. Two pillars of OOP, polymorphism and inheritance are addressed in this principle. With the use of interfaces that define the behaviors of base classes, you should be able to swap concrete implementations without breaking code. I was going to attempt to provide a concrete example of this principle, but I will save that for another blog post.

    Interface Segregation Principle

    Bearing in mind the tenants of the single responsibility principle, this principle enforces that from an interface perspective. When coding solutions and using interfaces (and I hope you do), you should not force behaviors on classes that won’t use or need them. In practice, I strive to keep things generic as possible while leveraging interfaces. The best example of that would be my use of ICollection<T> when returning collections of objects of a particular type. I do this in lieu of concrete implementations like List<T>. They both will get you to the same destination, but I like to live by principles and good design patterns whenever possible.

    Dependency Inversion

    For me, this principle translates directly to dependency injection. To me it’s where the rubber meets the road in terms of the other principles. Interfaces are used to define behaviors in concrete classes that handle the heavy lifting in a .NET solution. Those interfaces are then injected into the constructors of classes (or sometimes in methods) to receive dependent services to do their jobs. Those services then should inherit from an abstract base class each focusing on a single responsibility. I think that is the true essence of DRY principles.

    Putting It All Together

    I hope this post has given you an idea of how to use SOLID design principles in a practical way and how those principles translate to the way you might structure your solution using the four object-oriented design pillars – Abstraction, Encapsulation, Inheritance, and Polymorphism.

    One Final Thought – SOLID is not YAGNI

    Using SOLID design principles is paramount to delivering solid software solutions and is absolutely necessary for success. Some might think You Ain’t Gonna Need It (YAGNI), but you truly do.

    Thanks for reading my post!

    + , , ,
  • Working remotely is not a new thing for me. I’ve been a full-time telecommuter since 2010 and prior to that when I was a technology freelancer back in 2005. Working remotely works for me and in this post, I will explain why.

    The COVID-19 Pandemic changed many things for the world, one of which was introducing many to working remotely. For a lot of people, this was a blessing in disguise and for others that weren’t prepared, it was a burden. At that time, I was working for a major bank that didn’t exactly embrace remote work but at that time they were forced to comply. Fortunately, I had been grandfathered in under a remote working arrangement when I joined the bank as a full-time employee and was accustomed to working in that fashion.

    Don’t get me wrong, not every person or position is a good fit for remote work. However, for those of us who work in technology or in jobs that don’t require being physically present, working remotely is the superior option. The arguments against remote work, I feel are unfounded, such as this notion that being in person and sitting with your team increases productivity. I find that going into an office has quite the opposite effect.

    For me, working remotely is all pros and no cons. When Wells Fargo started pushing the hybrid thing really hard, the argument for sitting with your team was a complete fallacy. First off, the teams I worked on were geographically dispersed not only by cities but also by locations within cities. Secondly, Wells Fargo had invested millions (billions?) in kicking out tenants and reclaiming space in their properties that were outfitted with disparate workstations. First come, first serve, unassigned workstations. How could one sit with their team in that scenario?

    Why does working remotely work for me? For starters, it is good for the environment and my health. Throughout my career when I was a consultant, I had some grueling commutes that took sometimes 3 hours out of my day. For some of that time, I was driving a gas guzzling Cadillac Escalade which got around 10 MPG. I recall one of my commutes in Texas from Round Rock to Austin was just over an hour. Fortunately, I carpooled with a co-worker which saved a bit of money on gas. My all-time favorite commute was in Dublin, California when I worked for E-Loan. It was about 5 minutes and I used an electric Zappy scooter to get there.

    When in Houston, I sometimes rode the bus and for a while I had a gas-powered scooter. Thinking back on riding that thing over an hour each way to downtown Houston in heavy traffic makes me question my sanity at that time. My situation while living in Boca Raton was similar. I had a gas-powered scooter, but my commute was only 15 minutes with little to no traffic. When in Fort Lauderdale, I had a 3-mile commute, and I rode a nice Cannondale Urban bike which eventually got stolen. Man, I loved that bike.

    That’s enough reminiscing about my past commutes to work in an office. Let me share some other benefits of working remotely.

    Availability

    I’m available to work 24x7x365 if needed. It’s not that I want to work all the time, but I can recall working at the bank and deploying code which typically was done after working hours and often on the weekends. I couldn’t imagine working all day in the office, going home, and then coming back to the office to perform the release. Most of the releases, we’d do could span 12-16 hours over the weekend. At least, I could suffer through them in the comfort of my home office.

    Power Naps

    Another great perk of working remotely is taking power naps. Yes, I said power naps. I suffer from severe sleep apnea and sometimes I need to take a 5-to-10-minute nap on occasion. I would not feel comfortable doing that if I were working in an office.

    Coffee

    I drink a lot of coffee during the day, and I like it a certain way. Working from home affords me a supply of unlimited coffee without Starbuck’s prices. And a nice cup of Assam or Gunpowder Green tea is available at a moment’s notice and is just a quick trip downstairs to the kitchen.

    Incense, Music, and Cursing Loudly

    Sometimes technical work can be very frustrating. I like to burn incense to help calm me down and help me focus on my work. I can play any music from my vast collection of MP3s and LPs as loudly as I want. And yes, when something I am working on is not behaving nicely or meeting my expectations, I can curse as loudly as I please.

    Staying Healthy

    Aside from the health benefits of not having a commute, I find that working remotely helps me stay healthy. There are no worries about catching the crud, colds, the flu, RSV, or even worse COVID-19 when one works from home. Granted I don’t go anywhere period, and I mask up when I do. Not going into an office is the healthier option. Also, I have a home gym downstairs that I can use during my lunch break. In my home office, I have two standing VARIDESK workstations with multiple monitors. And then there is my fancy gaming chair which is perfect for taking power naps in.

    I eat better when working from home as I can just slip downstairs to make breakfast or lunch while still attending to my work duties. I’m not doing what I used to do which was taking a two-hour lunch break to escape being in an office. Most days, I eat at my desk while I am working.

    A big part of staying healthy for me is not only a physical thing, but it also a mental thing. My partner works from home and it’s wonderful to see her in person to share some news or sometimes my frustrations. Several times a week, we have lunch together in our wonderful home which is yet another perk when working remotely. Then there is our GSP who often comes up to my office to say hello and to see what I am working on. She’s a sweet girl and I’m always delighted when she pays me a visit.

    Working Remotely Works for Me

    Working remotely works for me, and I am grateful to be a in position to enjoy the benefits of this working style. Despite the recent Administration’s stance on working remotely and the many companies that are forcing workers to return to offices, I stand firmly behind the benefits to the environment and people’s mental and physical health. Granted many people have abused the privilege but I think those people behaved the same way when they worked in an office.

    Thanks for reading my post! By the way, it is also available on LinkedIn.

    + , , ,
  • Trying to find something new to do has been a long and hard journey over the last couple of years for me. I’ve been very fortunate in my nearly thirty years of working in technology and can’t recall a time that I’ve been unemployed. I survived the Dotcom boom and bust, traveled the US for technology gigs, been a freelancer, a consultant, and finally settled down for a long stint at a major bank.

    After devoting 13 years of my tech career to a very toxic company, I found myself totally burned out and decided to start another freelance technology consulting business. I was very confident I could repeat my successes from the past. I was wrong. Granted it was very liberating and enjoyable being a content creator and leveraging Generative AI to assist me, but bills must be paid, and I was burning through my savings.

    Most days I was shooting videos for Bad Gnome Gardening along with editing and uploading them to one of the three YouTube channels I was maintaining at the time. I acquired a few subscribers but not the amount it would take to make a living. In addition, I was writing regular blog posts for that endeavor while also creating technology videos, AI generated podcasts, and content for Knight Technologies. Along the way, I also managed to create an e-commerce site in an attempt to sell AI generated images. There were so many things I wanted to do including creating mobile apps which unfortunately never materialized.

    After a few months, I decided it was time to find another paying gig. It was the end of the Spring in 2023 and from what I could see the technology job market was a barren wasteland. Despite my many years of experience and marketable skillset, I was finding little to nothing in terms of software developer roles. After a couple of months of searching, I ended up with a handful of interviews and finally an offer from a small government contractor.

    Little did I know that I was entering an entirely different world then I had experienced while working in the banking industry. Don’t get me wrong, the banking environment was very toxic. But this new world of working for the government was different. Contracts are won, protested, recompeted, and milked. Yes, I said milked. Getting work done in an efficient manner using industry standards and best practices is sorely frowned upon (and a totally foreign concept).

    Although I was a Senior Sofware Developer and a lead, every attempt I made to foster a culture of collaboration and innovation was met with vicious backlash from very junior “software developers” and management. I was disrupting the gravy train for everyone, and I ended up leaving after about 9 months. I’m so glad I did.

    Shortly after, I ended up joining a much larger company on a different government contract. Things have been calmer and much more tolerable; however, the contract was recently recompeted and has been awarded to a different much smaller company. A majority of the original team was cut due to funding (not a bad thing necessarily). Most likely I will be contacted by the new company with an offer to work for them. I’m pretty sure at this point that I will take an offer if one is made.

    Knowing the state of the current contract, I recently restarted the job search machine as I call it. Part of that process involves updating my resume and uploading it to all of the various job sites including Dice, Indeed, and CareerBuilder. Networking has never really been something I did by choice so leveraging LinkedIn is a new experience for me. As usual, I never hear back from most places, but I have received a few turn downs for positions that aren’t exactly a good match. I tend to apply for anything that resembles my skillset.

    I will say that this time around, the tech job market looks really good. Applying for jobs is pure drudgery; however, it’s very encouraging to have hundreds of positions available across the various job boards. Job hunting is definitely a numbers game for me and the more I can apply the better I feel about landing something that I can live with for a while.

    Turning on the job search machine does have side-effects. Now I have to answer my phone whenever it rings. I get a fair amount of “scam” calls but some of these could be a job prospect. In addition, I’ve been getting a lot of email with positions that are not even remotely related to tech. My favorite thus far has been this one:

    We are a Raleigh, NC based company partnered with a Recruitment Marketing Agency to connect qualified candidates with the U.S. Secret Service.

    Our role is to guide candidates through the application process to ensure they meet qualifications and are enthusiastic about the opportunity.

    If you’re interested, please reply with “YES,” and I’ll assist you in applying for the position.

    Job Title: Uniformed Division Officer

    Location: Washington, DC

    Salary: $75,134 – $129,251 per year

    Working for the Secret Service might pay well, but I think I’m too old for that kind of work. Needless to say, I’m not interested in changing careers just yet. I think I will stick with software development.

    Thanks for reading! By the way, this post is also available on LinkedIn.

    + , , ,
  • Yes, I will admit it. I suck at aptitude tests. I’ve been in technology for literally 41 years and have worked in many facets and industries throughout my career. And yes, I hit the calculator button on my keyboard to do that math. From a very early age, I’ve had a knack for those things most consider to be technical or hard. In fact, I was tested for gifted and talented in elementary school and was often picked on for being a “brainiac”. 

    At the age of 12, early one morning, my father handed me a device which was slightly larger than a brick with a small red LCD screen and a bunch of buttons. It was a hand-held computer that his company issued to him to do inventory. He was a route salesman and very good at what he did. After he handed me the device, he said I’m not going to be able to figure this out and I need you to program it for me. A year later, he realized I had the knack for computers and purchased a TRS-80 Model III personal computer. 

    Shortly after receiving this amazing device, I was not only reverse engineering games that I had saved up lawn-mowing money to purchase, but I was also writing text-based adventure games in BASIC. I can also remember purchasing computer magazines for the free games and would spend hours typing in long strings of characters to try the latest game (Z80 anyone?). I liked BASIC much better. 

    In junior high school, I was showing my teachers how to use their Apple IIe computers and was writing code every chance I could get. This would include banging out code on any Commodore 64 I would encounter in stores like K-mart. Then high school rolled around, I got a job at McDonald’s and an old car which changed everything. 

    I hated school, especially high school, as I excelled in all of my classes and was often the target of bullying because I was intelligent. Many of my teachers would recognize this and would give me extra work to feed my brain which made the bullying worse. I would read anything I could get my hands on and often would read an entire book in one evening. 

    Soon I was promoted to assistant manager at the local McDonald’s in which I worked, the money back then was decent, and I was able to support myself although I lived in a small trailer on my parent’s property. Prior to my senior year of high school, I had aspirations of attending UNLV on a computer science scholarship. However, I was so fed up with school, I decided to make management my career. 

    Several years go by and I have had a successful career in fast-food and retail management often times holding either the first assistant or store manager roles. I also had a knack for sales and ended up working for various companies as an inside salesman and even as an outside salesman selling hydraulic seals to huge drilling companies. For a short period of time, I also did automotive body repair work and sold tropical plants door to door. My most interesting position during the years directly after graduating high school was working for the National Institutes of Health entering grant data into an application called HyperCard. 

    There wasn’t a lot of money in sales, and I got burned out fairly quickly chasing the carrot. While I was working for one of the places in which I was doing outside sales, I would often pitch in with helping figure out issues with their BNC network, installing new computers, and software. Eventually I found myself conducting photo shoots of products, producing brochures, catalogs, and even newsletters. Quickly I moved onto helping with extracting data from their AS-400 as the in-house technical guy couldn’t make it work. I started to feel that passion again that only computing could seem to bring. 

    One day, I decided to reinvent myself. I brushed up my resume and applied for a MIS Management role at a small company that sold prepaid phone cards and landed it. I handled managing all network infrastructure, computer hardware, and all aspects of the help desk. Applying what I had learned from managing people and establishments served me well. 

    If you’ve made to this point without bailing, thank you. Honestly my left hand is numb from typing out my life’s story albeit the Readers Digest version. Now you have a bit of my history and my humble beginnings as a technology professional. Without boring you with the nitty-gritty details, I went on to hold positions as director, manager, network engineer, lead software engineer, freelance technologist, managing consultant, and many other positions in between. I’ve had clients from all over the world including Iceland (that’s a story for another time). Let’s just say that I am a seasoned professional and have just about done it all. 

    After getting fed up with Wells Fargo after 13 years, I once again started my own tech company, Knight Technologies LLC with the hopes of being my own boss again. Things weren’t moving fast enough, and I ended up joining a small company that staffs government contracts and became a Senior .NET Developer for the USDA. Obviously, I took a huge pay cut, but with that came less responsibilities and I could focus on what I love the most about technology which is building software solutions utilizing patterns and best practices. 

    Currently I work for Guidehouse on a different USDA contract which is ending soon. There aren’t many things I hate in this world, however, finding something new to do ranks #1 on the list of things I hate the most. I often will make jokes about choosing between being physically tortured and finding a new job. I’m more comfortable with the former. It’s not that I’m not capable or don’t have the skills to find something new. I interview very well and have no issues with most interview questions. Mostly because I am typically the one doing the interviewing and screening applicants. 

    Aside from the pure drudgery of resume blasting across the various job boards and answering the same questions over and over again, there is the long wait and uncertainty. The worst part, however, for me, which is another thing I truly hate about the process, is those aptitude tests. 

    Yes, I will begrudgingly take them and answer all of the questions like “if Jane can work on Tuesdays, but not with Nick who works on Thursdays, when can Laura work?” or “which shape does not belong in this group”. Or, all of the math questions dealing with how many houses can John build if he can build 1.5 houses in a week. If John hires Larry, and Larry can build a house in two weeks. How many houses can they build together in a month in a half. Arggh! 

    I suck at aptitude tests, but I have had a highly successful career in technology across many verticals. Although I consider myself an expert in C# coding, I can read and understand many other programming languages easily. I can refactor just about any code base to introduce concepts like SOLID, DRY, and true object-oriented principles. I can figure out and correct obscure bugs across layers of infrastructure leaving clean code while reducing technical debt practically in my sleep. And I am adept at building teams and mentoring developers at all levels. 

    I will close this incredibly long blog post with this. Currently I am looking for something new to do and I am really motivated to find the right position. I really don’t want to go to work for a place that just hires warm bodies that can pass an aptitude test. Many others like me will agree that companies that use these types of tests to cull the flock will be left with people that are good at taking tests. I’ll take my skills, vast knowledge, and experience to a company that values people and what they can do and what real-world technology problems they can solve. The types of problems that don’t require knowing what shape comes next in a sequence or what days Jane can work. 

    Thanks for reading! 

    P.S. This is post is also available on LinkedIn.

    + , , ,
  • Note: This post was composed with Mistral 7B by using LM Studio and edited by a human.

    In the ever-evolving world of language models (LLMs), Shawn, the chief software developer at Knight Technologies LLC, has been conducting fascinating experiments in world of LLM and NLP using LlamaSharp. This open-source package allows developers to work with various LLM’s, including OpenAI’s GPT-3, along with offering integration with Microsoft’s semantic kernel. In this blog post, we will delve into Shawn’s journey as he navigates the complexities of leveraging these models and shares his insights on creating a stable version of SwankBOT for our upcoming Garden Guru project.

    LlamaSharp: A Convenient Library for LLM Experimentation

    LlamaSharp, an open-source C# wrapper around LLama.cpp, has proven to be a convenient tool for Shawn’s experiments with LLMs. This versatile library allows developers to work with multiple models and use them according to their specific needs. By using LlamaSharp, Shawn was able to explore the capabilities of various models from HuggingFace and gain valuable insights into how they can be applied to real-world scenarios.

    Microsoft’s Semantic Kernel: A Bleeding Edge Option with OpenAI Leanings

    During his experiments, Shawn also dabbled in Microsoft’s semantic kernel, which will work with other LLM’s but is bleeding edge and has a slant towards OpenAI considering Microsoft’s investment in it. While this presented some limitations, it did provide a unique opportunity for Shawn to delve deeper into the intricacies of LLMs and their potential applications. However, as OpenAI’s services come with a cost, Shawn had to find alternative solutions that would support semantic kernel functions without incurring additional expenses. Although this approach seemed encouraging, Shawn quickly found that the features that semantic kernel offered require a participating AI service to act on them. An attempt to use kernel memory also proved to be frustrating as the “memories” never finished loading.

    Introducing LM Studio: A Powerful Platform for LLM Experimentation

    After exploring various options, Shawn turned his attention to LM Studio, an innovative platform that can host various LLMs. This powerful tool allowed Shawn to further his experiments with attempting to create a stable version of SwankBOT. By leveraging the capabilities of LM Studio, Shawn was able to overcome the challenges posed by Microsoft’s semantic kernel and continue his experiments with LLMs by continuing running his experiments locally without incurring a charge for every conversation. Thus far this approach is great for experimenting but is not at all portable and not suited to run within an application.

    The Transcriber Solution: Capturing Thoughts in MongoDB

    It is worth noting that one of Shawn’s experiments for capturing data from a hand-written journal was a complete success. In an effort to streamline the data collection process, he developed a transcriber solution that utilized Microsoft’s Cognitive Services. This innovative tool captured transcribed material as “thoughts” in a MongoDB database, allowing for easy access and analysis. However, attempting to access this information without passing in a prompt has proven to be problematic. Many great things came from this experiment which included several private NuGet packages such as a MongoDB API to help encapsulate features required by the projects using this particular datastore paradigm.

    Anything LLM: A Versatile Tool for Chat-Based Interactions

    To effectively mine the data captured by the transcriber solution, Shawn turned to Anything LLM, which is a platform that can read documents from the file system and store them in a vector database. This versatile tool allowed Shawn to “chat” with the data stored in the vector database and retrieve relevant information on demand. By leveraging the capabilities of Anything LLM, Shawn was able to create a more efficient and user-friendly system for accessing and analyzing data which is helping to shape his future approaches to handling LLM concerns for SwankBOT.

    The Road Ahead: Developing a Stable Version of SwankBOT for Garden Guru

    As Shawn continues his journey exploring the world of LLMs, he remains focused on developing a stable version of SwankBOT for our upcoming Garden Guru project. By leveraging the insights gained from his experiments with LlamaSharp, LM Studio, and Anything LLM, Shawn is well-positioned to create a powerful tool that will revolutionize the way we interact with gardening information.

    In conclusion, Shawn’s experiments with various LLMs have provided valuable insights into the potential applications of these cutting-edge technologies. As we continue to refine and improve our tools, we are confident that SwankBOT will become an invaluable resource for gardeners everywhere. Stay tuned for more updates as we progress towards the launch of Garden Guru!

    [starbox]

    + , , ,
  • Note: This post was written by a bot using LM Studio with the Mistral 7b model.

    As a seasoned developer in the field of large language models (LLMs), I’ve recently encountered some unexpected roadblocks while attempting to run an LLM on Windows 11. In this blog post, I’d like to share my experiences and the valuable insights I gained throughout this educational journey.

    My initial plan was to utilize LLamaSharp, a popular open-source library for running large language models, as part of my project. The integration with the semantic kernel seemed promising, making it an appealing choice. However, after several attempts, I encountered numerous challenges that hindered my progress.

    The first hurdle was setting up the environment on Windows 11. Despite following various guides and troubleshooting steps, I was unable to get LLamaSharp running smoothly. The compatibility issues between the library and the operating system proved to be a significant obstacle.

    Determined not to give up, I decided to explore alternative options. After extensive research, I stumbled upon LM Studio – an excellent local LLM platform that runs directly on your machine, without requiring external cloud services. This choice ultimately proved to be a game-changer in my project.

    With LM Studio as my foundation, I began refactoring my codebase and removing the dependency on LLamaSharp. Instead, I opted for Microsoft’s libraries to create plugins that could retrieve data from a local MongoDB datastore. This not only improved compatibility with Windows 11 but also made my project more versatile in terms of future integrations.

    Finally, I performed thorough testing on OpenAI – an essential tool for evaluating the performance and accuracy of LLMs. The results were impressive, and it validated my decision to switch from LLamaSharp to LM Studio and Microsoft’s libraries.

    In conclusion, the process of running an LLM on Windows 11 was filled with challenges that required adaptability, patience, and a willingness to learn. While encountering obstacles with LLamaSharp, I discovered the value of LM Studio as a powerful alternative and embraced Microsoft’s libraries for plugin development.

    As developers, we all face setbacks and unexpected hurdles – but it is important to remember that every challenge presents an opportunity to learn and grow. My experience running an LLM on Windows 11 has been invaluable, and I am confident that the lessons I’ve learned will serve me well in future projects.

    [starbox]

    + ,
  • This was written by SwankBOT Guru:

    Describe the purpose and structure of the following XML comment in C#:

    /// <summary>
    /// Provides an interface for an animal.
    /// </summary>
    public interface IAnimal 
    {
    }

    The purpose of this XML comment is to provide a brief summary of what the code does or what it represents. In this case, the code defines an interface named IAnimal that provides an interface for an animal. The comment includes two parts: a <summary> section and a <remarks> section.

    The <summary> section provides a concise description of the code’s purpose or functionality. It should be short and to the point, giving users an idea of what the code does without going into too much detail. In this case, the summary states that the IAnimal interface provides an interface for Dog.

    The <remarks> section is optional and can provide additional information or context about the code. It should be used sparingly and only when necessary. In this case, the remarks state that the IAnimal interface is empty, which means it doesn’t have any methods defined in it.

    Overall, XML comments like this one are important for documenting code and making it easier to understand for other developers who may be working on the same project or using your code.

    ~ghost

    [starbox]

    + , ,
  • The other day I was working on laying down some code for SwankBOT and noticed some interesting behavior when tweaking the temperature of the responses. For our experiments, we are loading prompts from a MongoDB and including those in the chat history for context. From a coding perspective, we went with .NET 7.0 utilizing some typical OOP patterns in C# to host the bot in a console application. Currently we are using LlamaSharp with a Vicuna model for pair programming experiments with AI. Here were the simple instructions to SwankBOT –> Please introduce yourself

    Hello, I am SwankBOT! I love writing code.
    Now write some code! Remember you must program against the interface only (or other abstract base class)! Also provide XML Documentation Comments. Your code must follow Microsoft's C# coding standards: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/inside-a-program/coding-conventions
    First let's write some interfaces.
    SwankBOT, I need you to write an interface called IAnimal.
    IAnimal requires a property called Name and a method called MakeNoise()
    SwankBOT, provide XML Comment for IAnimal.
    Please write code!
    SwankBOT wrote some code but it is not yet ready. Fix the following issues:
      X IAnimal Interface should have an interface for Zoo.Swan which was specified as a parameter. The interface should only have properties and methods needed by that concrete class.
    Write code for IAnimal
    /// <summary>
    /// Provides and implementation of <see cref="IAnimal"/>
    /// </summary>
    public interface IAnimal
    {
        /// <summary>
        /// Gets name.
        /// </summary>
        string Name { get; }
    
        /// <summary>
        /// Provides a method to make noise
        /// </summary>
        Task MakeNoise();
    }
    SwankBOT, I need you to write an interface called IDog. This should not be abstract.
    IDog should have a property called Breed and it should inherit from IAnimal.
    SwankBOT, provide XML Comment for IDog.
    Write code for IDog
    /// <summary>
    /// Provides an interface for Animal.
    /// </summary>
    public interface IDog : IAnimal
    {
        /// <summary>
        /// Gets breed.
        /// </summary>
        string Breed { get; }
    }

    Next we want to write a concrete class for Swan.
    A Swan’s Name is “Swank”
    A Swan’s Breed is “Hannah”
    Swans make noise by Tooting!

    SwankBOT, I need you to write an interface called ISwank. This should not be abstract.
    ISwank should have a property called Name and it should inherit from IDog.
    SwankBOT, provide XML Comment for ISwank.
    Write code for ISwank
    /// <summary>
    /// Provides an implementation of <see cref="IAnimal"/>
    /// <inheritdoc/>
    public interface IZoo<T> where T : class, new()
    {
        /// <summary>
        /// Gets or sets Animal.
        /// </summary>
        T Animal { get; set; }
    
    }
    SwankBOT, I need you to write an interface called ISwank. This should not be abstract.
    ISwank should have a property called Name and it should inherit from IDog.
    SwankBOT, provide XML Comment for ISwank.
    Write code for ISwank
    /// <summary>
    /// Provides an implementation of <see cref="IDog"/>
    /// <inheritdoc/>
    public class Swan : IDog
    {
        private readonly string name;
        public Swan()
        {
            this.name = "Swank";
        }
        /// <summary>
        /// Gets or sets name.
        /// </summary>
        public string Name => name;
    
        /// <inheritdoc/>
        public string Breed { get; } = "Hannah";
    
        /// <inheritdoc/>
        public async Task MakeNoise()
        {
            await Console.Out.WriteLineAsync("Tooting!");
        }
    }

    Now let’s create a method in Zoo that does some basic operations on swans:

    SwankBOT, I need you to write an interface called ISwank. This should not be abstract.
    ISwank should have a property called Name and it should inherit from IDog.
    SwankBOT, provide XML Comment for ISwank.
    Write code for ISwank
    /// <summary>
    /// Gets or sets animal.
    /// </summary>
    public IAnimal Animal { get; set; }
    
    /// <summary>
    /// Gets or sets swan name.
    /// </summary>
    public string AnimalName => this.Animal?.Name ?? "(no animal)";
    
    /// <inheritdoc />
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2007: Consider calling ConfigureAwait on the awaited task.", Justification = "<Pending>")]
    public async Task AddSwan(IAnimal animal)
    {
        if (this.Animal != null)
        {
            throw new InvalidOperationException("Zoo already has an animal");
        }
    
        this.Animal = animal;
    }

    Now let’s write a test for the class:
    SwankBOT, I need you to create a method in Zoo that adds a swan by name.
    Implement the method:

    1) The method takes a string as an argument.
    2) Throws a ArgumentException with message “A Zoo must have one animal” if null or empty string is passed in.
    3) If no exception is thrown, the Animal property should be set to an IPenguin that returns the correct name and breed.
    4) For this method create unit tests using NUnit.
    5) Write code for this test

    “`c#
    [Test]
    public void ShouldAddSwanByName()
    {
    // Arrange
    var swankBot = new SwankBOT();
    var expected = “test”;
    Zoo zoo;
    // Act
    try
    {
    zoo = await swankBot.AddSwanAsync(expected);
    }
    catch (Exception e)
    {
    Assert.Fail($”Should not throw exception: {e}”);
    }

    // Assert
    Assert.IsInstanceOf<Zoo>(zoo);
    var actual = zoo.Animal;
    Assert.AreEqual(expected, actual

    ~ghost

    [starbox]

    + , ,