cloudwego/eino
The ultimate LLM/AI application development framework in Go.
Healthy across the board
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit today
- ✓14 active contributors
- ✓Distributed ownership (top contributor 31% of recent commits)
Show all 6 evidence items →Show less
- ✓Apache-2.0 licensed
- ✓CI configured
- ✓Tests present
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/cloudwego/eino)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/cloudwego/eino on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: cloudwego/eino
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/cloudwego/eino shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit today
- 14 active contributors
- Distributed ownership (top contributor 31% of recent commits)
- Apache-2.0 licensed
- CI configured
- Tests present
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live cloudwego/eino
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/cloudwego/eino.
What it runs against: a local clone of cloudwego/eino — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in cloudwego/eino | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of cloudwego/eino. If you don't
# have one yet, run these first:
#
# git clone https://github.com/cloudwego/eino.git
# cd eino
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of cloudwego/eino and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "cloudwego/eino(\\.git)?\\b" \\
&& ok "origin remote is cloudwego/eino" \\
|| miss "origin remote is not cloudwego/eino (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "adk/interface.go" \\
&& ok "adk/interface.go" \\
|| miss "missing critical file: adk/interface.go"
test -f "adk/handler.go" \\
&& ok "adk/handler.go" \\
|| miss "missing critical file: adk/handler.go"
test -f "adk/flow.go" \\
&& ok "adk/flow.go" \\
|| miss "missing critical file: adk/flow.go"
test -f "adk/callback.go" \\
&& ok "adk/callback.go" \\
|| miss "missing critical file: adk/callback.go"
test -f "adk/instruction.go" \\
&& ok "adk/instruction.go" \\
|| miss "missing critical file: adk/instruction.go"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~0d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/cloudwego/eino"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Eino is a Go framework for building LLM/AI applications with reusable components (ChatModel, Tool, Retriever, ChatTemplate), an Agent Development Kit (ADK) for tool-using agents with human-in-the-loop support, and composition primitives (graphs, chains, workflows) to orchestrate complex AI pipelines. It draws from LangChain and Google ADK but is designed specifically for Go conventions and idioms. Modular monorepo structure: adk/ contains the Agent Development Kit (ChatModelAgent, Runner, callback system, deterministic transfer); adk/filesystem/ provides pluggable storage backends (in-memory and file-based); compose/ likely contains composition primitives; tests are colocated with implementation (*_test.go). Core abstractions (ChatModel, Tool, etc.) are interface-driven, with implementations in the external eino-ext repo for OpenAI, Ollama, and others.
👥Who it's for
Go backend engineers building production AI agents and LLM applications who need structured tool calling, multi-agent coordination, context management, and interrupt/resume capabilities without the Python/JavaScript overhead of LangChain.
🌱Maturity & risk
Actively developed and production-ready. The project has decent GitHub visibility (inferred from CloudWeGo branding), comprehensive test coverage (test files across adk/, config management, callback handling), and organized CI/CD setup in .github/workflows/ including pr-check.yml, tests.yml, and release automation. The codebase is ~3MB of Go with recent activity indicated by test and workflow configurations.
Relatively low risk for a Go framework. Dependencies are lean and well-maintained (Bytedance/Sonic, Google UUID, smartystreets/goconvey for testing). Risk factors: the main ecosystem lives in eino-ext (external components) and eino-examples (external examples), so core stability depends on external repos; no visible breaking-change log in the snippet, so semver adherence unclear. Single-maintainer CloudWeGo team means community contribution velocity may vary.
Active areas of work
Active maintenance with PR checks and test automation in place. Test files like chatmodel_retry_test.go, callback_integration_test.go, and flow_test.go indicate ongoing work on reliability (retries), observability (callbacks), and workflow orchestration. The presence of .codedev.yml and .commit-rules.json suggests enforced code review and commit discipline.
🚀Get running
git clone https://github.com/cloudwego/eino.git
cd eino
go mod download
go test ./adk/...
No external services required for unit tests. Examples live in external eino-examples repo.
Daily commands:
go test ./...
for unit tests. For examples, clone eino-examples repo and follow instructions there (requires external LLM API keys like OpenAI). No dev server in traditional sense; Eino is a library, not a service.
🗺️Map of the codebase
adk/interface.go— Defines core interfaces (ChatModel, Agent, Tool) that all LLM application components must implement—foundational abstraction for the framework.adk/handler.go— Implements the Handler pattern for processing messages through the agent execution pipeline; critical for understanding request flow.adk/flow.go— Manages graph-based workflow orchestration and execution; enables complex multi-step AI application logic.adk/callback.go— Provides callback system for tracing, monitoring, and hooking into agent/chain execution; essential for observability.adk/instruction.go— Defines the Instruction type that drives agent reasoning and decision-making throughout execution cycles.adk/agent_tool.go— Abstracts tool/function-calling interface that agents use to interact with external systems and take actions.adk/call_option.go— Implements the option pattern for configuration and runtime customization across all framework components.
🛠️How to make changes
Add a Custom ChatModel Implementation
- Create a new struct in a provider package (e.g.,
providers/mymodel/chat.go) that implements theadk.ChatModelinterface defined inadk/interface.go(adk/interface.go) - Implement the required methods:
Generate()for streaming responses,GenerateOne()for single responses, andGetMessageHistory()for context management (providers/mymodel/chat.go (new)) - Add call options in
providers/mymodel/options.gousing thecall_option.gopattern to expose provider-specific configuration (temperature, model name, etc.) (adk/call_option.go) - Register the implementation in a factory function and add unit tests following the pattern in
adk/chatmodel_test.go(adk/chatmodel_test.go)
Add a New Middleware Layer
- Create a new middleware package in
adk/middlewares/(e.g.,adk/middlewares/myfeature/) (adk/middlewares/plantask/plantask.go) - Implement middleware that wraps a
Handlerand intercepts execution by modifying instructions, managing state, or filtering messages—reference existing middlewares likereduction.goandskill.go(adk/middlewares/reduction/reduction.go) - If the middleware needs persistence, define a backend interface (e.g.,
Backend) and implement in-memory and filesystem variants following the pattern inadk/middlewares/plantask/task.go(adk/middlewares/plantask/plantask.go) - Add comprehensive unit tests and integration tests in
*_test.gofiles validating middleware composition with other layers (adk/middlewares/plantask/plantask_test.go)
Add a Tool/Function Call Handler
- Define a new Tool struct in your application package implementing the
adk.Toolinterface fromadk/interface.go, withName,Description, andInvoke()method (adk/interface.go) - Use
adk.ToolCalltype (fromadk/agent_tool.go) to represent the tool invocation request with function name, arguments, and call ID (adk/agent_tool.go) - Register the tool with an Agent using call options defined in
adk/call_option.goor compose tools dynamically using theadk/middlewares/dynamictool/toolsearchmiddleware (adk/middlewares/dynamictool/toolsearch/toolsearch.go) - If the tool produces large results, use the filesystem middleware in
adk/middlewares/filesystem/to handle storage and reference management (adk/middlewares/filesystem/large_tool_result.go)
Build a Multi-Step Workflow with Flow
- Create a flow using
adk.NewFlow()and define nodes representing computational steps (agents, models, or custom handlers) as documented inadk/flow.go(adk/flow.go) - Connect nodes using
AddEdge()to create sequential steps, or useAddBranch()/AddParallel()for conditional and parallel execution patterns (adk/flow.go) - Use
deterministic_transfer.gologic or custom transfer functions to route execution based on instruction output, enabling feedback loops and dynamic control flow (adk/deterministic_transfer.go) - Attach callbacks via
callback.goto each node for tracing, and use interrupt signals frominterrupt.goto pause or cancel workflows based on external events (adk/callback.go)
🔧Why these technologies
- Go 1.18+ — Eino leverages Go's concurrency primitives (goroutines, channels) and generics for efficient, type-safe agent orchestration at scale.
- Graph-based flow composition (adk/flow.go) — Enables declarative multi-step AI workflows with parallel execution, branching, and dynamic routing—more flexible than linear chains.
- Interface-driven architecture (adk/interface.go) — Allows pluggable implementations of ChatModel, Agent, Tool, and Handler; enables vendor-agnostic integration with any LLM or external service.
- Callback & observability system (adk/callback.go) — Provides hooks into every stage of execution for tracing, metrics, debugging, and integration with APM/logging systems.
- Middleware stack (adk/middlewares/) — Composable layers (reduction, skill, task planning, filesystem) for cross-cutting concerns without modifying core agent logic.
⚖️Trade-offs already made
-
Graph-based flow over linear chain abstraction
- Why: Complexity: graphs are more expressive than chains for conditional routing and parallel execution, but require more careful composition and debugging.
- Consequence: Developers must design DAGs carefully; cycles/deadlocks are possible if transfer logic is misconfigured.
-
Callback-based observability over built-in logging
- Why: undefined
- Consequence: undefined
🪤Traps & gotchas
No build flags documented: unclear if //go:build tags gate optional dependencies. External ecosystem: Core implementations (OpenAI, Ollama, vector DBs) live in separate eino-ext repo—you'll need that for real usage; the main repo is framework-only. Config marshaling: uses gopkg.in/yaml.v3 and Sonic JSON, ensure consistency if mixing formats. Context propagation: callbacks and flow control rely on Go context passing; missing context.WithCancel() in chains can cause hangs. API keys: Quick Start example assumes OPENAI_API_KEY env var but no .env.example file provided. Test isolation: filesystem backend tests use in-memory by default; production testing requires explicit file backend selection in config.
🏗️Architecture
💡Concepts to learn
- ReAct Loop (Reasoning + Acting) — Core pattern in Eino agents; the loop decides when to call tools vs. respond directly. Understanding ReAct is essential to reasoning about agent behavior and debugging infinite loops.
- Interface-Driven Architecture (Go Idiom) — Eino's components (ChatModel, Tool, Retriever) are tiny interfaces, not concrete structs. This Go pattern enables dependency injection and swappable implementations without factory boilerplate.
- Callback/Observer Pattern — Eino's callback system (
adk/callback.go) decouples observability from core logic; understand pre/post hooks to add logging, metrics, and human-in-the-loop interrupts. - Function Calling / Tool Use (LLM Feature) — Modern LLMs return structured JSON tool calls instead of free text. Eino's
agent_tool.gowraps this; critical for deterministic agent behavior. - Context Propagation in Go — Eino passes
context.Contextthrough every API (agents, tools, callbacks). Mishandling context (e.g., missing cancellation) causes cascading failures; essential for timeout and graceful shutdown. - Deterministic Serialization / State Transfer — Eino's
deterministic_transfer.goenables interrupt/resume and multi-step agent persistence. Requires stable JSON field ordering (hencewk8/go-ordered-map) to avoid replay bugs. - Composition / Directed Acyclic Graph (DAG) — Eino's
flow.goand compose patterns let you wire agents, tools, and models into reusable pipelines. Understanding graph construction is key to building complex workflows without spaghetti code.
🔗Related repos
cloudwego/eino-ext— Official component implementations (OpenAI ChatModel, Ollama, vector stores); required for real-world Eino applications.cloudwego/eino-examples— Runnable examples for ChatModelAgent, multi-agent workflows, and tool use; essential reference for learning the API.langchain4j/langchain4j— LangChain port to JVM; architecturally similar composition and agent patterns—good for cross-ecosystem pattern research.google/generative-ai-go— Google's official Go SDK for Gemini API; simpler alternative for single-model use, but Eino's abstraction layer enables multi-model swapping.tmc/langchaingo— LangChain in Go community port; Eino's main Go alternative, though Eino has tighter ADK and tool-calling design.
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive integration tests for adk/middlewares/filesystem with large file handling
The filesystem middleware has a large_tool_result.go handler for managing large tool outputs, but there's no corresponding integration test file (large_tool_result_test.go exists but likely lacks end-to-end scenarios). This is critical for an AI framework where tool results could be large and filesystem handling is essential for production reliability.
- [ ] Create adk/middlewares/filesystem/large_tool_result_integration_test.go
- [ ] Add tests covering: in-memory vs filesystem storage transitions, concurrent access patterns, cleanup/lifecycle management
- [ ] Test interaction between large_tool_result.go and backend.go storage backends
- [ ] Add benchmarks for large result serialization/deserialization to catch performance regressions
Add GitHub Actions workflow for testing across multiple Go versions and platforms
The repo has .github/workflows/tests.yml and pr-check.yml, but they likely target a single Go version. Given the module targets go 1.18+, adding matrix testing across Go 1.18, 1.21, 1.22 and platforms (linux/amd64, linux/arm64, darwin/amd64) would catch version-specific bugs early, especially important for a framework with complex generic type usage and reflection.
- [ ] Enhance .github/workflows/tests.yml with Go version matrix (1.18, 1.21, 1.22+)
- [ ] Add OS matrix testing (ubuntu-latest, macos-latest, windows-latest) or at least linux/arm64
- [ ] Configure conditional failures (allow-failure for future versions while strict on LTS)
- [ ] Test against the sonic JSON library compatibility across versions (known to have platform-specific optimizations)
Add missing test coverage for adk/call_option.go and adk/config.go option builders
These files define critical configuration and call option patterns used throughout the framework, but call_option_test.go likely lacks edge cases. Options patterns in Go are prone to subtle bugs with nil receivers, ordering issues, and option conflicts that need explicit test coverage.
- [ ] Expand adk/call_option_test.go with: nil-safe option application, option override ordering, conflicting option handling
- [ ] Create adk/config_test.go (if missing) covering config validation, default values, and override scenarios
- [ ] Test integration between call_option.go and config.go to ensure options correctly propagate to config
- [ ] Add property-based tests using stretchr/testify to verify option composition properties (idempotency, associativity where applicable)
🌿Good first issues
- Add missing unit tests for
adk/filesystem/backend_inmemory.go's edge cases (overflow behavior, concurrent access patterns). Start at line 1 of the test file and add scenario matrices for memory limits. - Document the callback system lifecycle with a concrete example showing pre/post hook ordering for a multi-tool agent. Create
docs/callback_design.mdmirroring the patterns incallback_integration_test.go. - Implement a
LoggingCallbackwrapper inadk/callback.gothat outputs structured JSON logs for each agent step. Referencechatmodel_retry_test.gofor hook integration patterns.
⭐Top contributors
Click to expand
Top contributors
- @shentongmartin — 31 commits
- @meguminnnnnnnnn — 17 commits
- @hi-pender — 16 commits
- @JonXSnow — 13 commits
- @mrh997 — 8 commits
📝Recent commits
Click to expand
Recent commits
5e13055— fix(adk): preserve full ToolsNodeConfig fields on runtime tool updates (#1005) (JonXSnow)1aee289— fix(adk): correct tool handler wrapping order to match model path (#1000) (shentongmartin)4eafc54— feat(adk): reduction mw support tool_call & tool_resp messages rewrite (#956) (N3kox)9b80f95— feat(adk): add enhanced tool call related usage in middlewares (#990) (N3kox)7ac01e2— fix(adk): eagerly consume stream in GobEncode to prevent checkpoint failure on model retry (#980) (shentongmartin)d25ced3— feat(adk): PreserveSkillsConfig support MaxTokensPerSkill and SkillsTokenBudget (#967) (mrh997)7677537— feat(adk): add SummarizeMessages for on-demand synchronous summarization (#958) (mrh997)0b607bf— feat(adk): refactor summarization middleware with retry support (#902) (mrh997)5220676— feat(adk): reduction middleware support TruncExcludeTools (#946) (N3kox)27bb4ae— feat(adk): reduction middleware add TruncResult.StreamToolResult (#941) (N3kox)
🔒Security observations
The eino project demonstrates reasonable security practices for an LLM/AI development framework. Key concerns include: (1) Dynamic tool loading mechanisms that could be exploited if not properly validated, (2) Use of template engines and reflection libraries that require careful input validation, (3) Filesystem operations that need strict access controls, and (4) Outdated Go version target. The codebase lacks visible security configuration documentation and HTTPS/TLS setup guidance. No hardcoded secrets were identified in the visible file structure. Overall security posture is moderate; recommendations focus on input validation, dynamic code execution sandboxing, and security documentation improvements.
- Medium · Use of Deprecated/Unmaintained Dependency —
go.mod - github.com/nikolalohinski/gonja v1.5.3. The project uses 'github.com/nikolalohinski/gonja v1.5.3', which is a Jinja2 template engine port. Template engines can be vectors for injection attacks if user input is not properly sanitized before template rendering. Fix: Verify that all template rendering in the codebase properly escapes and validates user input. Consider using Go's native html/template instead if feasible. Ensure the dependency is actively maintained and regularly check for security advisories. - Medium · Potential Code Execution via Dynamic Tool Loading —
adk/middlewares/dynamictool/. The codebase includes 'adk/middlewares/dynamictool' functionality which appears to dynamically load and execute tools. This could be a vector for arbitrary code execution if tool sources are not properly validated. Fix: Implement strict validation and sandboxing for dynamically loaded tools. Use allowlists for permitted tools, validate tool signatures, and run tools with minimal privileges. Review the toolsearch and tool loading mechanisms for injection vulnerabilities. - Medium · Unsafe Reflection Usage Potential —
go.mod - github.com/modern-go/reflect2. The dependency 'github.com/modern-go/reflect2' is used, which provides unsafe reflection operations. Improper use of reflection on untrusted input can lead to type confusion and memory safety issues. Fix: Review all code using reflect2 to ensure it operates only on trusted, validated data structures. Avoid using reflection on user-supplied input. Add strict type checking before reflection operations. - Low · Missing HTTPS/TLS Configuration Documentation —
Repository root - no tls/security config visible. No security configuration files or documentation visible for TLS/HTTPS setup in the repository structure, which is critical for LLM/AI applications handling sensitive data. Fix: Add documentation for secure TLS configuration, certificate management, and HTTPS enforcement. Provide secure defaults in example configurations. - Low · Potential Data Exposure via Filesystem Middleware —
adk/middlewares/filesystem/. The 'adk/middlewares/filesystem' component handles large tool results and file operations. Improper file access controls could lead to unauthorized data access. Fix: Implement strict file access controls, validate all file paths against path traversal attacks, use principle of least privilege for file operations, and sanitize all file paths. - Low · Outdated Go Version —
go.mod - go 1.18. The project targets Go 1.18 which was released in March 2022. Current stable versions are significantly newer, and older versions may have known security vulnerabilities. Fix: Update to the latest stable Go version (1.22+) to benefit from security patches and improvements. Test thoroughly for compatibility. - Low · Missing Security Headers Documentation —
Repository root. No visible security headers, CORS, or authentication configuration in the repository structure for the LLM/AI framework. Fix: Document security best practices including CORS configuration, authentication/authorization requirements, rate limiting, and security headers for applications using this framework.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.