Skip to content
Ruanjq98Public

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Chatbot Agent

一个基于 OpenAI 兼容 API 的智能对话 Agent,支持原生 Function Calling 工具调用循环、多轮会话记忆(含自动压缩)、RAG 个人知识库、可加载的技能指令包,以及全链路 Trace 追踪。

功能概览

  • 工具调用 Agent — 在 LLM 与工具之间循环推理,直到产出最终回答(基于原生 function calling,非 ReAct 文本解析)
  • 多轮会话记忆 — SQLite 持久化,后台线程异步压缩旧对话为摘要,提取长期事实,按会话隔离
  • RAG 知识库 — 混合检索(向量 + FTS 全文),支持导入 .md / .txt / .pdf / .docx,LLM 可通过 kb_search 工具自主检索
  • 技能系统 — 可加载的指令包(Skill),扫描仓库与用户目录,按需注入 system prompt,内置 code-review 技能
  • 上下文预算管理 — CJK 感知的 token 计数,对系统消息、工具结果、调用轨迹分别预算截断
  • Trace 追踪 — OTel 语义兼容的轻量追踪,LLM 请求/响应、工具调用全量落盘为 JSONL
  • 事件流中间件 — 异步生成器中间件链,可插入日志、追踪等观察组件

快速开始

环境要求

  • Python >= 3.11(需要 SQLite >= 3.45,用于知识库 FTS 与 sqlite-vec)

安装

# 创建虚拟环境
python -m venv .venv
# Windows
.venv\Scripts\activate
# Linux/macOS
source .venv/bin/activate

# 安装依赖
pip install -r requirements.txt

配置

复制 .env.example 为 .env,填入你的 API 配置:

cp .env.example .env
OPENAI_API_KEY=your_api_key_here
OPENAI_BASE_URL=https://api.openai.com/v1
MODEL_NAME=gpt-4o-mini

支持任何 OpenAI 兼容的 API 服务(如智谱、DeepSeek 等),只需修改 OPENAI_BASE_URL 和 MODEL_NAME。

运行

# 交互式会话(默认)
python main.py

# 指定会话 ID
python main.py --session alice

# 单次执行问题
python main.py --once "2+3*4等于多少"

# 列出所有会话
python main.py --list-sessions

# 批量导入文档到知识库
python main.py --kb-ingest docs/

# DEBUG 级别日志 + 写入文件
python main.py --verbose --log-file app.log

交互模式斜杠命令

命令 说明
/sessions 列出所有会话
/switch ID 切换会话
/clear 清空当前会话
/facts 显示长期事实
/summary 显示历史摘要
/skills 列出所有技能
/skill <名称> 查看技能指令正文
/kb [查询] 检索知识库
/kb-stats 知识库文档/切片统计

项目结构

chatbot/
├── core/                # Agent 核心
│   ├── agent.py         #   事件流 Agent(工具调用循环)
│   ├── events.py        #   事件定义(RunStarted/LLMChunk 等)
│   ├── middleware.py    #   异步生成器中间件机制
│   ├── state.py         #   运行状态
│   ├── checkpoint.py    #   HITL 检查点
│   ├── structured.py    #   结构化输出
│   └── subagent.py      #   子代理
├── llm_client.py         # LLM 客户端:超时 + 指数退避重试
├── main.py               # CLI 入口:交互式 / 单次 / 知识库导入
├── prompts.py            # 系统提示词模板
├── tools/                # 工具模块
│   ├── base.py           #   Tool / ToolResult / @tool 装饰器
│   ├── registry.py       #   工具注册表
│   ├── executor.py       #   工具执行器
│   ├── calculator.py     #   内置工具:计算器
│   └── datetime_tool.py  #   内置工具:日期时间查询
├── memory/               # 记忆模块(SQLite 持久化)
│   ├── manager.py        #   门面:存储 + 异步压缩
│   ├── compressor.py     #   后台压缩线程
│   ├── session_store.py  #   会话存储
│   ├── turn_store.py     #   对话轮次存储
│   ├── summary_store.py  #   摘要存储
│   ├── fact_store.py     #   长期事实存储
│   └── llm.py            #   压缩用 LLM 接口
├── context/              # 上下文管理
│   ├── manager.py        #   预算分配 + 截断 + 多消息组装
│   ├── provider.py       #   Provider 接口(记忆/技能/知识库)
│   ├── fragment.py       #   上下文片段
│   └── token_counter.py  #   CJK 感知 token 计数
├── knowledge/            # RAG 知识库
│   ├── ingest/           #   文档导入管道(加载/切分/嵌入)
│   ├── retriever.py     #   混合检索(向量 + FTS)
│   ├── embedder.py       #   嵌入模型封装
│   ├── search_tool.py    #   kb_search 工具
│   ├── db.py             #   知识库表结构
│   └── schema.sql        #   SQL schema
├── skills/               # 技能模块
│   ├── manager.py        #   技能管理器(扫描/加载)
│   ├── model.py          #   Skill 数据模型
│   ├── provider.py       #   技能索引注入 Provider
│   ├── load_tool.py      #   load_skill 工具
│   └── code-review/      #   内置技能:代码审查
├── trace/                # Trace 追踪
│   ├── model.py          #   Span / SpanStatus 模型
│   ├── recorder.py       #   记录器
│   └── exporter.py       #   JSONL 导出器
├── logger/               # 日志与事件流中间件
│   ├── setup.py          #   日志配置
│   ├── logging_middleware.py #   日志中间件
│   └── trace_middleware.py   #   Trace 中间件
└── tests/                # 测试套件

环境变量

变量 默认值 说明
OPENAI_API_KEY (必填) API 密钥
OPENAI_BASE_URL https://api.openai.com/v1 API 地址
MODEL_NAME gpt-4o-mini 模型名称
LLM_TIMEOUT 60 请求超时(秒)
LLM_MAX_ATTEMPTS 3 最大尝试次数(含首次)
CHATBOT_DB_PATH data/chatbot.db SQLite 数据库路径
CHATBOT_SKILLS_DIR skills 仓库技能目录
CHATBOT_USER_SKILLS_DIR ~/.chatbot/skills 用户技能目录
CHATBOT_KB_ENABLED true 是否启用知识库
EMBEDDING_MODEL text-embedding-3-small 嵌入模型
EMBEDDING_DIM 1536 嵌入维度
EMBEDDING_BASE_URL 同 OPENAI_BASE_URL 嵌入 API 地址
EMBEDDING_API_KEY 同 OPENAI_API_KEY 嵌入 API 密钥
CHATBOT_TRACE_DIR (空,关闭) Trace 落盘目录
CHATBOT_TRACE_MAX_BYTES 52428800 (50MB) Trace 文件轮转阈值

核心设计

Agent 工具调用循环

Agent 在 LLM 与工具之间循环:每轮将 system prompt + 记忆 + 当前问题 + 累积的工具调用轨迹发送给 LLM。若 LLM 返回 tool_calls,则逐个执行工具并将结果回传;若 LLM 返回纯文本,即为最终回答。最大迭代次数防止死循环。

多轮记忆与异步压缩

  • 每轮对话同步写入 SQLite(turns 表),保证不丢失
  • 后台 daemon 线程串行执行压缩:将最旧的 N 条对话通过 LLM 压缩为摘要,提取长期事实
  • 压缩异步化,用户无需等待 LLM 压缩调用即可看到回答

上下文预算管理

ContextManager 统一管理系统消息的组装与 token 预算:

  • total_tokens — 基础消息预算(system + 历史 + 问题)
  • observation_max_tokens — 单条工具结果截断上限
  • trace_max_tokens — 工具调用轨迹截断上限(按消息组整组裁剪)

技能系统

技能(Skill)是可加载的指令包,由 SKILL.md(frontmatter + 指令正文)定义:

  • 启动时扫描仓库 skills/ 与用户 ~/.chatbot/skills/ 目录
  • 技能索引注入 system prompt,LLM 可通过 load_skill 工具按需加载完整指令
  • 内置 code-review 技能示例

RAG 知识库

  • 导入:IngestPipeline 加载文档 → 切分 → 嵌入 → 存储(支持 .md / .txt / .pdf / .docx)
  • 检索:HybridRetriever 结合向量相似度与 FTS 全文检索
  • 工具化:封装为 kb_search 工具,LLM 可在对话中自主检索知识库

测试

# 运行全部测试
.venv\Scripts\python -m pytest

# 运行指定模块测试
.venv\Scripts\python -m pytest tests/test_memory/

# 显示详细输出
.venv\Scripts\python -m pytest -v

测试覆盖所有核心模块:Agent、工具、记忆、上下文、知识库、技能、追踪、日志。

扩展指南

添加自定义工具

from pydantic import BaseModel, Field
from tools.base import ToolResult, tool

class MyArgs(BaseModel):
    param: str = Field(description="参数说明")

@tool(MyArgs)
def my_tool(args: MyArgs) -> ToolResult:
    """工具描述(LLM 可见)"""
    return ToolResult(ok=True, data="结果")

然后在 tools/init.py 的 build_default_registry() 中注册:

registry.register(my_tool)

添加自定义技能

在 skills/ 目录下创建子目录,添加 SKILL.md:

---
name: my-skill
description: 技能简要说明
---
## 角色

你是一名...

## 流程

1. ...
2. ...

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages