> ## Documentation Index
> Fetch the complete documentation index at: https://simplellmfunc.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# 构建第一个 Agent

> 10 分钟内用 @llm_chat 构建一个工具调用 Agent

# 构建第一个 Agent

本指南构建一个简单的 Agent，它可以使用工具来回答问题。你将看到完整的循环：用户消息 → LLM 推理 → 工具调用 → 工具结果 → 最终响应。

## 定义工具

工具是用 `@tool` 装饰的异步函数：

```python theme={null}
from SimpleLLMFunc import tool


@tool
async def search_docs(query: str) -> str:
    """
    搜索文档中的相关信息。

    Args:
        query: 搜索查询。

    Returns:
        匹配的文档摘录。

    Best Practices:
        - 使用具体、聚焦的查询。
        - 优先使用精确术语而非模糊描述。
    """
    if "install" in query.lower():
        return "安装方式: pip install SimpleLLMFunc"
    return f"未找到结果: {query}"
```

要点：

* 工具必须是 `async def`
* 文档字符串成为 LLM 看到的工具描述
* `Best Practices` 部分会被注入到系统提示词中作为使用指南
* 返回类型注解告诉框架期望什么

## 定义 Agent

```python theme={null}
from SimpleLLMFunc import OpenAICompatible, llm_chat

models = OpenAICompatible.load_from_json_file("provider.json")
llm = models["openrouter"]["openai/gpt-4o"]


@llm_chat(llm_interface=llm, toolkit=[search_docs], stream=True)
async def assistant(message: str, history: list | None = None):
    """
    你是一个有帮助的文档助手。
    需要具体信息时使用搜索工具回答问题。
    简洁直接。
    """
    pass
```

要点：

* `@llm_chat` 创建多轮 Agent（相对于单次调用的 `@llm_function`）
* `toolkit=[...]` 让 Agent 可以使用工具
* `stream=True` 启用流式响应
* `history` 参数名是特殊的——框架通过它管理对话状态
* 文档字符串就是 Agent 的系统提示词

## 运行并消费事件

`@llm_chat` 返回 `ReactOutput` 的异步生成器——包含响应片段或生命周期事件：

```python theme={null}
import asyncio
from SimpleLLMFunc.hooks import is_response_yield, is_event_yield


async def main():
    history = []

    async for output in assistant("如何安装 SimpleLLMFunc?", history):
        if is_response_yield(output):
            print(output.response, end="")
            history = output.messages
        elif is_event_yield(output):
            event = output.event

    print()


asyncio.run(main())
```

## 底层发生了什么

```
1. 用户消息 "如何安装 SimpleLLMFunc?" → 编译为 LLM 请求
2. LLM 决定调用 search_docs(query="install SimpleLLMFunc")
3. 框架执行工具，获取结果
4. 结果通过内部运行时补丁应用到对话记录
5. 上下文重新编译，发回 LLM
6. LLM 使用工具结果生成最终响应
7. 响应以 ReactOutput 事件流式返回
```

这就是 **ReAct 循环**——推理、行动、观察、重复。框架处理所有这些。你只定义了一个函数签名和一个工具。

## 添加更多工具

```python theme={null}
@tool
async def calculate(expression: str) -> float:
    """
    计算数学表达式。

    Args:
        expression: Python 数学表达式（如 "2 ** 10"）。

    Returns:
        数值结果。

    Best Practices:
        - 使用 Python 语法进行数学运算。
        - 保持表达式简单可读。
    """
    return float(eval(expression))


@llm_chat(llm_interface=llm, toolkit=[search_docs, calculate], stream=True)
async def assistant(message: str, history: list | None = None):
    """你是一个可以搜索文档和做数学计算的助手。"""
    pass
```

## 下一步

<CardGroup cols={2}>
  <Card title="多轮对话" icon="comments" href="/zh/first-chat">
    管理更长的对话，包括历史和流式输出。
  </Card>

  <Card title="为什么这样设计？" icon="lightbulb" href="/zh/philosophy/llm-is-function">
    理解为什么 LLM 调用是函数，而不是链。
  </Card>
</CardGroup>
