ForkNous ResearchNous Researchpublished Feb 9, 2024seen 5d

NousResearch/funcchain

forked from shroominic/funcchain

Open original ↗

Captured source

source ↗
published Feb 9, 2024seen 5dcaptured 11hhttp 200method plain

NousResearch/funcchain

Description: ⛓️ build cognitive systems, pythonic

Language: Python

License: MIT

Stars: 9

Forks: 4

Open issues: 0

Created: 2024-02-09T19:35:19Z

Pushed: 2024-02-13T03:00:59Z

Default branch: main

Fork: yes

Parent repository: shroominic/funcchain

Archived: no

README:

funcchain

![Version](https://badge.fury.io/py/funcchain) ![tests](https://github.com/shroominic/funcchain/actions/workflows/code-check.yml)

pip install funcchain

Introduction

funcchain is the *most pythonic* way of writing cognitive systems. Leveraging pydantic models as output schemas combined with langchain in the backend allows for a seamless integration of llms into your apps. It utilizes OpenAI Functions or LlamaCpp grammars (json-schema-mode) for efficient structured output. In the backend it compiles the funcchain syntax into langchain runnables so you can easily invoke, stream or batch process your pipelines.

![Open in GitHub Codespaces](https://codespaces.new/ricklamers/funcchain-demo)

Simple Demo

from funcchain import chain
from pydantic import BaseModel

# define your output shape
class Recipe(BaseModel):
ingredients: list[str]
instructions: list[str]
duration: int

# write prompts utilising all native python features
def generate_recipe(topic: str) -> Recipe:
"""
Generate a recipe for a given topic.
"""
return chain() # TodoList | ShoppingList:
"""
The user input is either a shopping List or a todo list.
"""
return chain()

# the model will choose the output type automatically
lst = extract_list(
input("Enter your list: ")
)

# custom handler based on type
match lst:
case ShoppingList(items=items, store=store):
print("Here is your Shopping List: ")
for item in items:
print(f"{item.name}: {item.description}")
print(f"You need to go to: {store}")

case TodoList(todos=todos, urgency=urgency):
print("Here is your Todo List: ")
for item in todos:
print(f"{item.name}: {item.description}")
print(f"Urgency: {urgency}")

Vision Models

from funcchain import Image
from pydantic import BaseModel, Field
from funcchain import chain, settings

# set global llm using model identifiers (see MODELS.md)
settings.llm = "openai/gpt-4-vision-preview"

# everything defined is part of the prompt
class AnalysisResult(BaseModel):
"""The result of an image analysis."""

theme: str = Field(description="The theme of the image")
description: str = Field(description="A description of the image")
objects: list[str] = Field(description="A list of objects found in the image")

# easy use of images as input with structured output
def analyse_image(image: Image) -> AnalysisResult:
"""
Analyse the image and extract its
theme, description and objects.
"""
return chain()

result = analyse_image(Image.open("examples/assets/old_chinese_temple.jpg"))

print("Theme:", result.theme)
print("Description:", result.description)
for obj in result.objects:
print("Found this object:", obj)

Seamless local model support

from pydantic import BaseModel, Field
from funcchain import chain, settings

# auto-download the model from huggingface
settings.llm = "ollama/openchat"

class SentimentAnalysis(BaseModel):
analysis: str
sentiment: bool = Field(description="True for Happy, False for Sad")

def analyze(text: str) -> SentimentAnalysis:
"""
Determines the sentiment of the text.
"""
return chain()

# generates using the local model
poem = analyze("I really like when my dog does a trick!")

# promised structured output (for local models!)
print(poem.analysis)

Features

  • 🐍 pythonic
  • 🔀 easy swap between openai or local models
  • 🔄 dynamic output types (pydantic models, or primitives)
  • 👁️ vision llm support
  • 🧠 langchain_core as backend
  • 📝 jinja templating for prompts
  • 🏗️ reliable structured output
  • 🔁 auto retry parsing
  • 🔧 langsmith support
  • 🔄 sync, async, streaming, parallel, fallbacks
  • 📦 gguf download from huggingface
  • ✅ type hints for all functions and mypy support
  • 🗣️ chat router component
  • 🧩 composable with langchain LCEL
  • 🛠️ easy error handling
  • 🚦 enums and literal support
  • 📐 custom parsing types

Documentation

Checkout the docs here 👈

Also highly recommend to try and run the examples in the ./examples folder.

Contribution

You want to contribute? Thanks, that's great! For more information checkout the [Contributing Guide](docs/contributing/dev-setup.md). Please run the dev setup to get started:

git clone https://github.com/shroominic/funcchain.git && cd funcchain

./dev_setup.sh

Excerpt shown — open the source for the full document.