Thanks for the insight, I wasn't aware of `track_caller`. I'll definitely be looking into this. I was scratching my head trying to figure out how to make file and line number usage consistent and customizable, this looks like the answer!
You're also right that this will pretty much eliminate the need for macros.
That's also a very key insight about Display vs. Debug printing. I'll be looking into that as well.
Anyhow still makes things easier for application development. The main drawback is that the resulting error type doesn't implement std::error::Error, so it's not suitable for library development (as pointed out in the anyhow documentation). Stack Error is a bit less ergonomic, but suitable for library development.
I played around a bit with SNAFU a couple of years ago, but I'm haven't worked deeply with the library so there might well be some features I'm not aware of.
I think SNAFU is more like a combination of anyhow and thiserror into a single crate, rather than Stack Error which leans more heavily into the "turnkey" error struct. Using the Whatever struct, you get some overlap with Stack Error features:
- Error message are co-located.
- Error type implement std::error::Error (suitable for library development).
- External errors can be wrapped and context can easily be added.
Where Stack Error differs:
- Error codes (and URIs) offer ability for runtime error handling without having to compare strings.
- Provides pseudo-stack by stacking messages.
Underlying this is an opinion I baked into Stack Error: error messages are for debugging, not for runtime error handling. Otherwise all your error strings effectively become part of your public interface since a downstream library can rely on them for error handling.
Stack Error is a pragmatic error handling library for Rust that provides helpful messages for debugging, and structured data for runtime error handling.
Features:
- Informative error messages: stack error messages and optionally add file/line context to your messages. This helps convey not just what went wrong, but also how it went wrong, making debugging faster.
- Programmatic error handling: include optional error codes and URIs for robust runtime handling.
- Library-Friendly: define custom error types easily while staying compatible with Rust’s error ecosystem.
If designing good error structures for your projects slows you down, and you need something more library-friendly and structured than anyhow, Stack Error might be what you’re looking for.
This gets discussed in the Roc community. They are exploring designing a language without higher kinded polymorphism.
Here's a snippet from the Roc FAQ.
> It's impossible for a programming language to be neutral on this. If the language doesn't support HKP, nobody can implement a Monad typeclass (or equivalent) in any way that can be expected to catch on. Advocacy to add HKP to the language will inevitably follow. If the language does support HKP, one or more alternate standard libraries built around monads will inevitably follow, along with corresponding cultural changes. (See Scala for example.) Culturally, to support HKP is to take a side, and to decline to support it is also to take a side.
Unfortunately you can ask Clint to tell you just about anything. But fortunately it will at least try to tell you that some things are less plausible than others.
Clint should be used only to research information. It provides links to resources. It uses Retrieval Augmented Generation which is less prone providing incorrect information, though it can still happen.
Thank you! That's great feedback. Clint is very much a proof-of-concept, I'm sure this idea can be taken much further when done properly. But to get a "pretty neat" from an RN feels like an accomplishment xD.
I see what you mean about going down the wrong path. I can explore a couple of modifications to help it have better context of the conversation as a whole.
I chunk the documents by section, and embed only the first 2048 tokens that fit in the OpenAI embeddings. I'm using OpenAI for embedding as opposed to something like all-minilm-l6-v2 because I don't want to have to ship a model to the clients (transfer times could be large and supporting this would increase the complexity of the library).
I didn't experiment with different chunk sizes, and I suspect something smaller would be more beneficial as you point out. But it would also complicate the logic, and most choices I made in this project were to remove complexity and get this done quickly. If I revisit this I might chunk by paragraph on your advice :).
RAG is indeed what is being used. But it a few different ways. The diagnoses are refined using a pretty straightforward RAG prompt: consider these notes ... consider this diagnosis ... can you improve on it etc.
But in a way the entire program is RAG-based. In most prompts some documents are added to the system message for context. It's not clear that the information in the documents is always used, but based on a bit of experimentation it seems to improve various responses.
I have no plans to fine tune. I'm not sure how beneficial would be fine tuning here. The model needs a fair bit of general knowledge to reason about descriptions of symptoms. Fine tuning could over-specialize it. And hallucinations could come up even with fine-tuning, so you would probably want a RAG-like prompt to get it to focus on real details.
This this is very much a hobby, so I haven't dug deep enough to look into other models. But I'd be _very_ curious to see how GPT 3.5 with RAG compares to vanilla MedPALM. In my experience GPT 3.5 can reason quite well about with the right documents in the context.
It's using Activity Stream (https://www.w3.org/ns/activitystreams/v1) which can be represented in RDF or JSON-LD formats. In this case, JSON-LD is used, but this can be easily converted to RDF.
To me it's still unclear if having a message traverse the entire graph is good or bad. Something like this is required otherwise this will really just be a chat app, and probably not a very good one at that. What I mean is that if you can see only messages directly addressed or shared with you, well that's just Signal.
The current implementation traverses the graph of follows, which has some nice properties. Even if you had 10x as many bots as users on a platform, they can all post and share and like etc. But if no one from your social graph is following those bots, you won't see any of their content. Of course all it takes is one person in your network to follow a bot, and now you're exposed to all that spam. In that case you might want to unfollow this non-discerning friend. And the threat of being unfollowed will create incentives for people to make meaningful follows in the first place.
Some more granular tools will need to be built to help refine this. For example, you might not want to see things more than 3 steps away in your graph. There is also the concept of flagging messages which is not currently implemented, but will allow one user to stop a message from spreading to their followers.
As for the echo chambers, I'm not sure yet what this will look like. In the physical world there are soft echo chambers. People make like-minded friends and join like-minded organizations. To some extent this is good, when comparing to the alternative where everyone has to listen to anyone which would create a lot of conflict. Taken to the extreme though it does seem to make people intolerant to differing ideas.
The question I am asking myself (and for which I do not have an answer) is: will a platform like Chatter Net encourage people to progressively discover new ideas (the more people you follow, the more variety of content you will receive), or will it give the tools for people to lock out any competing views.
There are lots of similarities indeed. No idea exists on its own, and it is not surprising that there are many others trying to solve the same problems and arriving to similar conclusions. I would consider Chatter Net to be a parallel experiment exploring similar ideas.
I think I can also address the elephant in the room: Bluesky is built by a team of (very likely talented) individuals. Chatter Net is, well, Chatter Net xD. The atproto project is very interesting to me, and part of the reason for pushing Chatter Net so early was to make sure its have a chance to be heard before the space becomes too crowded.
At a high level I can spot a few differences in the approaches:
- Chatter Net is smaller project focused much more on the data model, whereas atproto is more of a holistic solution specifying not just the data model but also how it should be shared and stored to some extent.
- Chatter Net builds on the Activity Pub (and JSON-LD) standard whereas atproto introduces a new data format.
The core ideas atproto are very similar to the ideas in Chatter Net. Those ideas are extended to touch on some complicated topic that Chatter Net is just starting to address (their big world vs. small world discussion).
However, I'm not entirely sure yet how decentralized Bluesky (atproto) will be. In security the system is only as strong as its weakest link, and I think ultimately whether Bluesky is decentralized, federated, or run by a consortium will depend on:
- how personal data servers are created / managed
- how easy it is in practice for a user move between apps, servers etc. The signing key is not controlled by the user, but they do control a recovery key. If a platform changes direction or becomes otherwise incompatible with a user, I can imagine this system working out quite well, or it becoming akin to asking for your post history from one platform, and then manually uploading it to another and having to rebuild your network etc.
Good question! Right now the client and server talk over HTTP using routes that conform with the Activity Pub spec (everything resource under `/ap` on the server should be a valid Activity Stream document conforming to Activity Pub spec).
However:
1) this isn't tested with any other Activity Pub client, so there are probably some implementation differences (errors) to iron out.
2) Currently the server doesn't implement the full Activity Pub protocol, so an existing client will probably make calls that will 404.
3) The server doesn't use any kind of authentication becasue Chatter Net doesn't rely on any server authentication. Clients authenticate messages based on signatures, so it doesn't really matter where the messages come from. Activity Pub doesn't seem to say anything about how authentication should work, so this should in theory be compatible. But in practice, existing Activity Pub implementations seem to rely on certain authentication patterns.
But I would definitely like to get the project to be compatible Fediverse clients. So this is something I want to work towards.
You're also right that this will pretty much eliminate the need for macros.
That's also a very key insight about Display vs. Debug printing. I'll be looking into that as well.
Thank you for the thoughtful reply.