Skip to content

MetaGLM/langchain-glm

Repository files navigation

🔗 LangChain-GLM

项目介绍

本项目通过langchain的基础组件,实现了完整的支持智能体和相关任务架构。底层采用智谱AI的最新的 GLM-4 All Tools, 通过智谱AI的API接口, 能够自主理解用户的意图,规划复杂的指令,并能够调用一个或多个工具(例如网络浏览器、Python解释器和文本到图像模型)以完成复杂的任务。

all_tools.png

图|GLM-4 All Tools 和定制 GLMs(智能体)的整体流程。

项目结构

包路径 说明
agent_toolkits 平台工具AdapterAllTool适配器, 是一个用于为各种工具提供统一接口的平台适配器工具,目的是在不同平台上实现无缝集成和执行。该工具通过适配特定的平台参数,确保兼容性和一致的输出。
agents 定义AgentExecutor的输入、输出、智能体会话、工具参数、工具执行策略的封装
callbacks 抽象AgentExecutor过程中的一些交互事件,通过事件展示信息
chat_models zhipuai sdk的封装层,提供langchain的BaseChatModel集成,格式化输入输出为消息体
embeddings zhipuai sdk的封装层,提供langchain的Embeddings集成
utils 一些会话工具

快速使用

Python版本支持

正式的 Python (3.8, 3.9, 3.10, 3.11, 3.12)

使用前请设置环境变量ZHIPUAI_API_KEY,值为智谱AI的API Key。

工具使用

  • Set environment variables
import getpass
import os

os.environ["ZHIPUAI_API_KEY"] = getpass.getpass()
from langchain_glm import ChatZhipuAI
llm = ChatZhipuAI(model="glm-4")
  • 定义一些示例工具:
from langchain_core.tools import tool

@tool
def multiply(first_int: int, second_int: int) -> int:
    """Multiply two integers together."""
    return first_int * second_int

@tool
def add(first_int: int, second_int: int) -> int:
    "Add two integers."
    return first_int + second_int

@tool
def exponentiate(base: int, exponent: int) -> int:
    "Exponentiate the base to the exponent power."
    return base**exponent
  • 构建chain 绑定工具到语言模型并调用:
from operator import itemgetter
from typing import Dict, List, Union

from langchain_core.messages import AIMessage
from langchain_core.runnables import (
    Runnable,
    RunnableLambda,
    RunnableMap,
    RunnablePassthrough,
)

tools = [multiply, exponentiate, add]
llm_with_tools = llm.bind_tools(tools)
tool_map = {tool.name: tool for tool in tools}


def call_tools(msg: AIMessage) -> Runnable:
    """Simple sequential tool calling helper."""
    tool_map = {tool.name: tool for tool in tools}
    tool_calls = msg.tool_calls.copy()
    for tool_call in tool_calls:
        tool_call["output"] = tool_map[tool_call["name"]].invoke(tool_call["args"])
    return tool_calls


chain = llm_with_tools | call_tools
  • 调用chain
chain.invoke(
    "What's 23 times 7, and what's five times 18 and add a million plus a billion and cube thirty-seven"
)

代码解析使用示例

  • 创建一个代理执行器 我们的glm-4-alltools的模型提供了平台工具,通过ZhipuAIAllToolsRunnable,你可以非常方便的设置了一个执行器来运行多个工具。

code_interpreter:使用sandbox指定代码沙盒环境, 默认 = auto,即自动调用沙盒环境执行代码。 设置 sandbox = none,不启用沙盒环境。

web_browser:使用web_browser指定浏览器工具。 drawing_tool:使用drawing_tool指定绘图工具。

from langchain_glm.agents.zhipuai_all_tools import ZhipuAIAllToolsRunnable
agent_executor = ZhipuAIAllToolsRunnable.create_agent_executor(
    model_name="glm-4-alltools",
    tools=[
        {"type": "code_interpreter", "code_interpreter": {"sandbox": "none"}},
        {"type": "web_browser"},
        {"type": "drawing_tool"},
        multiply, exponentiate, add
    ],
)
  • 执行agent_executor并打印结果 这部分使用代理来运行一个Shell命令,并在结果出现时打印出来。它检查结果的类型并打印相关信息。 这个invoke返回一个异步迭代器,可以用来处理代理的输出。 你可以多次调用invoke方法,每次调用都会返回一个新的迭代器。 ZhipuAIAllToolsRunnable会自动处理状态保存和恢复,一些状态信息会被保存实例中 你可以通过callback属性获取intermediate_steps的状态信息。
from langchain_glm.agents.zhipuai_all_tools.base import (
    AllToolsAction, 
    AllToolsActionToolEnd,
    AllToolsActionToolStart,
    AllToolsFinish, 
    AllToolsLLMStatus
)
from langchain_glm.callbacks.agent_callback_handler import AgentStatus


chat_iterator = agent_executor.invoke(
    chat_input="看下本地文件有哪些,告诉我你用的是什么文件,查看当前目录"
)
async for item in chat_iterator:
    if isinstance(item, AllToolsAction):
        print("AllToolsAction:" + str(item.to_json()))
    elif isinstance(item, AllToolsFinish):
        print("AllToolsFinish:" + str(item.to_json()))
    elif isinstance(item, AllToolsActionToolStart):
        print("AllToolsActionToolStart:" + str(item.to_json()))
    elif isinstance(item, AllToolsActionToolEnd):
        print("AllToolsActionToolEnd:" + str(item.to_json()))
    elif isinstance(item, AllToolsLLMStatus):
        if item.status == AgentStatus.llm_end:
            print("llm_end:" + item.text)

集成demo

我们提供了一个集成的demo,可以直接运行,查看效果。

  • 安装依赖
fastapi = "~0.109.2"
sse_starlette = "~1.8.2" 
uvicorn = ">=0.27.0.post1"
# webui
streamlit = "1.34.0"
streamlit-option-menu = "0.3.12"
streamlit-antd-components = "0.3.1"
streamlit-chatbox = "1.1.12.post4"
streamlit-modal = "0.1.0"
streamlit-aggrid = "1.0.5"
streamlit-extras = "0.4.2"
python tests/assistant/server/server.py
python tests/assistant/start_chat.py

展示

demo.mp4