underthesea 9.5.0


pip install underthesea

  Latest version

Released: May 17, 2026


Meta
Author: Vu Anh
Requires Python: >=3.10

Classifiers

Development Status
  • 5 - Production/Stable

Intended Audience
  • Developers
  • Science/Research

Operating System
  • POSIX :: Linux
  • MacOS :: MacOS X
  • Microsoft :: Windows

Natural Language
  • English

Programming Language
  • Python :: 3
  • Python :: 3.10
  • Python :: 3.11
  • Python :: 3.12
  • Python :: 3.13
  • Python :: 3.14




Open-source Agentic AI Toolkit

Underthesea is:

🌊 An Agentic AI Toolkit. Since v9.3.0, Underthesea is an open-source Agentic AI Toolkit with built-in Vietnamese NLP capabilities. It provides multi-provider AI Agent support and a suite of Python modules for Vietnamese Natural Language Processing.

🎁 Support Us! Every bit of support helps us achieve our goals. Thank you so much. 💝💝💝

Installation

$ pip install underthesea

Agent

Multi-provider AI Agent with zero external dependencies. Communicates with LLM APIs using only Python stdlib (urllib + json) — no openai, anthropic, or google-genai packages required.

Providers: OpenAI | Azure OpenAI | Anthropic Claude | Google Gemini

Quick Start

# Pick one provider:
$ export OPENAI_API_KEY=sk-...
# or Azure:
$ export AZURE_OPENAI_API_KEY=... && export AZURE_OPENAI_ENDPOINT=https://...
# or Anthropic:
$ export ANTHROPIC_API_KEY=sk-ant-...
# or Gemini:
$ export GOOGLE_API_KEY=...
from underthesea.agent import Agent, LLM

agent = Agent(name="assistant", provider=LLM())
agent("Hello!")

Providers

Each provider is its own class, following the Anthropic SDK pattern.

from underthesea.agent import Agent, OpenAI, AzureOpenAI, Anthropic, Gemini, LLM

# OpenAI
agent = Agent(name="bot", provider=OpenAI(api_key="sk-..."))

# Azure OpenAI
agent = Agent(name="bot", provider=AzureOpenAI(
    api_key="...",
    endpoint="https://my.openai.azure.com",
    deployment="gpt-4",
))

# Anthropic Claude
agent = Agent(name="bot", provider=Anthropic(api_key="sk-ant-..."))

# Google Gemini
agent = Agent(name="bot", provider=Gemini(api_key="..."))

# Auto-detect from environment variables
agent = Agent(name="bot", provider=LLM())

Streaming

for chunk in agent.stream("Explain what an AI agent is"):
    print(chunk, end="", flush=True)

Tool Calling

from underthesea.agent import Agent, Tool, OpenAI

def get_weather(location: str) -> dict:
    """Get current weather for a location."""
    return {"location": location, "temp": 25, "condition": "sunny"}

agent = Agent(
    name="assistant",
    provider=OpenAI(),
    tools=[Tool(get_weather)],
    instruction="You are a helpful assistant.",
)

agent("What's the weather in Hanoi?")
# 'The weather in Hanoi is 25°C and sunny.'

Default Tools

12 built-in tools: calculator, datetime, web search, wikipedia, file I/O, shell, python exec.

from underthesea.agent import Agent, default_tools, LLM

agent = Agent(name="assistant", provider=LLM(), tools=default_tools)
agent("Calculate sqrt(144) + 10")

Multi-Session

Long-running agents with context reset and structured handoff between sessions, following Anthropic harness patterns.

from underthesea.agent import Agent, Session, AzureOpenAI

agent = Agent(name="researcher", provider=AzureOpenAI(...))
session = Session(agent, progress_file="progress.json")
session.create_task("Analyze documents", [
    "Read and classify documents",
    "Summarize each group",
    "Write final report",
])
session.run_until_complete(max_sessions=5)

Tracing

Every agent call is automatically traced to ~/.underthesea/traces/. Disable with UNDERTHESEA_TRACE_DISABLED=1.

from underthesea.agent import Agent, LangfuseTracer, calculator_tool

# Auto local trace (default) — zero config
agent = Agent(name="bot", tools=[calculator_tool])
agent("What is 2+2?")
# >> Trace [a1b2c3] bot
#    |-- Generation: llm.chat #1 (gpt-4.1-mini) ... 1200ms | 100->18 tokens
#    |-- Tool: tool.calculator ... 0ms
#    |-- Generation: llm.chat #2 (gpt-4.1-mini) ... 800ms | 150->12 tokens
# << Trace [a1b2c3] [ok] 2000ms -> ~/.underthesea/traces/20260411_trace_a1b2c3.json

# Langfuse (pip install langfuse)
agent = Agent(name="bot", tools=[calculator_tool], tracer=LangfuseTracer())

# @trace decorator — nested functions become child spans
from underthesea.agent.trace import trace, LocalTracer

@trace(LocalTracer())
def pipeline(text):
    return Agent(name="bot")(text)  # auto-inherits trace context

Architecture

underthesea.agent
├── providers/
│   ├── OpenAI          # api.openai.com
│   ├── AzureOpenAI     # *.openai.azure.com
│   ├── Anthropic       # api.anthropic.com
│   └── Gemini          # generativelanguage.googleapis.com
├── trace/
│   ├── LocalTracer     # JSON files to ~/.underthesea/traces/
│   ├── LangfuseTracer  # Langfuse v4 observability
│   └── @trace          # Decorator with auto-nesting
├── Agent               # Tool calling loop + streaming
├── LLM                 # Auto-detect provider from env vars
├── Session             # Multi-session orchestration
├── Tool                # Function → tool wrapper
└── default_tools       # 12 built-in tools

Vietnamese NLP

See full documentation at NLP.md.

Pipeline Usage
Sentence Segmentation sent_tokenize(text)
Text Normalization text_normalize(text)
Word Segmentation word_tokenize(text)
POS Tagging pos_tag(text)
Chunking chunk(text)
Named Entity Recognition ner(text)
Text Classification classify(text)
Sentiment Analysis sentiment(text)
Language Detection lang_detect(text)
Dependency Parsing dependency_parse(text)
Translation translate(text)
Text-to-Speech tts(text)
from underthesea import word_tokenize, ner, sentiment

word_tokenize("Chàng trai 9X Quảng Trị khởi nghiệp từ nấm sò")
# ["Chàng trai", "9X", "Quảng Trị", "khởi nghiệp", "từ", "nấm", "sò"]

ner("Chưa tiết lộ lịch trình tới Việt Nam của Tổng thống Mỹ Donald Trump")
# [... ('Việt Nam', 'Np', 'B-NP', 'B-LOC'), ... ('Donald', 'Np', 'B-NP', 'B-PER'), ('Trump', 'Np', 'B-NP', 'I-PER')]

sentiment("Sản phẩm hơi nhỏ nhưng chất lượng tốt, đóng gói cẩn thận.")
# 'positive'

Contributing

Do you want to contribute with underthesea development? Great! Please read more details at Contributing Guide

💝 Support Us

If you found this project helpful and would like to support our work, you can just buy us a coffee ☕.

Your support is our biggest encouragement 🎁!

9.5.0 May 17, 2026
9.4.0 Apr 11, 2026
9.3.0 Apr 11, 2026
9.2.11 Feb 07, 2026
9.2.10 Feb 07, 2026
9.2.9 Feb 03, 2026
9.2.8 Feb 02, 2026
9.2.7 Feb 02, 2026
9.2.6 Feb 02, 2026
9.2.5 Feb 02, 2026
9.2.4 Feb 02, 2026
9.2.3 Feb 02, 2026
9.2.2 Feb 02, 2026
9.2.1 Feb 01, 2026
9.2.0 Jan 31, 2026
9.1.5 Jan 29, 2026
9.1.4 Jan 24, 2026
9.1.3 Jan 24, 2026
9.1.2 Jan 24, 2026
9.1.1 Jan 24, 2026
9.1.0 Jan 24, 2026
9.0.0 Jan 23, 2026
8.3.0 Sep 28, 2025
8.3.0a2 Sep 28, 2025
8.3.0a1 Sep 27, 2025
8.3.0a0 Sep 27, 2025
8.2.0 Sep 21, 2025
8.2.0a1 Sep 21, 2025
8.2.0a0 Sep 21, 2025
8.1.0 Sep 21, 2025
8.1.0a0 Sep 21, 2025
8.0.1 Sep 21, 2025
8.0.1a1 Sep 20, 2025
8.0.1a0 Sep 20, 2025
8.0.0 Sep 20, 2025
8.0.0a1 Sep 20, 2025
6.8.4 Jun 22, 2024
6.8.3 Jun 08, 2024
6.8.0 Sep 22, 2023
6.7.0 Jul 28, 2023
6.6.0 Jul 27, 2023
6.5.0 Jul 14, 2023
6.4.0 Jul 14, 2023
6.3.0 Jun 28, 2023
6.2.0 Mar 04, 2023
6.1.4 Feb 26, 2023
6.1.3 Feb 25, 2023
6.1.2 Feb 15, 2023
6.1.1 Feb 10, 2023
6.1.0 Feb 08, 2023
6.0.3 Jan 25, 2023
6.0.2 Jan 17, 2023
6.0.1 Jan 08, 2023
6.0.0 Jan 01, 2023
1.4.1 Dec 23, 2022
1.4.1a0 Dec 16, 2022
1.4.0 Dec 11, 2022
1.4.0a3 Nov 20, 2022
1.4.0a2 Nov 11, 2022
1.4.0a1 Nov 07, 2022
1.4.0a0 Nov 03, 2022
1.3.5 Oct 31, 2022
1.3.5a3 Aug 13, 2022
1.3.5a2 Aug 12, 2022
1.3.5a1 Aug 08, 2022
1.3.5a0 Jun 28, 2022
1.3.4 Jan 08, 2022
1.3.4a2 Nov 18, 2021
1.3.4a1 Nov 17, 2021
1.3.4a0 Nov 17, 2021
1.3.3 Sep 02, 2021
1.3.3a1 Sep 02, 2021
1.3.3a0 Aug 08, 2021
1.3.2 Aug 04, 2021
1.3.2a3 Aug 04, 2021
1.3.2a2 Aug 04, 2021
1.3.2a1 Jan 18, 2021
1.3.2a0 Jan 11, 2021
1.3.1 Jan 11, 2021
1.3.1a2 Jan 07, 2021
1.3.1a1 Dec 27, 2020
1.3.1a0 Dec 25, 2020
1.3.0 Dec 11, 2020
1.3.0a2 Dec 10, 2020
1.3.0a1 Nov 29, 2020
1.3.0a0 Nov 29, 2020
1.2.3 Nov 28, 2020
1.2.3a4 Nov 18, 2020
1.2.3a3 Nov 14, 2020
1.2.3a2 Nov 09, 2020
1.2.3a1 Nov 09, 2020
1.2.2 Nov 04, 2020
1.2.2a1 Nov 01, 2020
1.2.2a0 Oct 30, 2020
1.2.1 Oct 28, 2020
1.2.1a1 Oct 28, 2020
1.2.1a0 Oct 28, 2020
1.2.0 Oct 28, 2020
1.2.0a3 Oct 28, 2020
1.2.0a2 Oct 28, 2020
1.2.0a1 Jul 03, 2020
1.2.0a0 Jul 02, 2020
1.1.17 Aug 29, 2019
1.1.17a1 Aug 29, 2019
1.1.17a0 Aug 29, 2019
1.1.16 Jun 15, 2019
1.1.16a2 Jun 15, 2019
1.1.16a1 Jun 15, 2019
1.1.16a0 Jun 15, 2019
1.1.15 Mar 13, 2019
1.1.14 Mar 13, 2019
1.1.13 Mar 13, 2019
1.1.12 Mar 13, 2019
1.1.12a0 Mar 13, 2019
1.1.11 Jan 13, 2019
1.1.10 Jan 13, 2019
1.1.9 Jan 01, 2019
1.1.9a6 Oct 04, 2018
1.1.9a5 Sep 17, 2018
1.1.9a4 Sep 17, 2018
1.1.9a3 Sep 17, 2018
1.1.9a2 Aug 18, 2018
1.1.9a1 Jul 24, 2018
1.1.9a0 Jul 24, 2018
1.1.8 Jun 20, 2018
1.1.8a0 May 06, 2018
1.1.7 Apr 29, 2018
1.1.7a2 Apr 11, 2018
1.1.7a1 Apr 11, 2018
1.1.7a0 Apr 11, 2018
1.1.6 Jan 24, 2018
1.1.6rc2 Dec 30, 2017
1.1.6rc0 Dec 26, 2017
1.1.6a1 Dec 30, 2017
1.1.6a0 Dec 23, 2017
1.1.5 Oct 25, 2017
1.1.5rc1 Oct 12, 2017
1.1.4rc2 Sep 13, 2017
1.1.4rc1 Sep 13, 2017
1.1.3 Aug 25, 2017
1.1.2 Aug 24, 2017
1.1.1 Jul 04, 2017
1.1.0 May 30, 2017
1.0.20 May 26, 2017
1.0.19 May 25, 2017
1.0.18 May 24, 2017
1.0.17 May 24, 2017
1.0.16 May 23, 2017
1.0.15 May 09, 2017
1.0.14 May 09, 2017
1.0.13 May 08, 2017
1.0.12 Apr 07, 2017
1.0.11 Mar 31, 2017
1.0.10 Mar 23, 2017
1.0.9 Mar 07, 2017
1.0.8 Mar 03, 2017
1.0.7 Mar 03, 2017
1.0.6 Mar 03, 2017
1.0.5 Mar 03, 2017
1.0.1 Mar 02, 2017
1.0.0 Mar 01, 2017

Wheel compatibility matrix

Platform Python 3
any

Files in release