diff --git a/docs/assets/agent-tooluse-stream.png b/docs/assets/agent-tooluse-stream.png new file mode 100644 index 000000000..bb0bb7446 Binary files /dev/null and b/docs/assets/agent-tooluse-stream.png differ diff --git a/docs/assets/agent-tooluse.png b/docs/assets/agent-tooluse.png new file mode 100644 index 000000000..f1d9eb0be Binary files /dev/null and b/docs/assets/agent-tooluse.png differ diff --git a/docs/en/Cookbook/function_call.md b/docs/en/Cookbook/function_call.md new file mode 100644 index 000000000..26bf392fc --- /dev/null +++ b/docs/en/Cookbook/function_call.md @@ -0,0 +1,398 @@ +# Build an Agent with LazyLLM + +LazyLLM supports the creation of agents that use language models as reasoning engines to determine which actions to take and how to interact with external tools. These agents can analyze user queries, decide when to use specific tools, and process the results to provide comprehensive responses. This tool-calling capability is fundamental to building intelligent agents that can interact with the real world. + +In this tutorial, we will build an agent that can interact with a search engine through tool-calling. You will learn how to: + +1. Create and register custom tools that your agent can use +2. Set up a language model as the agent's reasoning engine +3. Configure the agent to make intelligent decisions about tool usage +4. Enable the agent to maintain conversation history and context +5. Deploy the agent with a web interface for easy interaction +6. Implement streaming responses for real-time feedback + +Let's get started! + +## Setup + +### Installation + +First, install LazyLLM: + +```bash +pip install lazyllm +``` + +### Environment Variables + +You'll need to set up your API keys: + +```bash +export BOCHA_API_KEY=your_bocha_api_key +export LAZYLLM_DEEPSEEK_API_KEY=your_deepseek_api_key +``` +#### Applying for API Keys + +Before using this tutorial, you need to apply for the corresponding API keys: + +**Bocha API Key Application:** +1. Visit the [Bocha Open Platform](https://open.bochaai.com/overview) +2. Register and log in to your account +3. Create a new API key in the "API KEY Management" page +4. Copy the generated API key and set it in your environment variables + +**DeepSeek API Key Application:** +1. Visit the [DeepSeek Platform](https://platform.deepseek.com/) +2. Register and log in to your account +3. Create a new API key in the "API Keys" page +4. Copy the generated API key and set it in your environment variables + +### Dependencies + +Make sure you have the required dependencies: + +```bash +pip install httpx +``` + +## Define Tools + +First, let's define a search tool that the agent can use. In LazyLLM, we use the `@fc_register("tool")` decorator to register functions as tools: + +```python +import os +import httpx +import lazyllm +from lazyllm.tools import fc_register + +@fc_register("tool") +def bocha_search(query: str) -> str: + """ + Query information using Bocha Search API + + Args: + query (str): Search query, e.g.: "LazyLLM framework", "Latest AI developments" + + Returns: + str: Search result summary + """ + try: + # Get API key from environment variables + api_key = os.getenv('BOCHA_API_KEY') + if not api_key: + return "Error: BOCHA_API_KEY environment variable not set" + + # Send request to Bocha API + url = "https://api.bochaai.com/v1/web-search" + headers = { + "Authorization": f"Bearer {api_key}", + "Content-Type": "application/json" + } + data = { + "query": query, + "summary": True, + "freshness": "noLimit", + "count": 10 + } + + with httpx.Client(timeout=30) as client: + response = client.post(url, headers=headers, json=data) + if response.status_code == 200: + return response.text + return f"Search failed: {response.status_code}" + + except Exception as e: + return f"Search error: {str(e)}" +``` + +The `@fc_register("tool")` decorator automatically makes this function available to LazyLLM agents. The function docstring is important as it helps the agent understand when and how to use the tool. + +## Using Language Models + +LazyLLM provides easy access to various online language models through `OnlineChatModule`: + +```python +# Create LLM +llm = lazyllm.OnlineChatModule( + source="deepseek", + timeout=30 +) +``` + +You can also use other providers: + +```python +# OpenAI +llm = lazyllm.OnlineChatModule(source="openai") + +# Anthropic Claude +llm = lazyllm.OnlineChatModule(source="claude") + +# Local models +llm = lazyllm.OnlineChatModule(source="ollama") +``` + +## Create the Agent + +Now let's create a ReactAgent that can use our search tool: + +```python +def create_agent(): + """Create a configured search agent""" + # Create LLM + llm = lazyllm.OnlineChatModule( + source="deepseek", + timeout=30 + ) + + # Create ReactAgent + agent = lazyllm.tools.agent.ReactAgent( + llm=llm, + tools=["bocha_search"], # Reference our registered tool + max_retries=2, + return_trace=False, + stream=False + ) + + return agent +``` + +The `ReactAgent` follows the ReAct (Reasoning and Acting) paradigm, which allows the agent to: +- **Think** about what it needs to do +- **Act** by calling tools when needed +- **Observe** the results and continue reasoning + +## Run the Agent + +Let's test our agent with a simple query: + +```python +# Create agent +agent = create_agent() + +# Run query +result = agent("Search for the latest information about LazyLLM framework") +print(result) +``` + +The agent will: +1. Analyze the query +2. Decide to use the `bocha_search` tool +3. Call the tool with the appropriate search terms +4. Process the results and provide a comprehensive answer + +## Web Interface + +LazyLLM makes it easy to deploy your agent with a web interface: + +![Web Interface Demo](../assets/agent-tooluse.png) + +```python +def start_web_interface(): + """Start web interface""" + print("Starting Bocha Search Tool Web Interface...") + + try: + # Check API key + if not os.getenv('BOCHA_API_KEY'): + print("Warning: BOCHA_API_KEY environment variable not set") + print("Please set: export BOCHA_API_KEY=your_api_key") + return + + # Create agent + agent = create_agent() + + # Start web interface + web_module = lazyllm.WebModule( + agent, + port=8848, + title="Bocha Search Agent" + ) + + print(f"Web interface started: http://localhost:8848") + print("Press Ctrl+C to stop the service") + + web_module.start().wait() + + except KeyboardInterrupt: + print("\nStopping service...") + except Exception as e: + print(f"Start failed: {e}") +``` + +## Streaming Responses + +To enable streaming responses, modify the agent configuration: + +![Streaming Response Demo](../assets/agent-tooluse-stream.png) + +```python +agent = lazyllm.tools.agent.ReactAgent( + llm=llm, + tools=["bocha_search"], + max_retries=2, + return_trace=False, + stream=True # Enable streaming output +) +``` + +## Adding Memory + +LazyLLM agents can maintain conversation history through the web interface automatically, or you can implement custom memory functionality to enhance the agent's ability to maintain context across conversations. + +Memory features enable agents to: +- Remember previous conversations and user preferences +- Maintain context across multiple interactions +- Provide more personalized responses based on conversation history +- Build up knowledge about ongoing projects or topics + +*Custom memory implementation will be added in future updates.* + +## Complete Example + +Here's the complete working example: + +```python +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Search Tool Agent using LazyLLM Framework +Web interface supported with Bocha Search API +""" + +import os +import httpx +import lazyllm +from lazyllm.tools import fc_register + + +@fc_register("tool") +def bocha_search(query: str) -> str: + """ + Query information using Bocha Search API + + Args: + query (str): Search query, e.g.: "LazyLLM framework", "Latest AI developments" + + Returns: + str: Search result summary + """ + try: + # Get API key from environment variables + api_key = os.getenv('BOCHA_API_KEY') + if not api_key: + return "Error: BOCHA_API_KEY environment variable not set" + + # Send request to Bocha API + url = "https://api.bochaai.com/v1/web-search" + headers = { + "Authorization": f"Bearer {api_key}", + "Content-Type": "application/json" + } + data = { + "query": query, + "summary": True, + "freshness": "noLimit", + "count": 10 + } + + with httpx.Client(timeout=30) as client: + response = client.post(url, headers=headers, json=data) + if response.status_code == 200: + return response.text + return f"Search failed: {response.status_code}" + + except Exception as e: + return f"Search error: {str(e)}" + + +def create_agent(): + """Create a configured search agent""" + # Create LLM + llm = lazyllm.OnlineChatModule( + source="deepseek", + timeout=30) + + # Create ReactAgent + agent = lazyllm.tools.agent.ReactAgent( + llm=llm, + tools=["bocha_search"], + max_retries=2, + return_trace=False, + stream=False + ) + + return agent + + +def start_web_interface(): + """Start web interface""" + print("Starting Bocha Search Tool Web Interface...") + + try: + # Check API key + if not os.getenv('BOCHA_API_KEY'): + print("Warning: BOCHA_API_KEY environment variable not set") + print("Please set: export BOCHA_API_KEY=your_api_key") + return + + # Create agent + agent = create_agent() + + # Start web interface + web_module = lazyllm.WebModule( + agent, + port=8848, + title="Bocha Search Agent" + ) + + print(f"Web interface started: http://localhost:8848") + print("Press Ctrl+C to stop the service") + + web_module.start().wait() + + except KeyboardInterrupt: + print("\nStopping service...") + except Exception as e: + print(f"Start failed: {e}") + + +if __name__ == "__main__": + start_web_interface() +``` + +## Usage Examples + +### Command Line Usage + +```python +# Create and use agent +agent = create_agent() + +# Search for technical information +result = agent("Search for Python async programming best practices") +print(result) + +# Search for news +result = agent("Find latest breakthroughs in AI field") +print(result) +``` + +### Web Interface Usage + +1. Run the script: `python tool_agent.py` +2. Open your browser to `http://localhost:8848` +3. Start chatting with the agent through the web interface + +## Conclusion + +LazyLLM provides a powerful and easy-to-use framework for building intelligent agents. With just a few lines of code, you can: + +- Register custom tools +- Create sophisticated agents +- Deploy web interfaces +- Handle streaming and memory + +This framework makes it accessible to build production-ready AI agents that can interact with external APIs and provide intelligent responses to user queries. + +For more information about LazyLLM, check out the official documentation and examples. diff --git a/docs/mkdocs.template.yml b/docs/mkdocs.template.yml index 806aeee06..9f867cb0f 100644 --- a/docs/mkdocs.template.yml +++ b/docs/mkdocs.template.yml @@ -15,6 +15,7 @@ nav: - Great Writer: Cookbook/great_writer.md - RAG: Cookbook/rag.md - Streaming: Cookbook/streaming.md + - Function Call: Cookbook/function_call.md - Best Practice: - Flow: Best Practice/flow.md - Flowapp: Best Practice/flowapp.md diff --git a/docs/zh/Cookbook/function_call.md b/docs/zh/Cookbook/function_call.md new file mode 100644 index 000000000..6d48e066b --- /dev/null +++ b/docs/zh/Cookbook/function_call.md @@ -0,0 +1,395 @@ +# 使用 LazyLLM 构建智能代理 + +LazyLLM 支持创建使用语言模型作为推理引擎的智能代理,这些代理能够确定采取什么行动以及如何与外部工具交互。智能代理可以分析用户查询,决定何时使用特定工具,并处理结果以提供全面的响应。这种工具调用能力是构建能够与现实世界交互的智能代理的基础。 + +在本教程中,我们将构建一个可以通过工具调用与搜索引擎交互的智能代理。您将学习如何: + +1. 创建和注册代理可以使用的自定义工具 +2. 设置语言模型作为代理的推理引擎 +3. 配置代理以智能地决定工具使用 +4. 启用代理维护对话历史和上下文 +5. 部署带有 Web 界面的代理以便于交互 +6. 实现流式响应以获得实时反馈 + +让我们开始吧! + +## 环境准备 + +### 安装依赖 + +首先,安装 LazyLLM: + +```bash +pip install lazyllm +``` + +### 环境变量 + +您需要设置 API 密钥: + +```bash +export BOCHA_API_KEY=your_bocha_api_key +export LAZYLLM_DEEPSEEK_API_KEY=your_deepseek_api_key +``` + +**Bocha API 密钥申请:** +1. 访问 [Bocha Open 平台](https://open.bochaai.com/overview) +2. 注册并登录您的账户 +3. 在"API KEY管理"页面创建新的 API 密钥 +4. 复制生成的 API 密钥并设置到环境变量中 + +**DeepSeek API 密钥申请:** +1. 访问 [DeepSeek 平台](https://platform.deepseek.com/) +2. 注册并登录您的账户 +3. 在"API Keys"页面创建新的 API 密钥 +4. 复制生成的 API 密钥并设置到环境变量中 + +### 依赖包 + +确保您安装了所需的依赖: + +```bash +pip install httpx +``` + +## 定义工具 + +首先,让我们定义一个代理可以使用的搜索工具。在 LazyLLM 中,我们使用 `@fc_register("tool")` 装饰器来注册函数作为工具: + +```python +import os +import httpx +import lazyllm +from lazyllm.tools import fc_register + +@fc_register("tool") +def bocha_search(query: str) -> str: + """ + 使用 Bocha 搜索 API 查询信息 + + Args: + query (str): 搜索查询,例如:"LazyLLM 框架"、"最新 AI 发展" + + Returns: + str: 搜索结果摘要 + """ + try: + # 从环境变量获取 API 密钥 + api_key = os.getenv('BOCHA_API_KEY') + if not api_key: + return "错误:未设置 BOCHA_API_KEY 环境变量" + + # 向 Bocha API 发送请求 + url = "https://api.bochaai.com/v1/web-search" + headers = { + "Authorization": f"Bearer {api_key}", + "Content-Type": "application/json" + } + data = { + "query": query, + "summary": True, + "freshness": "noLimit", + "count": 10 + } + + with httpx.Client(timeout=30) as client: + response = client.post(url, headers=headers, json=data) + if response.status_code == 200: + return response.text + return f"搜索失败:{response.status_code}" + + except Exception as e: + return f"搜索错误:{str(e)}" +``` + +`@fc_register("tool")` 装饰器会自动使此函数对 LazyLLM 代理可用。函数的文档字符串很重要,因为它帮助代理理解何时以及如何使用该工具。 + +## 使用语言模型 + +LazyLLM 通过 `OnlineChatModule` 提供对各种在线语言模型的便捷访问: + +```python +# 创建 LLM +llm = lazyllm.OnlineChatModule( + source="deepseek", + timeout=30 +) +``` + +您也可以使用其他提供商: + +```python +# OpenAI +llm = lazyllm.OnlineChatModule(source="openai") + +# Anthropic Claude +llm = lazyllm.OnlineChatModule(source="claude") + +# 本地模型 +llm = lazyllm.OnlineChatModule(source="ollama") +``` + +## 创建代理 + +现在让我们创建一个可以使用搜索工具的 ReactAgent: + +```python +def create_agent(): + """创建配置好的搜索代理""" + # 创建 LLM + llm = lazyllm.OnlineChatModule( + source="deepseek", + timeout=30 + ) + + # 创建 ReactAgent + agent = lazyllm.tools.agent.ReactAgent( + llm=llm, + tools=["bocha_search"], # 引用我们注册的工具 + max_retries=2, + return_trace=False, + stream=False + ) + + return agent +``` + +`ReactAgent` 遵循 ReAct(推理和行动)范式,它允许代理: +- **思考**需要做什么 +- **行动**通过在需要时调用工具 +- **观察**结果并继续推理 + +## 运行代理 + +让我们用一个简单的查询来测试我们的代理: + +```python +# 创建代理 +agent = create_agent() + +# 运行查询 +result = agent("搜索关于 LazyLLM 框架的最新信息") +print(result) +``` + +代理将: +1. 分析查询 +2. 决定使用 `bocha_search` 工具 +3. 使用适当的搜索词调用工具 +4. 处理结果并提供全面的答案 + +## Web 界面 + +LazyLLM 让部署带有 Web 界面的代理变得简单: + +![Web 界面演示](../assets/agent-tooluse.png) + +```python +def start_web_interface(): + """启动 Web 界面""" + print("启动博查搜索工具 Web 界面...") + + try: + # 检查 API 密钥 + if not os.getenv('BOCHA_API_KEY'): + print("警告:未设置 BOCHA_API_KEY 环境变量") + print("请设置:export BOCHA_API_KEY=your_api_key") + return + + # 创建代理 + agent = create_agent() + + # 启动 Web 界面 + web_module = lazyllm.WebModule( + agent, + port=8848, + title="博查搜索代理" + ) + + print(f"Web 界面已启动:http://localhost:8848") + print("按 Ctrl+C 停止服务") + + web_module.start().wait() + + except KeyboardInterrupt: + print("\n停止服务...") + except Exception as e: + print(f"启动失败:{e}") +``` + +## 流式响应 + +要启用流式响应,请修改代理配置: + +![流式响应演示](../assets/agent-tooluse-stream.png) + +```python +agent = lazyllm.tools.agent.ReactAgent( + llm=llm, + tools=["bocha_search"], + max_retries=2, + return_trace=False, + stream=True # 启用流式输出 +) +``` + +## 添加记忆功能 + +LazyLLM 代理可以通过 Web 界面自动维护对话历史,或者您可以实现自定义记忆功能来增强代理在对话中维护上下文的能力。 + +记忆功能使代理能够: +- 记住之前的对话和用户偏好 +- 在多次交互中维护上下文 +- 基于对话历史提供更个性化的响应 +- 积累关于正在进行的项目或主题的知识 + +*自定义记忆实现将在未来更新中添加。* + +## 完整示例 + +这是完整的工作示例: + +```python +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +使用 LazyLLM 框架的搜索工具代理 +支持博查搜索 API 的 Web 界面 +""" + +import os +import httpx +import lazyllm +from lazyllm.tools import fc_register + + +@fc_register("tool") +def bocha_search(query: str) -> str: + """ + 使用 Bocha 搜索 API 查询信息 + + Args: + query (str): 搜索查询,例如:"LazyLLM 框架"、"最新 AI 发展" + + Returns: + str: 搜索结果摘要 + """ + try: + # 从环境变量获取 API 密钥 + api_key = os.getenv('BOCHA_API_KEY') + if not api_key: + return "错误:未设置 BOCHA_API_KEY 环境变量" + + # 向 Bocha API 发送请求 + url = "https://api.bochaai.com/v1/web-search" + headers = { + "Authorization": f"Bearer {api_key}", + "Content-Type": "application/json" + } + data = { + "query": query, + "summary": True, + "freshness": "noLimit", + "count": 10 + } + + with httpx.Client(timeout=30) as client: + response = client.post(url, headers=headers, json=data) + if response.status_code == 200: + return response.text + return f"搜索失败:{response.status_code}" + + except Exception as e: + return f"搜索错误:{str(e)}" + + +def create_agent(): + """创建配置好的搜索代理""" + # 创建 LLM + llm = lazyllm.OnlineChatModule( + source="deepseek", + timeout=30) + + # 创建 ReactAgent + agent = lazyllm.tools.agent.ReactAgent( + llm=llm, + tools=["bocha_search"], + max_retries=2, + return_trace=False, + stream=False + ) + + return agent + + +def start_web_interface(): + """启动 Web 界面""" + print("启动博查搜索工具 Web 界面...") + + try: + # 检查 API 密钥 + if not os.getenv('BOCHA_API_KEY'): + print("警告:未设置 BOCHA_API_KEY 环境变量") + print("请设置:export BOCHA_API_KEY=your_api_key") + return + + # 创建代理 + agent = create_agent() + + # 启动 Web 界面 + web_module = lazyllm.WebModule( + agent, + port=8848, + title="博查搜索代理" + ) + + print(f"Web 界面已启动:http://localhost:8848") + print("按 Ctrl+C 停止服务") + + web_module.start().wait() + + except KeyboardInterrupt: + print("\n停止服务...") + except Exception as e: + print(f"启动失败:{e}") + + +if __name__ == "__main__": + start_web_interface() +``` + +## 使用示例 + +### 命令行使用 + +```python +# 创建和使用代理 +agent = create_agent() + +# 搜索技术信息 +result = agent("搜索 Python 异步编程最佳实践") +print(result) + +# 搜索新闻 +result = agent("查找 AI 领域的最新突破") +print(result) +``` + +### Web 界面使用 + +1. 运行脚本:`python tool_agent.py` +2. 在浏览器中打开 `http://localhost:8848` +3. 通过 Web 界面与代理开始对话 + +## 总结 + +LazyLLM 提供了一个强大且易于使用的框架来构建智能代理。只需几行代码,您就可以: + +- 注册自定义工具 +- 创建复杂的代理 +- 部署 Web 界面 +- 处理流式和记忆功能 + +这个框架使构建可以与外部 API 交互并为用户查询提供智能响应的生产就绪 AI 代理变得容易。 + +有关 LazyLLM 的更多信息,请查看官方文档和示例。