diff --git a/README.md b/README.md index b069f615..0087dfde 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ logo # DSRs -A high-performance DSPy rewrite in Rust for building LLM-powered applications +A high-performance DSPy rewrite in Rust for building LM-powered applications [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE) [![Rust](https://img.shields.io/badge/rust-1.70+-orange.svg)](https://www.rust-lang.org) @@ -18,7 +18,7 @@ ## 🚀 Overview -**DSRs** (DSPy Rust) is a ground-up rewrite of the [DSPy framework](https://github.com/stanfordnlp/dspy) in Rust, designed for building robust, high-performance applications powered by Language Models. Unlike a simple port, DSRs leverages Rust's type system, memory safety, and concurrency features to provide a more efficient and reliable foundation for LLM applications. +**DSRs** (DSPy Rust) is a ground-up rewrite of the [DSPy framework](https://github.com/stanfordnlp/dspy) in Rust, designed for building robust, high-performance applications powered by Language Models. Unlike a simple port, DSRs leverages Rust's type system, memory safety, and concurrency features to provide a more efficient and reliable foundation for LM applications. ## 📦 Installation @@ -27,10 +27,10 @@ Add DSRs to your `Cargo.toml`: ```toml [dependencies] # Option 1: Use the shorter alias (recommended) -dsrs = { package = "dspy-rs", version = "0.0.2-beta" } +dsrs = { package = "dspy-rs", version = "0.5.0" } # Option 2: Use the full name -dspy-rs = "0.0.2-beta" +dspy-rs = "0.5.0" ``` Or use cargo: @@ -96,7 +96,7 @@ DSRs follows a modular architecture with clear separation of concerns: ``` dsrs/ ├── core/ # Core abstractions (LM, Module, Signature) -├── adapter/ # LLM provider adapters (OpenAI, etc.) +├── adapter/ # LM provider adapters (OpenAI, etc.) ├── data/ # Data structures (Example, Prediction) ├── predictors/ # Built-in predictors (Predict, Chain, etc.) ├── evaluate/ # Evaluation framework and metrics @@ -137,13 +137,13 @@ impl Module for CustomModule { } ``` -#### 3. **Predictors** - Pre-built LLM Interaction Patterns +#### 3. **Predictors** - Pre-built LM Interaction Patterns ```rust // Get prediction let predict = Predict::new(MySignature::new()); ``` -#### 4. **Language Models** - Configurable LLM Backends +#### 4. **Language Models** - Configurable LM Backends ```rust // Configure with OpenAI let lm = LM::builder() diff --git a/crates/dspy-rs/README.md b/crates/dspy-rs/README.md index b069f615..0087dfde 100644 --- a/crates/dspy-rs/README.md +++ b/crates/dspy-rs/README.md @@ -2,7 +2,7 @@ logo # DSRs -A high-performance DSPy rewrite in Rust for building LLM-powered applications +A high-performance DSPy rewrite in Rust for building LM-powered applications [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE) [![Rust](https://img.shields.io/badge/rust-1.70+-orange.svg)](https://www.rust-lang.org) @@ -18,7 +18,7 @@ ## 🚀 Overview -**DSRs** (DSPy Rust) is a ground-up rewrite of the [DSPy framework](https://github.com/stanfordnlp/dspy) in Rust, designed for building robust, high-performance applications powered by Language Models. Unlike a simple port, DSRs leverages Rust's type system, memory safety, and concurrency features to provide a more efficient and reliable foundation for LLM applications. +**DSRs** (DSPy Rust) is a ground-up rewrite of the [DSPy framework](https://github.com/stanfordnlp/dspy) in Rust, designed for building robust, high-performance applications powered by Language Models. Unlike a simple port, DSRs leverages Rust's type system, memory safety, and concurrency features to provide a more efficient and reliable foundation for LM applications. ## 📦 Installation @@ -27,10 +27,10 @@ Add DSRs to your `Cargo.toml`: ```toml [dependencies] # Option 1: Use the shorter alias (recommended) -dsrs = { package = "dspy-rs", version = "0.0.2-beta" } +dsrs = { package = "dspy-rs", version = "0.5.0" } # Option 2: Use the full name -dspy-rs = "0.0.2-beta" +dspy-rs = "0.5.0" ``` Or use cargo: @@ -96,7 +96,7 @@ DSRs follows a modular architecture with clear separation of concerns: ``` dsrs/ ├── core/ # Core abstractions (LM, Module, Signature) -├── adapter/ # LLM provider adapters (OpenAI, etc.) +├── adapter/ # LM provider adapters (OpenAI, etc.) ├── data/ # Data structures (Example, Prediction) ├── predictors/ # Built-in predictors (Predict, Chain, etc.) ├── evaluate/ # Evaluation framework and metrics @@ -137,13 +137,13 @@ impl Module for CustomModule { } ``` -#### 3. **Predictors** - Pre-built LLM Interaction Patterns +#### 3. **Predictors** - Pre-built LM Interaction Patterns ```rust // Get prediction let predict = Predict::new(MySignature::new()); ``` -#### 4. **Language Models** - Configurable LLM Backends +#### 4. **Language Models** - Configurable LM Backends ```rust // Configure with OpenAI let lm = LM::builder() diff --git a/docs/community.mdx b/docs/community.mdx new file mode 100644 index 00000000..d581f67b --- /dev/null +++ b/docs/community.mdx @@ -0,0 +1,11 @@ +--- +title: "Community" +description: "Join the conversation and get help" +icon: "users" +--- + +Stay connected with the DSRs community. + +- Discord: https://discord.com/invite/ZAEGgxjPUe +- GitHub: https://github.com/krypticmouse/DSRs + diff --git a/docs/docs.json b/docs/docs.json index 4824b9ef..cd53f8ca 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -11,43 +11,45 @@ "navigation": { "tabs": [ { - "tab": "Documentation", + "tab": "Learn DSRs", "groups": [ { - "group": "Getting started", + "group": "Get Started", "pages": [ "index", "docs/getting-started/quickstart" ] }, + { + "group": "Building Blocks", + "pages": [ + "docs/building-blocks/signature", + "docs/building-blocks/lm", + "docs/building-blocks/predictors", + "docs/building-blocks/module" + ] + }, { "group": "Data", "pages": [ "docs/data/examples", "docs/data/prediction" ] - }, + } + ] + }, + { + "tab": "Tutorials", + "groups": [ { - "group": "Building blocks", + "group": "Overview", "pages": [ - "docs/building-blocks/signature", - "docs/building-blocks/lm", - "docs/building-blocks/predictors", - "docs/building-blocks/module" + "docs/tutorials/overview" ] } ] } - ], - "global": { - "anchors": [ - { - "anchor": "DSPy Discord", - "href": "https://discord.com/invite/ZAEGgxjPUe", - "icon": "discord" - } - ] - } + ] }, "logo": { "light": "/logo/main.png", @@ -65,7 +67,8 @@ "footer": { "socials": { "x": "https://x.com/krypticmouse", - "github": "https://github.com/krypticmouse/DSRs" + "github": "https://github.com/krypticmouse/DSRs", + "discord": "https://discord.com/invite/ZAEGgxjPUe" } } -} \ No newline at end of file +} diff --git a/docs/docs/building-blocks/lm.mdx b/docs/docs/building-blocks/lm.mdx index d21804c8..547f027e 100644 --- a/docs/docs/building-blocks/lm.mdx +++ b/docs/docs/building-blocks/lm.mdx @@ -1,5 +1,92 @@ --- -title: 'Language Model' +title: 'Language Models' description: 'Configure and integrate language models in your pipelines' icon: 'arrow-down-a-z' ---- \ No newline at end of file +--- + +DSRs treats the Language Model (`LM`) as a first–class, configurable client for chat-style inference. This page explains what an LM is in DSRs, how it’s structured in Rust terms, and how it cooperates with other building blocks. + +## What is an LM? + +- **Purpose:** Encapsulates a provider client (e.g., OpenAI) and model-level settings, and executes chat completions. +- **Rust shape:** `LM` is a clonable struct built via a builder (`LM::builder()`), holding `LMConfig` and an internal client. +- **Async-first:** `LM::call(...)` is `async` and returns a `(Message, LmUsage)` pair. +- **History:** Each call is recorded; inspect recent calls via `lm.inspect_history(n)`. + +## Key types + +- **`LM` (struct):** Holds `api_key`, `base_url`, `config`, and a `history` of calls. Implements `Clone`. +- **`LMConfig` (struct):** Builder-driven config (e.g., `model`, `temperature`, `max_tokens`). +- **`Chat`, `Message` (structs):** Internal chat abstraction used by adapters to format/parse messages. +- **`Adapter` (trait) and `ChatAdapter` (impl):** Orchestrate how a `Signature` + `Example` become a `Chat`, and parse the model’s response back to a `Prediction`. + +## Construction and configuration + +```rust +use dsrs::{LM, LMConfig}; + +let lm = LM::builder() + .api_key(std::env::var("OPENAI_API_KEY")?.into()) + .config( + LMConfig::builder() + .model("gpt-4o-mini".to_string()) + .temperature(0.7) + .max_tokens(512) + .build() + ) + .build(); +``` + +- **Builder pattern:** Idiomatic in Rust; keeps construction explicit and typed. +- **Clone semantics:** `LM` implements `Clone`—cloning copies config and history for that instance. + +## Global vs explicit usage + +- **Global:** `configure(lm.clone(), ChatAdapter::default())` sets the process-wide default used by predictors. +- **Explicit:** Some APIs accept a mutable `&mut LM` if you prefer local control: `predictor.forward_with_config(inputs, &mut lm).await`. + +## Async execution and sync entry + +- **Async:** Calls are `async`; prefer using an async runtime (Tokio). +- **Sync-style:** If you need a plain `fn main`, create a runtime and `block_on` the async work. + + + + +```rust +#[tokio::main] +async fn main() -> anyhow::Result<()> { + // build + use LM here + Ok(()) +} +``` + + + + +```rust +fn main() -> anyhow::Result<()> { + let rt = tokio::runtime::Runtime::new()?; + rt.block_on(async move { + // build + use LM here + Ok(()) + }) +} +``` + + + + +## Inspecting history + +```rust +let history = lm.inspect_history(3); +for entry in history { + println!("Model: {} | Output: {}", entry.config.model, entry.output.content()); +} +``` + +## Where it fits + +- You rarely call `LM` directly; instead, a `Predictor` uses an `Adapter` to format a `Signature` and call the LM. +- This keeps business logic (your task) separate from transport (the model client), matching Rust’s trait-driven composition style. diff --git a/docs/docs/building-blocks/module.mdx b/docs/docs/building-blocks/module.mdx index adf2fbea..ef795ac2 100644 --- a/docs/docs/building-blocks/module.mdx +++ b/docs/docs/building-blocks/module.mdx @@ -1,5 +1,39 @@ --- -title: 'Module' -description: 'Building flows for complex LLM pipelines' +title: 'Modules' +description: 'Building flows for complex LM pipelines' icon: 'circle-nodes' ---- \ No newline at end of file +--- + +Modules let you compose multiple predictors and arbitrary Rust logic into reusable units. In DSRs, a module is any type that implements the `Module` trait. + +## What is a module? + +- **Purpose:** Encapsulate a multi-step workflow (e.g., analysis then answer) as a single callable unit. +- **Rust shape:** Any type implementing `Module` with an `async fn forward(&self, inputs: Example)`. +- **Composition:** Typically holds one or more `Predict` fields and sequences their calls. + +## Minimal example + +```rust +use dsrs::{Example, Module, Predict, Prediction, Signature}; + +#[Signature] +struct QA { #[input] question: String, #[output] answer: String } + +struct Answerer { predict: Predict } + +impl Default for Answerer { fn default() -> Self { Self { predict: Predict::new(QA::new()) } } } + +#[allow(async_fn_in_trait)] +impl Module for Answerer { + async fn forward(&self, inputs: Example) -> anyhow::Result { + self.predict.forward(inputs).await + } +} +``` + +## Design notes + +- **Traits and async:** `Module` is a trait with an async method; implement it where your composition lives. +- **State:** Keep structured state as fields (other predictors, config, toggles). Prefer builders for complex modules. +- **Testability:** You can inject a `DummyLM` via `forward_with_config` in tests to avoid network calls. diff --git a/docs/docs/building-blocks/predictors.mdx b/docs/docs/building-blocks/predictors.mdx index e656649d..77cee4a6 100644 --- a/docs/docs/building-blocks/predictors.mdx +++ b/docs/docs/building-blocks/predictors.mdx @@ -1,5 +1,5 @@ --- title: 'Predictors' -description: 'Learn how to create and use predictors for LLM inference' +description: 'Learn how to create and use predictors for LM inference' icon: 'robot' --- diff --git a/docs/docs/building-blocks/signature.mdx b/docs/docs/building-blocks/signature.mdx index 46048de1..6789603c 100644 --- a/docs/docs/building-blocks/signature.mdx +++ b/docs/docs/building-blocks/signature.mdx @@ -1,5 +1,64 @@ --- -title: 'Signature' -description: 'Define task specifications for LLM interactions' +title: 'Signatures' +description: 'Define task specifications for LM interactions' icon: 'pen-to-square' ---- \ No newline at end of file +--- + +Signatures declare the schema of your LM task: the inputs you provide and the outputs you expect. In Rust terms, a `#[Signature]` macro generates an implementation of the `MetaSignature` trait for your type. + +## What is a signature? + +- **Purpose:** Describe a task contract: structured inputs, structured outputs, and an optional instruction. +- **Rust shape:** A normal Rust `struct` annotated with `#[Signature]` and field attributes (`#[input]`, `#[output]`). +- **Trait impl:** The macro implements `MetaSignature` (introspection of input/output fields, instruction, demos). + +## Defining a signature + +```rust +use dsrs::Signature; + +#[Signature] +struct QA { + /// Use Renaissance-era English to answer the question. + #[input] + question: String, + + #[output] + answer: String, +} +``` + +- **Doc comments:** The `///` above the struct become the signature’s instruction (used by adapters). +- **Field roles:** Mark inputs vs. outputs with attributes for clear orchestration. + +## Inline macro alternative + +```rust +use dsrs::sign; +let sig = sign! { (question: String) -> answer: String }; +``` + +## Demos (few-shot examples) + +You can attach examples at runtime for few-shot prompting. + +```rust +use dsrs::{Example, MetaSignature, hashmap}; + +let mut sig = QA::new(); +sig.set_demos(vec![ + Example::new( + hashmap!{ + "question".to_string() => "What is gravity?".into(), + "answer".to_string() => "A natural power that draweth bodies earthward.".into() + }, + vec!["question".to_string()], + vec!["answer".to_string()], + ) +])?; +``` + +## Where it fits + +- A `Signature` does not call the LM by itself; a `Predictor` uses it, via an `Adapter`, to build a `Chat` and parse a `Prediction`. +- Keeping the task contract as data (the signature) supports reuse, testing, and optimizer integration later. diff --git a/docs/docs/data/prediction.mdx b/docs/docs/data/prediction.mdx index a40f5ba0..f98debb5 100644 --- a/docs/docs/data/prediction.mdx +++ b/docs/docs/data/prediction.mdx @@ -1,5 +1,5 @@ --- title: 'Prediction' -description: 'Understand and work with prediction outputs from your LLM pipelines' +description: 'Understand and work with prediction outputs from your LM pipelines' icon: "chart-line" --- \ No newline at end of file diff --git a/docs/docs/getting-started/quickstart.mdx b/docs/docs/getting-started/quickstart.mdx index 7e4e3c58..a1852f5c 100644 --- a/docs/docs/getting-started/quickstart.mdx +++ b/docs/docs/getting-started/quickstart.mdx @@ -1,68 +1,99 @@ --- title: "Quickstart" -description: "Start building awesome LLM pipelines in minutes" +description: "Start building awesome LM pipelines in minutes" icon: "rocket" --- -This guide will walk you through setting up DSRs in your Rust project and building your first LLM pipeline. You'll learn how to install the necessary dependencies, configure your language model provider, create a simple signature, and run your first prediction. +This guide will walk you through setting up your Rust project and building your first LM pipeline in DSRs. +The entire process takes a few minutes and requires only basic Rust +knowledge. The goal in this quickstart demo is to get you up and running configuring your LM in DSRs, +define a signature, run a prediction, and see the results. Let's go! 🚀 -The entire process takes about 10-15 minutes and requires only basic Rust knowledge. We'll start with installation, then move through configuration, and finally build a practical example that you can extend for your own use cases. You can add DSRs to your project just like any other Rust crate, using either of these two methods: -**Option 1: Add via Cargo.toml** +**Option 1: Add to Cargo.toml** ```toml [dependencies] -dsrs = { package = "dspy-rs", version = "0.0.2-beta" } +anyhow = "1.0.99" +dspy-rs = "0.5.0" +serde = "1.0.221" +serde_json = "1.0.145" +tokio = "1.47.1" ``` -**Option 2: Add via cargo command** +**Option 2: Add via Cargo command** ```bash -cargo add dsrs --package dspy-rs +cargo add dspy-rs anyhow serde serde_json tokio ``` This will create an alias `dsrs` for the `dspy-rs` crate which is the intended way to use it. -The reason we wanna do aliasing is because `dsrs` was already a published crate so I couldn't get the name, but this is how we intend to use it. +We need to install DSRS using the name `dspy-rs` for now, because +`dsrs` is an already-published crate. +This may change in the future if the `dsrs` crate name is donated back or becomes available. - + -You can configure `LM` and `ChatAdapter` as a global configuration using `configure` method. You can set `LM` using builder patterns and ChatAdapter can be passed as default: +The first step in DSRs is to configure your Language Model (LM). DSRs supports +any LM supported via the `async-openai` crate. You can define your LM +configuration using the builder pattern as follows. + +Once the LM instance is created, pass it to the configure function along with +a chat adapter to set the global LM and adapter for your application. +`ChatAdapter` is the default adapter in DSRs and is responsible for converting +the instructions and the structure from your signature (defined in the next step) +into a prompt that the LM can follow to complete the task. ```rust -use dsrs::{configure, LM, ChatAdapter}; +use dspy_rs::{configure, ChatAdapter, LM, LMConfig}; +use std::env; -configure( - LM::builder() +fn main() -> Result<(), anyhow::Error> { + //Define a config for the LM + let config = LMConfig::builder() + .model("gpt-4.1-nano".to_string()) + .build(); + // Create the LM instance via the builder + let lm = LM::builder() + .config(config) .api_key(env::var("OPENAI_API_KEY")?.into()) - .build(), - ChatAdapter::default(), -); + .build(); + // Configure the global LM and adapter + configure(lm, ChatAdapter::default()); + + Ok(()) +} ``` - + -A **Signature** defines the structure of your task: what inputs it takes and what outputs it should produce. Think of it as a schema for your LLM call, you can create it in 2 ways: inline macro and attribute macro. For example, to create a simple question-answering signature: +A signature defines the structure of your task: what inputs it takes and what outputs it should produce. Think of it as a schema for your LM call, + +You can create your signature in DSRs in one of two ways: using an inline macro, and via an attribute macro. + +Let's create a question-answering signature using the inline macro: ```rust let signature = sign! { (question: String) -> answer: String }; ``` +The input fields are to the left of the `->` arrow, and the output fields are to the right. Multiple fields can be comma-separated, for e.g., `(question: String, +context: String) -> answer: String`. -You can have more control over defining more granular aspect of the signature by defining signature using attribute macro on structs: +Alternatively, you can have more control over defining more granular aspects of the signature by defining signature using attribute macro on structs. ```rust -// COT Signature: Adds a reasoning output field on its own -#[Signature(cot)] +#[Signature] struct QASignature { /// Answer the question concisely. @@ -74,29 +105,168 @@ struct QASignature { } ``` +The advantage of the latter approach is that you can add doc comments at the +top of the struct, specifying +important domain information or specific instructions to the LM. +Additionally, you can also annotate each field with `#[input]` and `#[output]` +attributes, useful when you have multiple input and output fields, and when +you want to add descriptions to each field. + - + -Create a `.env` file in your project root to configure your language model provider: +A predictor is the simplest module in DSRs. It takes a signature and input data, and orchestrates the LM call to produce a prediction. Let's demonstrate this +with an example. -```bash -mint dev +Gravity was explained by Isaac Newton in 1687. To make this more interesting, +let's ask the LM to answer in Renaissance-era English! We can do this by asking +for this explicitly in the signature doc comment. + +LM calls in DSRs are asynchronous and return a future, so we need to use the `tokio` runtime to execute a function that uses a predictor. + +```rust +use dspy_rs::{ + ChatAdapter, Example, LM, LMConfig, Predict, Predictor, Signature, configure, hashmap, +}; +use std::env; + +#[Signature] +struct QA { + /// Use Renaissance-era English to answer the question. + + #[input] + pub question: String, + + #[output] + pub answer: String, +} + +#[tokio::main] +async fn main() -> Result<(), anyhow::Error> { + let config = LMConfig::builder().model("gpt-4.1-nano".to_string()).build(); + + let lm = LM::builder() + .config(config) + .api_key(env::var("OPENAI_API_KEY")?.into()) + .build(); + + configure(lm.clone(), ChatAdapter::default()); + // Create a questin-answering signature instance + let signature = QA::new(); + // Create a predictor + let predictor = Predict::new(signature); + // Define the question + let question = "What is gravity?"; + // Create an example input to the predictor + let inputs = Example::new( + hashmap! { + "question".to_string() => question.to_string().into() + }, + vec!["question".to_string()], + vec!["answer".to_string()], + ); + + let result = predictor.forward(inputs).await?; + println!("Answer: {:?}", result.get("answer", None).as_str().unwrap()); + Ok(()) +} ``` -A local preview of your documentation will be available at `http://localhost:3000`. +The predictor takes an `Example` as input, which is a mapping from field names to values. The following result is obtained. + +Result: + +```txt +Answer: "Gravity, good sir or madam, is the unseen force that draweth all things +unto the center of the Earth, binding the celestial spheres and ensuring that +objects fall when cast down. It is the natural power ordained by the divine +hand to keep the heavens in their orbits and men grounded upon the earth." +``` + +There we go. You can imagine that as being explained by Isaac Newton himself! 🧐 - + +Predictors are the simples module calls in DSRs. You can also compose together +a more complex module that wraps a predictor and your own forwards calls. + +```rust +use dspy_rs::{ + ChatAdapter, Example, LM, LMConfig, Module, Predict, Prediction, Predictor, Signature, + configure, hashmap, +}; +use std::env; + +struct AnswerQuestion { + inner: Predict, +} -Create a `.env` file in your project root to configure your language model provider: +impl AnswerQuestion { + fn new() -> Self { + Self { + inner: Predict::new(QA::new()), + } + } +} -```bash -mint dev +impl Module for AnswerQuestion { + async fn forward(&self, inputs: Example) -> anyhow::Result { + self.inner.forward(inputs).await + } +} ``` +You can define an implementation of the `Module` trait for your own struct that +composes together one or more predictors and your own arbitrary logic. In this case, the `AnswerQuestion` module wraps a predictor that uses the `QA` signature defined earlier. +The forward method is async because it wraps a predictor call. -A local preview of your documentation will be available at `http://localhost:3000`. +We can define the main function to use this module as follows. + +```rust +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let config = LMConfig::builder() + .model("gpt-4.1-nano".to_string()) + .build(); + + let lm: LM = LM::builder() + .config(config) + .api_key(env::var("OPENAI_API_KEY")?.into()) + .build(); + + configure(lm, ChatAdapter::default()); + // Create the module instance + let module = AnswerQuestion::new(); + // Define the question + let question = "What is gravity?"; + // Create an example input to the module + let inputs = Example::new( + hashmap! { + "question".to_string() => question.to_string().into() + }, + vec!["question".to_string()], + vec!["answer".to_string()], + ); + + let result = module.forward(inputs).await?; + println!("Answer: {:?}", result.get("answer", None).as_str().unwrap()); + Ok(()) +} +``` +This produces a similar result. + +``` +Answer: "Gravity is the divine force, as understood by the wise of the +Renaissance, that draweth all things towards the center of the Earth, binding +the heavens and the earth in a harmonious embrace. It is the unseen hand that +keeps the celestial bodies in their courses and the objects upon the ground +in their place." +``` + +This is just the tip of the iceberg. DSRs supports many more features, including +an Optimizable trait for modules that can help improve your modules via +optimizers. Continue exploring the rest of the documentation to learn more! diff --git a/docs/docs/tutorials/overview.mdx b/docs/docs/tutorials/overview.mdx new file mode 100644 index 00000000..0af18e9e --- /dev/null +++ b/docs/docs/tutorials/overview.mdx @@ -0,0 +1,5 @@ +--- +title: 'Overview' +description: 'Tutorials with end-to-end examples' +icon: 'graduation-cap' +--- diff --git a/docs/index.mdx b/docs/index.mdx index 8b4a9590..82355e74 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -18,14 +18,14 @@ iconType: "light" }} /> -DSRs is a rewrite of the DSPy framework, built from the ground up in Rust for programming robust, LLM-powered applications. By leveraging Rust’s type system, memory safety, and concurrency, DSRs offers a more efficient and reliable foundation for language model workflows. +DSRs is a rewrite of the DSPy framework, built from the ground up in Rust for programming robust, LM-powered applications. By leveraging Rust’s type system, memory safety, and concurrency, DSRs offers a more efficient and reliable foundation for language model workflows. - **Not just a port:** DSRs reimagines DSPy’s abstractions with Rust’s strengths in mind. - **Modern Rust API:** Take advantage of Rust’s ecosystem, async support, and strong typing. - **Core features:** Includes signatures, modules, adapters, etc. - **Easy to get started:** Install via Cargo, and follow the [Quickstart](docs/getting-started/quickstart) to build your first pipeline in minutes. -> _Inspired by the original [DSPy](https://github.com/stanfordnlp/dspy) framework, DSRs brings LLM application development to the Rust community._ +> _Inspired by the original [DSPy](https://github.com/stanfordnlp/dspy) framework, DSRs brings LM application development to the Rust community._ ## Setting up @@ -41,7 +41,7 @@ Get your documentation site up and running in minutes. Get up and running with DSRs in under 5 minutes. Install, configure, and run your first pipeline. -## Learn More +## Learn more Understand in-depth about the building blocks of DSRs