# SHB Agent 🤖
[](https://pypi.org/project/shbagents/)
[](https://opensource.org/licenses/MIT)
[](https://badge.fury.io/py/shbagents)
一个通用的多模型智能体框架,支持灵活的工具调用和多种 LLM 模型。
## ✨ 特性
- 🔧 **灵活的工具系统**: 支持 `@tool` 装饰器和传统 Tool 对象
- 🤖 **多模型支持**: 支持 OpenAI、Anthropic 等多种 LLM 模型
- 📝 **通用工具调用**: 基于文本解析,不依赖特定模型的 function calling
- 📊 **丰富的日志**: 显示智能体思考过程和执行步骤
- 🔄 **智能检测**: 自动检测最终答案并结束任务
- 🎯 **易于使用**: 简洁的 API 设计
## 🚀 快速开始
### 安装
```bash
pip install shbagents
```
### 基本使用
```python
from shbagents import Agent, OpenAIModel, tool
# 使用 @tool 装饰器定义工具
@tool
def add_numbers(a: float, b: float) -> float:
"""两数相加"""
return a + b
@tool
def compare_numbers(a: float, b: float) -> str:
"""比较两个数的大小"""
if a > b:
return f"{a} 比 {b} 大"
elif a < b:
return f"{a} 比 {b} 小"
else:
return f"{a} 和 {b} 相等"
# 创建模型
model = OpenAIModel(model_id="gpt-5")
# 创建智能体,直接传递装饰过的函数
agent = Agent(
model=model,
tools=[add_numbers, compare_numbers]
)
# 运行任务
result = agent.run("计算 3.5 + 2.7,然后比较结果与 6 的大小")
print(result)
```
### 高级使用
#### 混合工具定义
```python
from shb_agent import Agent, Tool, tool
# 方式1: @tool 装饰器
@tool
def calculate(expression: str) -> float:
"""计算数学表达式"""
return eval(expression) # 注意:实际使用中应该用更安全的计算方法
# 方式2: 传统 Tool 对象
def format_number(number: float) -> str:
"""格式化数字"""
return f"{number:.2f}"
format_tool = Tool(
name="format_number",
description="格式化数字为两位小数",
func=format_number,
arguments=[("number", "float")],
outputs="str"
)
# 混合使用两种方式
agent = Agent(
model=model,
tools=[
calculate, # @tool 装饰的函数
format_tool # Tool 对象
]
)
```
#### 自定义提示模板
```python
from shb_agent import PromptTemplates
custom_templates = {
"system_prompt": """你是一个专业的数学助手。
使用以下工具来帮助解决数学问题:{{ tools }}
调用工具格式:
思考: [你的推理过程]
调用工具: tool_name(参数1=值1, 参数2=值2)
""",
# ... 其他模板
}
agent = Agent(
model=model,
tools=[calculate],
prompt_templates=custom_templates
)
```
## 📖 详细文档
### 工具定义
#### 使用 @tool 装饰器(推荐)
```python
@tool
def search_web(query: str, max_results: int = 5) -> list:
"""搜索网页"""
# 实际的搜索逻辑
return ["结果1", "结果2", "结果3"]
```
#### 使用 Tool 类
```python
def search_web(query: str, max_results: int = 5) -> list:
"""搜索网页"""
return ["结果1", "结果2", "结果3"]
search_tool = Tool(
name="search_web",
description="搜索网页",
func=search_web,
arguments=[
("query", "str"),
("max_results", "int")
],
outputs="list"
)
```
### 模型支持
目前支持的模型:
- **OpenAI**: `OpenAIModel(model_id="gpt-5")`
- 更多模型支持即将推出...
### 日志系统
智能体提供详细的执行日志:
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 步骤 1 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🤖 智能体正在思考和决策...
💭 智能体思考: 用户需要我计算两个数字的和
🔧 调用工具: add_numbers
参数: a=3.5, b=2.7
📤 工具结果: 6.2
```
## 🛠️ 开发
### 运行示例
```bash
make run-example
```
## 📋 要求
- Python 3.10+
- openai>=1.0.0
- rich>=13.0.0
- 其他依赖见 `requirements.txt`
## 📄 许可证
本项目采用 MIT 许可证。
## 🔗 链接
- [PyPI 包](https://pypi.org/project/shbagents/)
## 📈 路线图
- [ ] 支持更多 LLM 模型 (Anthropic, Gemini, etc.)
- [ ] 添加流式输出支持
- [ ] 改进工具调用性能
- [ ] 添加更多内置工具
- [ ] Web UI 界面
Raw data
{
"_id": null,
"home_page": null,
"name": "shbagents",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "llm, agent, ai, artificial-intelligence, openai, tool-calling, multi-model, chatbot",
"author": "huangbaocheng",
"author_email": "huangbaocheng@example.com",
"download_url": "https://files.pythonhosted.org/packages/d9/69/6924bae2e05a3f030c0126fe1cca9df4e9eee80c4f250bbc820e55f4ea9e/shbagents-0.1.3.tar.gz",
"platform": null,
"description": "# SHB Agent \ud83e\udd16\n\n[](https://pypi.org/project/shbagents/)\n[](https://opensource.org/licenses/MIT)\n[](https://badge.fury.io/py/shbagents)\n\n\u4e00\u4e2a\u901a\u7528\u7684\u591a\u6a21\u578b\u667a\u80fd\u4f53\u6846\u67b6\uff0c\u652f\u6301\u7075\u6d3b\u7684\u5de5\u5177\u8c03\u7528\u548c\u591a\u79cd LLM \u6a21\u578b\u3002\n\n## \u2728 \u7279\u6027\n\n- \ud83d\udd27 **\u7075\u6d3b\u7684\u5de5\u5177\u7cfb\u7edf**: \u652f\u6301 `@tool` \u88c5\u9970\u5668\u548c\u4f20\u7edf Tool \u5bf9\u8c61\n- \ud83e\udd16 **\u591a\u6a21\u578b\u652f\u6301**: \u652f\u6301 OpenAI\u3001Anthropic \u7b49\u591a\u79cd LLM \u6a21\u578b\n- \ud83d\udcdd **\u901a\u7528\u5de5\u5177\u8c03\u7528**: \u57fa\u4e8e\u6587\u672c\u89e3\u6790\uff0c\u4e0d\u4f9d\u8d56\u7279\u5b9a\u6a21\u578b\u7684 function calling\n- \ud83d\udcca **\u4e30\u5bcc\u7684\u65e5\u5fd7**: \u663e\u793a\u667a\u80fd\u4f53\u601d\u8003\u8fc7\u7a0b\u548c\u6267\u884c\u6b65\u9aa4\n- \ud83d\udd04 **\u667a\u80fd\u68c0\u6d4b**: \u81ea\u52a8\u68c0\u6d4b\u6700\u7ec8\u7b54\u6848\u5e76\u7ed3\u675f\u4efb\u52a1\n- \ud83c\udfaf **\u6613\u4e8e\u4f7f\u7528**: \u7b80\u6d01\u7684 API \u8bbe\u8ba1\n\n## \ud83d\ude80 \u5feb\u901f\u5f00\u59cb\n\n### \u5b89\u88c5\n\n```bash\npip install shbagents\n```\n\n### \u57fa\u672c\u4f7f\u7528\n\n```python\nfrom shbagents import Agent, OpenAIModel, tool\n\n# \u4f7f\u7528 @tool \u88c5\u9970\u5668\u5b9a\u4e49\u5de5\u5177\n@tool\ndef add_numbers(a: float, b: float) -> float:\n \"\"\"\u4e24\u6570\u76f8\u52a0\"\"\"\n return a + b\n\n@tool\ndef compare_numbers(a: float, b: float) -> str:\n \"\"\"\u6bd4\u8f83\u4e24\u4e2a\u6570\u7684\u5927\u5c0f\"\"\"\n if a > b:\n return f\"{a} \u6bd4 {b} \u5927\"\n elif a < b:\n return f\"{a} \u6bd4 {b} \u5c0f\"\n else:\n return f\"{a} \u548c {b} \u76f8\u7b49\"\n\n# \u521b\u5efa\u6a21\u578b\nmodel = OpenAIModel(model_id=\"gpt-5\")\n\n# \u521b\u5efa\u667a\u80fd\u4f53\uff0c\u76f4\u63a5\u4f20\u9012\u88c5\u9970\u8fc7\u7684\u51fd\u6570\nagent = Agent(\n model=model,\n tools=[add_numbers, compare_numbers]\n)\n\n# \u8fd0\u884c\u4efb\u52a1\nresult = agent.run(\"\u8ba1\u7b97 3.5 + 2.7\uff0c\u7136\u540e\u6bd4\u8f83\u7ed3\u679c\u4e0e 6 \u7684\u5927\u5c0f\")\nprint(result)\n```\n\n### \u9ad8\u7ea7\u4f7f\u7528\n\n#### \u6df7\u5408\u5de5\u5177\u5b9a\u4e49\n\n```python\nfrom shb_agent import Agent, Tool, tool\n\n# \u65b9\u5f0f1: @tool \u88c5\u9970\u5668\n@tool\ndef calculate(expression: str) -> float:\n \"\"\"\u8ba1\u7b97\u6570\u5b66\u8868\u8fbe\u5f0f\"\"\"\n return eval(expression) # \u6ce8\u610f\uff1a\u5b9e\u9645\u4f7f\u7528\u4e2d\u5e94\u8be5\u7528\u66f4\u5b89\u5168\u7684\u8ba1\u7b97\u65b9\u6cd5\n\n# \u65b9\u5f0f2: \u4f20\u7edf Tool \u5bf9\u8c61\ndef format_number(number: float) -> str:\n \"\"\"\u683c\u5f0f\u5316\u6570\u5b57\"\"\"\n return f\"{number:.2f}\"\n\nformat_tool = Tool(\n name=\"format_number\",\n description=\"\u683c\u5f0f\u5316\u6570\u5b57\u4e3a\u4e24\u4f4d\u5c0f\u6570\",\n func=format_number,\n arguments=[(\"number\", \"float\")],\n outputs=\"str\"\n)\n\n# \u6df7\u5408\u4f7f\u7528\u4e24\u79cd\u65b9\u5f0f\nagent = Agent(\n model=model,\n tools=[\n calculate, # @tool \u88c5\u9970\u7684\u51fd\u6570\n format_tool # Tool \u5bf9\u8c61\n ]\n)\n```\n\n#### \u81ea\u5b9a\u4e49\u63d0\u793a\u6a21\u677f\n\n```python\nfrom shb_agent import PromptTemplates\n\ncustom_templates = {\n \"system_prompt\": \"\"\"\u4f60\u662f\u4e00\u4e2a\u4e13\u4e1a\u7684\u6570\u5b66\u52a9\u624b\u3002\n \u4f7f\u7528\u4ee5\u4e0b\u5de5\u5177\u6765\u5e2e\u52a9\u89e3\u51b3\u6570\u5b66\u95ee\u9898\uff1a{{ tools }}\n \n \u8c03\u7528\u5de5\u5177\u683c\u5f0f\uff1a\n \u601d\u8003: [\u4f60\u7684\u63a8\u7406\u8fc7\u7a0b]\n \u8c03\u7528\u5de5\u5177: tool_name(\u53c2\u65701=\u503c1, \u53c2\u65702=\u503c2)\n \"\"\",\n # ... \u5176\u4ed6\u6a21\u677f\n}\n\nagent = Agent(\n model=model,\n tools=[calculate],\n prompt_templates=custom_templates\n)\n```\n\n## \ud83d\udcd6 \u8be6\u7ec6\u6587\u6863\n\n### \u5de5\u5177\u5b9a\u4e49\n\n#### \u4f7f\u7528 @tool \u88c5\u9970\u5668\uff08\u63a8\u8350\uff09\n\n```python\n@tool\ndef search_web(query: str, max_results: int = 5) -> list:\n \"\"\"\u641c\u7d22\u7f51\u9875\"\"\"\n # \u5b9e\u9645\u7684\u641c\u7d22\u903b\u8f91\n return [\"\u7ed3\u679c1\", \"\u7ed3\u679c2\", \"\u7ed3\u679c3\"]\n```\n\n#### \u4f7f\u7528 Tool \u7c7b\n\n```python\ndef search_web(query: str, max_results: int = 5) -> list:\n \"\"\"\u641c\u7d22\u7f51\u9875\"\"\"\n return [\"\u7ed3\u679c1\", \"\u7ed3\u679c2\", \"\u7ed3\u679c3\"]\n\nsearch_tool = Tool(\n name=\"search_web\",\n description=\"\u641c\u7d22\u7f51\u9875\",\n func=search_web,\n arguments=[\n (\"query\", \"str\"),\n (\"max_results\", \"int\")\n ],\n outputs=\"list\"\n)\n```\n\n### \u6a21\u578b\u652f\u6301\n\n\u76ee\u524d\u652f\u6301\u7684\u6a21\u578b\uff1a\n\n- **OpenAI**: `OpenAIModel(model_id=\"gpt-5\")`\n- \u66f4\u591a\u6a21\u578b\u652f\u6301\u5373\u5c06\u63a8\u51fa...\n\n### \u65e5\u5fd7\u7cfb\u7edf\n\n\u667a\u80fd\u4f53\u63d0\u4f9b\u8be6\u7ec6\u7684\u6267\u884c\u65e5\u5fd7\uff1a\n\n```\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501 \u6b65\u9aa4 1 \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\ud83e\udd16 \u667a\u80fd\u4f53\u6b63\u5728\u601d\u8003\u548c\u51b3\u7b56...\n\ud83d\udcad \u667a\u80fd\u4f53\u601d\u8003: \u7528\u6237\u9700\u8981\u6211\u8ba1\u7b97\u4e24\u4e2a\u6570\u5b57\u7684\u548c\n\ud83d\udd27 \u8c03\u7528\u5de5\u5177: add_numbers\n \u53c2\u6570: a=3.5, b=2.7\n\ud83d\udce4 \u5de5\u5177\u7ed3\u679c: 6.2\n```\n\n## \ud83d\udee0\ufe0f \u5f00\u53d1\n\n### \u8fd0\u884c\u793a\u4f8b\n\n```bash\nmake run-example\n```\n\n## \ud83d\udccb \u8981\u6c42\n\n- Python 3.10+\n- openai>=1.0.0\n- rich>=13.0.0\n- \u5176\u4ed6\u4f9d\u8d56\u89c1 `requirements.txt`\n\n## \ud83d\udcc4 \u8bb8\u53ef\u8bc1\n\n\u672c\u9879\u76ee\u91c7\u7528 MIT \u8bb8\u53ef\u8bc1\u3002\n\n## \ud83d\udd17 \u94fe\u63a5\n\n- [PyPI \u5305](https://pypi.org/project/shbagents/)\n\n## \ud83d\udcc8 \u8def\u7ebf\u56fe\n\n- [ ] \u652f\u6301\u66f4\u591a LLM \u6a21\u578b (Anthropic, Gemini, etc.)\n- [ ] \u6dfb\u52a0\u6d41\u5f0f\u8f93\u51fa\u652f\u6301\n- [ ] \u6539\u8fdb\u5de5\u5177\u8c03\u7528\u6027\u80fd\n- [ ] \u6dfb\u52a0\u66f4\u591a\u5185\u7f6e\u5de5\u5177\n- [ ] Web UI \u754c\u9762\n",
"bugtrack_url": null,
"license": null,
"summary": "\u901a\u7528\u7684\u591a\u6a21\u578b\u667a\u80fd\u4f53\u6846\u67b6\uff0c\u652f\u6301\u5de5\u5177\u8c03\u7528\u548c\u591a\u79cdLLM\u6a21\u578b",
"version": "0.1.3",
"project_urls": null,
"split_keywords": [
"llm",
" agent",
" ai",
" artificial-intelligence",
" openai",
" tool-calling",
" multi-model",
" chatbot"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "4496aa2ef659bdf9e522ca23cafece3eb98cc47da6f1e560b31c832814e3f7a8",
"md5": "75e3f0485d8b132d4bf230b30ceabe0f",
"sha256": "9fed78dc38738c4c96c9f0bb0fe137f8452aae5f005bc30207b43a8672e0e1b4"
},
"downloads": -1,
"filename": "shbagents-0.1.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "75e3f0485d8b132d4bf230b30ceabe0f",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 26635,
"upload_time": "2025-08-24T08:39:34",
"upload_time_iso_8601": "2025-08-24T08:39:34.633602Z",
"url": "https://files.pythonhosted.org/packages/44/96/aa2ef659bdf9e522ca23cafece3eb98cc47da6f1e560b31c832814e3f7a8/shbagents-0.1.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "d9696924bae2e05a3f030c0126fe1cca9df4e9eee80c4f250bbc820e55f4ea9e",
"md5": "42001dbe5599cc59d9bea19e48bbd680",
"sha256": "38529ecb7a9678c641b10d2710fdddf87df2525a33042a36810899dba7fa0906"
},
"downloads": -1,
"filename": "shbagents-0.1.3.tar.gz",
"has_sig": false,
"md5_digest": "42001dbe5599cc59d9bea19e48bbd680",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 25531,
"upload_time": "2025-08-24T08:39:36",
"upload_time_iso_8601": "2025-08-24T08:39:36.044544Z",
"url": "https://files.pythonhosted.org/packages/d9/69/6924bae2e05a3f030c0126fe1cca9df4e9eee80c4f250bbc820e55f4ea9e/shbagents-0.1.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-24 08:39:36",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "shbagents"
}