# gorot **Repository Path**: tp5test/gorot ## Basic Information - **Project Name**: gorot - **Description**: go agent test - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-30 - **Last Updated**: 2026-07-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # gorot > 仓库地址:https://gitee.com/tp5test/gorot 基于 [Eino](https://github.com/cloudwego/eino) 框架的 LLM ReAct Agent 应用。六边形架构(Hexagonal Architecture),技能驱动、流式输出、工具调用,CLI + HTTP (Gin/SSE) 双入口。 ## 架构 ``` cmd/ 入口(薄,仅组装依赖) ▼ adapter/input/ 输入适配器 ├─ sse/ Gin HTTP SSE(中间件: recovery / trace / CORS) └─ cli/ 交互式 REPL ▼ app/ 应用层 ├─ service.go ChatService(MCP注册 + Agent创建 + 回调注入 + 编排) └─ dto.go/config.go DTO + 配置 ▼ domain/ 领域层(零外部依赖) ├─ skill.go/agent.go/event.go/tool.go 核心接口 └─ trace.go TokenUsage 值对象 ▼ adapter/output/ 输出适配器 ├─ chatmodel/ LLM 模型(opencode / deepseek / local) ├─ mcp/ MCP 客户端 + 工具注册 ├─ skillrepo/ 技能加载器 └─ callback/ Eino callbacks(trace + token 日志) pkg/ 基础设施 ├─ config/ 环境变量加载 ├─ logger/ slog + trace_id + 日期文件 ├─ httpx/ Resty HTTP 客户端封装 ├─ session/ 会话/记忆持久化(File / InMem) └─ registry/ 工具/模型注册表 ``` ## 目录结构 ``` gorot/ ├── cmd/ │ ├── cli/main.go CLI 入口(交互式 REPL) │ └── server/ │ ├── main.go HTTP 入口(Gin + SSE) │ └── chat.html 内嵌前端 │ ├── internal/ │ ├── domain/ # 零外部依赖 │ │ ├── skill.go Skill 接口 │ │ ├── agent.go Agent 接口 │ │ ├── event.go Event 接口 + 事件类型 │ │ ├── tool.go Tool 接口 + ToolResult │ │ └── trace.go TraceInfo + TokenUsage │ │ │ ├── app/ # 应用编排 │ │ ├── service.go ChatService(MCP + Agent + Callbacks) │ │ ├── dto.go ChatRequest / ChatResponse │ │ └── config.go ChatServiceConfig │ │ │ ├── adapter/ │ │ ├── input/ │ │ │ ├── cli/repl.go CLI 事件渲染 │ │ │ └── sse/ │ │ │ ├── handler.go Gin SSE HandlerFunc │ │ │ ├── serializer.go Event → JSON │ │ │ └── gin_middleware.go Trace / CORS 中间件 │ │ └── output/ │ │ ├── chatmodel/ LLM 适配(opencode / deepseek / local) │ │ ├── mcp/ MCP 客户端 + 工具注册 │ │ ├── skillrepo/ 技能加载器 │ │ └── callback/ Eino callbacks(trace + token) │ │ │ ├── pkg/ # 基础设施 │ │ ├── config/config.go os.Getenv 统一加载 │ │ ├── logger/logger.go slog + trace_id + 日志文件 │ │ ├── httpx/client.go Resty 封装 │ │ ├── session/ Session + File/InMem 持久化 │ │ └── registry/registry.go 工具 / 模型注册表 │ │ │ ├── agents/ # [待迁移] ReAct 循环引擎 │ │ ├── react_stream.go 手动 ReAct 循环(核心,不改动) │ │ ├── skill.go Skill 结构体 │ │ └── skill_loader.go ParseSkill │ ├── chatmodel/ # [待迁移] 旧模型工厂 │ ├── tools/ # [待迁移] 旧工具 │ └── skills/ # 仅保留 .md 技能定义 │ ├── recruitment.md │ └── user_assistant.md │ ├── sessions/ # File Memory 持久化目录 ├── logs/ # 日期日志(如 2026-07-30) ├── .env.example # 环境变量模板(复制为 .env 后填写密钥) ├── go.mod └── go.sum ``` ## 快速开始 ```bash # 1. 配置环境 cp .env.example .env # 编辑 .env 填入 API Key # 2. CLI 交互模式 go run cmd/cli/main.go --env-file .env # 3. HTTP 服务模式 go run cmd/server/main.go --env-file .env # 访问 http://localhost:8082 ``` ### 构建与测试 ```bash go build ./... # 编译全部包 go test ./... # 运行单元测试 go vet ./... # 静态检查 ``` ## 配置 核心环境变量(`.env` 文件或 `--env-file` 参数): | 变量 | 默认值 | 说明 | |------|--------|------| | `GOROT_OPENCODE_API_KEY` | — | opencode.ai API Key | | `GOROT_OPENCODE_BASE_URL` | `https://opencode.ai/zen/v1` | opencode API 地址 | | `GOROT_OPENCODE_MODEL` | `deepseek-v4-flash-free` | 默认模型 | | `GOROT_DEEPSEEK_API_KEY` | — | DeepSeek API Key | | `GOROT_DEEPSEEK_BASE_URL` | `https://api.deepseek.com` | DeepSeek API 地址 | | `GOROT_DEEPSEEK_MODEL` | `deepseek-v4-flash` | DeepSeek 模型 | | `GOROT_LOCAL_API_KEY` | — | 本地模型 API Key | | `GOROT_LOCAL_BASE_URL` | `http://172.16.0.101:8000/v1` | 本地模型地址 | | `GOROT_LOCAL_MODEL` | `Qwen3.6-35B-A3B` | 本地模型名 | | `GOROT_MCP_URL` | — | MCP 服务地址 | | `GOROT_MCP_SECRET` | — | MCP 访问密钥 | | `GOROT_MEMORY_TYPE` | `inmem` | 后端: `inmem` / `file` | | `GOROT_GIN_PORT` | `8082` | HTTP 服务端口 | ## HTTP API ``` POST /api/chat Content-Type: application/json {"message": "推荐岗位", "session_id": "sess-1"} ``` SSE 响应(每个事件一行 `data:`): ```json {"type":"text","content":"好的"} {"type":"tool_start","tool_name":"get_weknora_knowledge","arguments":"{\"search_key\":\"岗位\"}"} {"type":"tool_end","tool_name":"get_weknora_knowledge"} {"type":"text","content":"根据知识库..."} ``` 响应头带 `X-Trace-ID`,前端可通过该值追踪整条请求链路。 ## 日志 日志输出到控制台和按日期的文件: ``` logs/ └── 2026-07-30 # 每天的日志独立文件 ``` 格式为 slog text,key=value 对: ``` time=... level=INFO msg="model call end" trace_id=req-... prompt_tokens=120 completion_tokens=350 total_tokens=470 ``` 无论流式(Stream)还是非流式(Generate)的模型调用,结束时都会输出 `model call end` 并带上 token 用量;流式场景的用量来自最后一个 chunk(`OnEndWithStreamOutput` 回调)。 通过 `X-Trace-ID` 或 CLI 自动生成的 trace_id,可追踪 **请求入口 → 模型调用 → 工具调用 → MCP 调用** 全链路。 ## 技能系统 技能以 YAML front matter + Markdown 正文定义在 `internal/skills/`: ```markdown --- name: recruitment_assistant description: 招聘助手 model: deepseek tools: - get_weknora_knowledge --- 你是薪聘云招聘岗位推荐助手... ``` ### 现有技能 | 技能 | 文件 | 说明 | |------|------|------| | `recruitment_assistant` | `recruitment.md` | 招聘岗位推荐 | | `user_assistant` | `user_assistant.md` | 用户服务(含工资查询) | ### 新增技能 1. 在 `internal/skills/` 下创建 `.md` 文件 2. 如需新工具:在 `internal/tools/` 实现,在 `internal/pkg/registry/registry.go` `ToolRegistry` 注册 3. 如需新模型:在 `internal/chatmodel/model.go` 实现,在 `internal/pkg/registry/registry.go` `ModelRegistry` 注册 4. 在 `internal/adapter/output/skillrepo/embedded.go` 添加加载函数 5. 在入口文件中通过 `ChatServiceConfig.Skill` 切换 ## TODO ### 架构遗留 - [ ] **旧包完全清理**:`internal/agents/`、`internal/chatmodel/`、`internal/tools/` 仍被引用,待所有消费方迁到新 adapter 后可删除 - [ ] **CLI 多轮会话**:CLI 每轮调用 `svc.Chat()` 不传 SessionID,无法跨轮复用历史 - [ ] **技能运行时切换**:技能启动时固定,不支持运行时动态切换 ### 功能 - [ ] **Auth 中间件**:Gin 路由无认证 - [ ] **Rate Limit 中间件**:API 无频率限制 - [ ] **更多 Memory 后端**:SQLite / Redis - [ ] **上下文窗口裁剪**:长对话 token 超限时的压缩策略 - [ ] **多 Agent 协作**:复杂任务拆子任务并行 ### 测试 - [ ] **单元测试**:domain / app / adapter 层均无 UT - [ ] **集成测试**:无端到端测试覆盖 ### 可观测性 - [ ] **指标导出**:Prometheus metrics(QPS / 延迟 / token 用量趋势) - [ ] **告警**:API Key 失效 / MCP 连接断开自动通知 ## 技术栈 | 组件 | 说明 | |------|------| | [Eino](https://github.com/cloudwego/eino) | 字节 LLM 应用框架(model / tool / callbacks ) | | [eino-ext/openai](https://github.com/cloudwego/eino-ext) | OpenAI 兼容模型 | | [Gin](https://github.com/gin-gonic/gin) | HTTP 框架 + 中间件 | | [Resty](https://github.com/go-resty/resty) | HTTP 客户端(工具调用) | | [godotenv](https://github.com/joho/godotenv) | .env 文件加载 | | [mcp-go](https://github.com/mark3labs/mcp-go) | MCP 协议客户端 | | `embed` | Go 内置(技能 .md 嵌入二进制) | | `log/slog` | Go 1.21+ 结构化日志 |