4 ms·
Show HN: Pickaxe – A TypeScript library for building AI agents
Hey HN, Gabe and Alexander here from Hatchet. Today we're releasing Pickaxe, a Typescript library to build AI agents which are scalable and fault-tolerant.
Here's a demo: https://github.com/user-attachments/assets/b28fc406-f501-4427-9574-e4c756b29dd4 https://github.com/user-attachments/assets/b28fc406-f501-442...
Pickaxe provides a simple set of primitives for building agents which can automatically checkpoint their state and suspend or resume processing (also known as durable execution) while waiting for external events (like a human in the loop). The library is based on common patterns we've seen when helping Hatchet users run millions of agent executions per day.
Unlike other tools, Pickaxe is not a framework. It does not have any opinions or abstractions for implementing agent memory, prompting, context, or calling LLMs directly. Its only focus is making AI agents more observable and reliable.
As agents start to scale, there are generally three big problems that emerge:
1. Agents are long-running compared to other parts of your application. Extremely long-running processes are tricky because deploying new infra or hitting request timeouts on serverless runtimes will interrupt their execution.
2. They are stateful: they generally store internal state which governs the next step in the execution path
3. They require access to lots of fresh data, which can either be queried during agent execution or needs to be continuously refreshed from a data source.
(These problems are more specific to agents which execute remotely -- locally running agents generally don't have these problems)
Pickaxe is designed to solve these issues by providing a simple API which wraps durable execution infrastructure for agents. Durable execution is a way of automatically checkpointing the state of a process, so that if the process fails, it can automatically be replayed from the checkpoint, rather than starting over from the beginning. This model is also particularly useful when your agent needs to wait for an external event or human review in order to continue execution. To support this pattern, Pickaxe uses a Hatchet feature called `waitFor` which durably registers a listener for an event, which means that even if the agent isn't actively listening for the event, it is guaranteed to be processed by Hatchet and stored in the execution history and resume processing. This infrastructure is powered by what is essentially a linear event log, which stores the entire execution history of an agent in a Postgres database managed by Hatchet.
Full docs are here: https://pickaxe.hatchet.run/ https://pickaxe.hatchet.run/
We'd greatly appreciate any feedback you have and hope you get the chance to try out Pickaxe.
- jskalc92 1y agoIf I understand it correctly, tools and agents run() method works in a similar way to react hooks, correct? Depending on execution order, tool is either called or a cached value returned. That way local state can be replayed, and that's why "no side effects" rule is in place. I like it. Just, what's the recommended way to have a chat assistant agent with multiple tools? Message history would need to be passed to the very top-level agent.run call, isn't it?
- gabrielruttner 1y agoyes, similar and we've been toying around with some feedback to have a `pickaxe.memo(()=>{})` utility to quickly wrap small chunks of code similar to `useMemo`. we'll be continuously improving docs on this project, but since pickaxe is built on hatchet it supports concurrency [1]. so for a chat usecase, you can pass the chat history to the top level agent but propagate cancelation for other message runs in the session to handle if the user sends a few messages in a row. we'll work an example in pattern section for this! [1] https://docs.hatchet.run/home/concurrency#cancel-in-progress https://docs.hatchet.run/home/concurrency#cancel-in-progress
- blixt 1y agoI see the API is rarely mentioning exact message structure (system prompt, assistant/user history, etc) or the choice of model (other than defaultLanguageModel). And it's not immediately clear to me how `toolbox.pickAndRun` can access any context from an ongoing agentic flow other than within the one prompt. But this is just from skimming the docs, maybe all of this is supported? The reason I ask is because I've had a lot of success using different models for different tasks, constructing the system prompt specifically for each task, and also choosing between the "default" long assistant/tool_call/user/(repeat) message history vs. constantly pruning it (bad for caching but sometimes good for performance). And it would be nice to know a library like this could allow experimentation of these strategies.
- gabrielruttner 1y agogabe, hatchet cofounder here. thanks for this feedback and i agree! under the hood we're using vercel ai sdk to make tool calls so this is easily extended [1]. this is the only "opinionated" api for calling llm apis which is "bundled" within the sdk and we were torn on how to expose it for this exact reason, but since its so common we decided to include it. some things we were thinking is overloading `defaultLanguageModel` with a map for different usecases, or allowing users to "eject" the tool picker to customize it as needed. i've opened a discussion [2] to track this. [1] https://github.com/hatchet-dev/pickaxe/blob/main/sdk/src/client/toolbox.ts https://github.com/hatchet-dev/pickaxe/blob/main/sdk/src/cli... [2] https://github.com/hatchet-dev/pickaxe/discussions/3 https://github.com/hatchet-dev/pickaxe/discussions/3