Underthesea AI Agent

by undertheseanlp• 1.8k•• Scanned•Claim this listing•Request removal
Otheragentic aiagentsaiassistanthermes agent

Underthesea - AI Assistant

Underthesea is an open-source ai agent by undertheseanlp, written mainly in Python, with 1,814 GitHub stars and the Apache-2.0 license. Its code was last updated Nov 1, 2026. The latest PyPI release is underthesea 9.5.0, published May 17, 2026, with 10,716 downloads last week.

<p align="center"> <br> <img src="https://raw.githubusercontent.com/undertheseanlp/underthesea/main/docs/static/img/logo.png"/> <br/> </p> <p align="center"> <a href="https://pypi.python.org/pypi/underthesea"> <img src="https://img.shields.io/pypi/v/underthesea.svg"> </a> <a href="https://pypi.python.org/pypi/underthesea"> <img src="https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue"> </a> <a href="http://undertheseanlp.com/"> <img src="https://img.shields.io/badge/demo-live-brightgreen"> </a> <a href="https://undertheseanlp.github.io/underthesea/"> <img src="https://img.shields.io/badge/docs-live-brightgreen"> </a> <a href="https://colab.research.google.com/drive/1gD8dSMSE_uNacW4qJ-NSnvRT85xo9ZY2"> <img src="https://img.shields.io/badge/colab-ff9f01?logo=google-colab&logoColor=white"> </a> <a href="https://www.facebook.com/undertheseanlp/"> <img src="https://img.shields.io/badge/Facebook-1877F2?logo=facebook&logoColor=white"> </a> <a href="https://www.youtube.com/channel/UC9Jv1Qg49uprg6SjkyAqs9A"> <img src="https://img.shields.io/badge/YouTube-FF0000?logo=youtube&logoColor=white"> </a> </p> <br/> <p align="center"> <a href="https://github.com/undertheseanlp/underthesea/blob/main/docs/contribute/SPONSORS.md"> <img src="https://img.shields.io/badge/sponsors-30-red?style=social&logo=GithubSponsors"> </a> </p> <h3 align="center"> Open-source Agentic AI Toolkit </h3>

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

Serving (A2A)

Expose any agent over the A2A protocol — JSON-RPC message/stream over HTTP+SSE with a discoverable AgentCard and an optional bundled chat UI. The server is a raw ASGI app with no web-framework dep in the base install — plug it into any ASGI server you like.

# Optional convenience extra: uvicorn + starlette + httpx
$ pip install 'underthesea[agent-server]'
from underthesea.agent import Agent, Tool
from underthesea.agent.server import serve

def add(a: int, b: int) -> int:
    """Add two integers."""
    return a + b

agent = Agent(name="MathAgent", instruction="...", tools=[Tool(add)])
serve(agent, port=8000, path="/a2a/math", ui=True)
# → GET  http://127.0.0.1:8000/a2a/math/ui            (bundled chat UI)
# → GET  http://127.0.0.1:8000/a2a/math/.well-known/agent-card.json
# → POST http://127.0.0.1:8000/a2a/math               (JSON-RPC message/stream, SSE)

For custom routing or your own ASGI server, use make_app():

from underthesea.agent.server import make_app

app = make_app(agent, path="/a2a/math")  # → raw ASGI callable
# uvicorn module:app
# hypercorn module:app
# daphne module:app

One Agent is spawned per A2A contextId so each conversation keeps its own history. Tool calls are streamed live as tool_call artifacts; the agent's reply arrives as a text artifact when the loop finishes.

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
├── server/
│   ├── make_app        # Raw ASGI callable (JSON-RPC + SSE + AgentCard)
│   ├── serve           # uvicorn convenience entrypoint
│   └── static/         # Bundled chat UI (ui=True)
├── 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.

PipelineUsage
Sentence Segmentationsent_tokenize(text)
Text Normalizationtext_normalize(text)
Diacritics Restorationrestore_diacritics(text)
Word Segmentationword_tokenize(text)
POS Taggingpos_tag(text)
Chunkingchunk(text)
Named Entity Recognitionner(text)
Text Classificationclassify(text)
Sentiment Analysissentiment(text)
Language Detectionlang_detect(text)
Dependency Parsingdependency_parse(text)
Translationtranslate(text)
Text-to-Speechtts(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 🎁!

<img src="https://raw.githubusercontent.com/undertheseanlp/underthesea/main/docs/static/img/support.png"/>

Underthesea alternatives

View more →

Similar ai agents in Other, ranked by GitHub stars. Compare licence, recent activity and scan status before you choose.

NameStarsLicenceLast updatedScan
Underthesea (this page)
undertheseanlp
1.8kApache-2.0Nov 1, 2026Scanned, no flagged issues
Hermes Desktop
fathah
15kMITOct 13, 2026Scanned, no flagged issues
CubeSandbox
TencentCloud
13kNone foundNov 1, 2026Not scanned yet
Openchamber
openchamber
12kMITNov 1, 2026Scanned, no flagged issues
Open Swe
langchain-ai
11kMITNov 1, 2026Scanned, no flagged issues
Moltworker
cloudflare
9.9kApache-2.0May 9, 2026Scanned, no flagged issues