Skip to content

tonnie17/wxagent

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Jan 3, 2025
b8bcf2c · Jan 3, 2025

History

22 Commits
Nov 27, 2024
Dec 5, 2024
Dec 27, 2024
Dec 27, 2024
Dec 3, 2024
Jan 3, 2025
Jan 3, 2025
Nov 27, 2024
Nov 27, 2024
Nov 27, 2024
Nov 27, 2024
Jan 3, 2025
Jan 3, 2025
Dec 26, 2024
Dec 26, 2024
Nov 27, 2024

Repository files navigation

wxagent

让公众号瞬间变身为智能助手,支持特性:

  • 接近零成本部署,只需要一个域名即可绑定到公众号
  • 支持对话记忆,超时自动回复,以及对话结果回溯
  • 支持多种工具调用,包括:获取天气,关键字搜索,网页总结,Home Assistant 设备控制
  • 支持构建本地 RAG 知识库进行读取和检索

一键部署到 Vercel:

Deploy with Vercel

  1. 参考配置填写环境变量,完成部署
  2. 拿到Vercel生成的默认域名进行访问,没问题的话会输出OK
  3. 绑定域名到服务器地址,然后配置公众号服务器地址为:{domain}/wechat/receive/

示例

点击查看对话效果

基础对话:

basic_dialogue

获取天气:

get_weather

文章总结:

webpage_summary

信息搜索:

google_search

知识库检索:

knowledge_base

配置

所有配置通过环境变量指定,支持通过.env文件自动加载:

  • WECHAT_TOKEN:公众号服务器配置的令牌(Token)
  • WECHAT_ALLOW_LIST:允许交互的微信账号(openid),用逗号分隔,默认无限制
  • WECHAT_MEM_TTL:公众号单轮对话记忆保存时间,默认为5m
  • WECHAT_MEM_MSG_SIZE:公众号单轮对话记忆消息记录上限(包括工具消息),默认为6
  • WECHAT_TIMEOUT:公众号单轮对话超时时间(公众号限制回复时间不能超过5秒),默认为4s
  • WECHAT_APP_ID:公众号 AppID,安全模式下需要指定
  • WECHAT_ENCODING_AES_KEY:公众号消息加解密密钥 (EncodingAESKey),安全模式下需要指定
  • LLM_PROVIDER:LLM 提供者,支持:openai,默认为openai
  • OPENAI_API_KEY:OpenAI(兼容接口)API KEY
  • OPENAI_BASE_URL:OpenAI(兼容接口)Base URL
  • SERVER_ADDR:服务器模式的启动地址,默认为0.0.0.0:8082
  • USE_RAG:是否开启 RAG 从知识库检索查询
  • EMBEDDING_PROVIDER:文本嵌入模型提供者,支持:openai,默认为 openai
  • KNOWLEDGE_BASE_PATH:本地知识库目录路径,目前支持文件格式:txt,默认为 ./knowledge_base

Agent 配置

  • AGENT_TOOLS:Agent 可以使用的 Tools,用逗号分隔,需要配置相关的环境变量,支持:
    • google_search:Google 搜索
    • get_weather:天气查询
    • webpage_summary:网页文本总结
    • get_devices:获取 Home Assistant 设备列表
    • execute_device:执行 Home Assistant 设备动作
  • AGENT_TIMEOUT:Agent 对话超时时间,默认为30s
  • MAX_TOOL_ITER:Agent 调用工具最大迭代次数,默认为3
  • TOOL_TIMEOUT:工具调用超时时间,默认为10s
  • LLM_MODEL:LLM 模型名称,默认为gpt-3.5-turbo
  • LLM_MAX_TOKENS:最大输出 Token 数量,默认为500
  • LLM_TEMPERATURE:Temperature 参数,默认为0.2
  • LLM_TOP_P:Top P 参数,默认为0.9
  • SYSTEM_PROMPT:设置 Agent 对话的 System Prompt
  • EMBEDDING_MODEL:文本嵌入模型,支持:openai,默认为 openai

工具配置

Google 搜索(google_search)

  • GOOGLE_SEARCH_ENGINE:Google 搜索引擎
  • GOOGLE_SEARCH_API_KEY:Google 搜索 API Key

天气查询(get_weather)

  • OPENWEATHERMAP_API_KEY:OpenWeatherMap API Key

Home Assistant(get_devices,execute_device)

  • HA_BASE_URL:Home Assistant 服务器地址
  • HA_BEARER_TOKEN:Home Assistant API 验证 Bearer Token

扩展使用

与Agent交互
package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/tonnie17/wxagent/pkg/agent"
	"github.com/tonnie17/wxagent/pkg/config"
	"github.com/tonnie17/wxagent/pkg/llm"
	"github.com/tonnie17/wxagent/pkg/memory"
	"github.com/tonnie17/wxagent/pkg/tool"
)

func main() {
	tools := []tool.Tool{
		tool.NewWebPageSummary(),
	}

	agent := agent.NewAgent(&config.AgentConfig{
		AgentTools:   []string{"webpage_summary"},
		AgentTimeout: 30 * time.Second,
		MaxToolIter:  3,
		ToolTimeout:  10 * time.Second,
		Model:        "qwen-plus",
		MaxTokens:    500,
		Temperature:  0.2,
		TopP:         0.9,
	}, llm.NewOpenAI(), memory.NewBuffer(6), tools, nil)

	output, err := agent.Chat(context.Background(), "总结一下:https://golangnote.com/golang/golang-stringsbuilder-vs-bytesbuffer")
	if err != nil {
		log.Fatalf("chat failed: %v", err)
	}

	fmt.Println(output)
}
自定义工具

要定义一个工具,需要实现Tool定义的接口:

type Tool interface {
	Name() string
	Description() string
	Schema() map[string]interface{}
	Execute(context.Context, string) (string, error)
}

方法含义:

  • Name():工具名称
  • Description():工具描述,描述尽量清晰以便模型了解选择工具进行调用
  • Schema() map[string]interface{}:提供工具的参数描述以及定义
  • Execute(context.Context, string) (string, error):工具的执行逻辑,接收模型输入,返回执行结果
接入新模型

要接入新的模型,需要实现LLM定义的接口:

type LLM interface {
    Chat(context.Context, model string, messages []*ChatMessage, options ...ChatOption) (*ChatMessage, error)
}

本地开发

创建配置文件.env,将项目配置写入到文件:

echo "{CONFIG_KEY}={CONFIG_VALUE}" > .env 

拉取依赖:

go mod tidy

启动服务器:

go run cmd/server/main.go

启动交互式命令行:

go run cmd/cli/main.go

Streamlit 调用:

with httpx.stream("POST", server_addr, headers=headers, data=json.dumps({
    "messages": st.session_state.messages
}), timeout=30) as r:
    for line in r.iter_lines():
        if not line.strip():
            continue
        data = json.loads(line)
        # ...

构建

本地构建

编译二进制文件:

go build -o server /cmd/server

运行:

./server

Docker 构建

创建镜像:

docker build -t wxagent .

运行容器:

docker run -it --rm -p 8082:8082 --env-file .env wxagent

About

支持工具调用的公众号聊天机器人

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published