# GeneralAgent: From LLM to Agent
<p align="center">
<a href="README.md"><img src="https://img.shields.io/badge/文档-中文版-blue.svg" alt="CN doc"></a>
<a href="README_EN.md"><img src="https://img.shields.io/badge/document-English-blue.svg" alt="EN doc"></a>
</p>
GeneralAgent是一个Python原生的Agent框架,旨在将大型语言模型 与 Python 无缝集成。
**主要特性**
* 工具调用:GeneralAgent 不依赖大模型的 function call,通过python代码解释器来调用工具
* 序列化:GeneralAgent 支持序列化,包括记忆和python执行状态,随用随启
* 快速配置角色、函数和知识库,创建Agent
* 执行稳定的复杂业务流程,协调多个Agent完成任务
* 使用 `agent.run` 函数执行命令并产生结构化输出,超越简单的文本响应
* 使用 `agent.user_input` 函数与用户进行动态交互
* 自我调用(探索):GeneralAgent通过自我调用和堆栈记忆,最小化大模型的调用次数,来高效处理复杂任务。更多详情请见我们的 [论文](./docs/paper/General_Agent__Self_Call_And_Stack_Memory.pdf)
## 安装
```bash
pip install GeneralAgent
```
## 配置
### 方式一:使用环境变量(推荐)
1. 安装依赖:
```bash
pip install python-dotenv
```
2. 参考 [.env.example](./.env.example) 文件,创建并配置 .env 文件:
```bash
OPENAI_API_KEY=your_openai_api_key
# OPENAI_API_BASE=your_openai_base_url
```
3. 在代码中加载环境变量:
```python
from dotenv import load_dotenv
from GeneralAgent import Agent
load_dotenv()
agent = Agent('You are a helpful agent.')
```
### 方式二:直接在代码中配置
```python
from GeneralAgent import Agent
agent = Agent('You are a helpful agent.', api_key='sk-xxx')
```
## 使用
### 快速开始
```python
from GeneralAgent import Agent
agent = Agent('你是一个AI助手')
while True:
query = input()
agent.user_input(query)
print('-'*50)
```
### 函数调用
```python
# 函数调用
from GeneralAgent import Agent
# 函数: 获取天气信息
def get_weather(city: str) -> str:
"""
get weather information
@city: str, city name
@return: str, weather information
"""
return f"{city} weather: sunny"
agent = Agent('你是一个天气小助手', functions=[get_weather])
agent.user_input('成都天气怎么样?')
```
### 知识库
```python
# 知识库
from GeneralAgent import Agent
knowledge_files = ['../docs/paper/General_Agent__Self_Call_And_Stack_Memory.pdf']
agent = Agent('你是AI助手,用中文回复。', workspace='9_knowledge_files', knowledge_files=knowledge_files)
agent.user_input('Self call 是什么意思?')
```
知识库默认使用 GeneralAgent.skills 中 embedding_texts 函数来对文本进行 embedding (默认是OpenAI的text-embedding-3-small模型)
你可以重写 embedding_texts 函数,使用其他厂商 或者 本地的 embedding 方法,具体如下:
```python
def new_embedding_texts(texts) -> [[float]]:
"""
对文本数组进行embedding
"""
# 你的embedding方法
return result
from GeneralAgent import skills
skills.embedding_texts = new_embedding_texts
```
### 序列化
```python
# 序列化
from GeneralAgent import Agent
# agent序列化位置,运行过程中会自动保存LLM的messages和python解析器的状态
workspace='./5_serialize'
role = 'You are a helpful agent.'
agent = Agent(workspace=workspace)
agent.user_input('My name is Shadow.')
agent = None
agent = Agent(role, workspace=workspace)
agent.user_input('What is my name?')
# Output: Your name is Shadow. How can I help you today, Shadow?
# agent: 清除记忆 + python序列化状态
agent.clear()
agent.user_input('What is my name?')
# Output: I'm sorry, but I don't have access to your personal information, including your name. How can I assist you today?
import shutil
shutil.rmtree(workspace)
```
### 写小说
```python
# 写小说
from GeneralAgent import Agent
from GeneralAgent import skills
# 步骤0: 定义Agent
agent = Agent('你是一个小说家')
# 步骤1: 从用户处获取小说的名称和主题
# topic = skills.input('请输入小说的名称和主题: ')
topic = '小白兔吃糖不刷牙的故事'
# 步骤2: 小说的概要
summary = agent.run(f'小说的名称和主题是: {topic},扩展和完善一下小说概要。要求具备文艺性、教育性、娱乐性。')
# 步骤3: 小说的章节名称和概要列表
chapters = agent.run('输出小说的章节名称和每个章节的概要,返回列表 [(chapter_title, chapter_summary), ....]', return_type=list)
# 步骤4: 生成小说每一章节的详细内容
contents = []
for index, (chapter_title, chapter_summary) in enumerate(chapters):
content = agent.run(f'对于章节: {chapter_title}\n{chapter_summary}. \n输出章节的详细内容,注意只返回内容,不要标题。')
content = '\n'.join([x.strip() for x in content.split('\n')])
contents.append(content)
# 步骤5: 将小说格式化写入文件
with open('novel.md', 'w') as f:
for index in range(len(chapters)):
f.write(f'### {chapters[index][0]}\n')
f.write(f'{contents[index]}\n\n')
# 步骤6(可选): 将markdown文件转换为pdf文件
# 步骤7: 输出小说文件给用户
skills.output('你的小说已经生成[novel.md](novel.md)\n')
```
### 多Agent
```python
# 多Agent配合完成任务
from GeneralAgent import Agent
story_writer = Agent('你是一个故事创作家,根据大纲要求或者故事梗概,返回一个更加详细的故事内容。')
humor_enhancer = Agent('你是一个润色作家,将一个故事进行诙谐润色,增加幽默元素。直接输出润色后的故事')
# 禁用Python运行
story_writer.disable_python_run = True
humor_enhancer.disable_python_run = True
# topic = skills.input('请输入小说的大纲要求或者故事梗概: ')
topic = '写个小白兔吃糖不刷牙的故事,有教育意义。'
initial_story = story_writer.run(topic)
enhanced_story = humor_enhancer.run(initial_story)
print(enhanced_story)
```
### 多模态输入
user_input 的 input 参数,和 run 的 command 参数,支持字符串或者数组。
数组时支持多模态,格式为最简模式: ['text_content', {'image': 'path/to/image'}, ...]
```python
# 支持多模态: 图片输入
from GeneralAgent import Agent
agent = Agent('You are a helpful assistant.')
agent.user_input(['what is in the image?', {'image': '../docs/images/self_call.png'}])
```
### 大模型切换
#### OpenAI SDK
得益于GeneralAgent框架不依赖大模型厂商的 function call 能力实现了函数调用,可以无缝切换不同的大模型实现相同的能力。
GeneralAgent框架使用OpenAI Python SDK 来支持其他大模型。
```python
from GeneralAgent import Agent
agent = Agent('You are a helpful agent.', model='deepseek-chat', token_limit=32000, api_key='sk-xxx', base_url='https://api.deepseek.com/v1')
agent.user_input('介绍一下成都')
```
详情见: [examples/8_multi_model.py](./examples/8_multi_model.py)
#### Azure OpenAI
```python
from GeneralAgent import Agent
# api_key = os.getenv("OPENAI_API_KEY")
# base_url = os.getenv("OPENAI_API_BASE")
api_key = '8ef0b4df45e444079cd5xxx' # Azure API Key or use OPENAI_API_KEY environment variable
base_url = 'https://xxxx.openai.azure.com/' # Azure API Base URL or use OPENAI_API_BASE environment variable
model = 'azure_cpgpt4' # azure_ with model name, e.g. azure_cpgpt4
# azure api_version is default to '2024-05-01-preview'. You can set by environment variable AZURE_API_VERSION
agent = Agent('You are a helpful assistant', api_key=api_key, base_url=base_url, model=model)
while True:
query = input('Please input your query:')
agent.user_input(query)
print('-'*50)
```
#### OneAPI
如果其他大模型不支持OpenAI SDK,可以通过 https://github.com/songquanpeng/one-api 来支持。
#### 自定义大模型
或者重写 GeneralAgent.skills 中 llm_inference 函数来使用其他大模型。
```python
from GeneralAgent import skills
def new_llm_inference(messages, model, stream=False, temperature=None, api_key=None, base_url=None):
"""
使用大模型进行推理
"""
pass
skills.llm_inference = new_llm_inference
```
### 禁用Python运行
默认 GeneralAgent 自动运行 LLM 输出的python代码。
某些场景下,如果不希望自动运行,设置 `disable_python_run` 为 `True` 即可。
```python
from GeneralAgent import Agent
agent = Agent('你是一个python专家,辅助用户解决python问题。')
agent.disable_python_run = True
agent.user_input('用python实现一个读取文件的函数')
```
### 隐藏python运行
在正式的业务场景中,不希望用户看到python代码的运行,而只是看到最终结果,可以设置 `hide_python_code` 为 `True`。
```python
from GeneralAgent import Agent
agent = Agent('You are a helpful assistant.', hide_python_code=True)
agent.user_input('caculate 0.999 ** 1000')
```
### AI搜索
```python
# AI搜索
# 运行前置条件:
# 1. 请先配置环境变量 SERPER_API_KEY (https://serper.dev/ 的API KEY);
# 2. 安装 selenium 库: pip install selenium
from GeneralAgent import Agent
from GeneralAgent import skills
google_results = []
# 步骤1: 第一次google搜索
question = input('请输入问题,进行 AI 搜索: ')
# question = '周鸿祎卖车'
content1 = skills.google_search(question)
google_results.append(content1)
# 步骤2: 第二次google搜索: 根据第一次搜索结构,获取继续搜索的问题
agent = Agent('你是一个AI搜索助手。')
querys = agent.run(f'用户问题: \n{question}\n\n搜索引擎结果: \n{content1}\n\n。请问可以帮助用户,需要继续搜索的关键短语有哪些(最多3个,且和问题本身不太重合)?返回关键短语列表变量([query1, query2])', return_type=list)
print(querys)
for query in querys:
content = skills.google_search(query)
google_results.append(content)
# 步骤3: 提取重点网页内容
agent.clear()
web_contents = []
google_result = '\n\n'.join(google_results)
urls = agent.run(f'用户问题: \n{question}\n\n搜索引擎结果: \n{google_result}\n\n。哪些网页对于用户问题比较有帮助?请返回最重要的不超过5个的网页url列表变量([url1, url2, ...])', return_type=list)
for url in urls:
content = skills.web_get_text(url, wait_time=2)
web_contents.append(content)
# 步骤4: 输出结果
agent.clear()
web_content = '\n\n'.join(web_contents)
agent.run(f'用户问题: \n{question}\n\n搜索引擎结果: \n{google_result}\n\n部分网页内容: \n{web_content}\n\n。请根据用户问题,搜索引擎结果,网页内容,给出用户详细的回答,要求按一定目录结构来输出,并且使用markdown格式。')
```
### 更多
更多例子请见 [examples](./examples)
## API
### 基础使用
**Agent.\__init__(self, role: str, workspace: str = None, functions: List[Callable] = [], knowledge_files: List[str] = None)**
初始化一个Agent实例。
- role (str): Agent的角色。
- workspace (str, 可选): Agent的工作空间。默认值为None(不序列化)。如果指定了目录,Agent会自动保存状态并在下次初始化时重新加载。
- functions (List[Callable], 可选): Agent可以调用的函数列表。
- knowledge_files (List[str], 可选): Agent知识库文件路径列表。
- messages (List[str], 可选): Agent的历史消息列表, 消息字段中必须包含 'role', 'content' 字段。
**Agent.run(self, command: Union[str, List[Union[str, Dict[str, str]]]], return_type: str = str, display: bool = False)**
执行命令并返回指定类型的结果。
- command (Union[str, List[Union[str, Dict[str, str]]]]): 要执行的命令。例如:'describe chengdu' 或 ['what is in image?', {'image': 'path/to/image'}]。
- return_type (str, 可选): 结果的返回类型。默认值为str。
- display (bool, 可选): 是否显示LLM生成的中间内容。默认值为False。
**Agent.user_input(self, input: Union[str, List[Union[str, Dict[str, str]]]])**
响应用户输入,并始终显示LLM生成的中间内容。
- input (Union[str, List[Union[str, Dict[str, str]]]]): 用户输入。
**Agent.temporary_context(self, input: Union[str, List[Union[str, Dict[str, str]]]])**
对话产生的数据,不进入 agent memory 中。
- input (Union[str, List[Union[str, Dict[str, str]]]]): 用户输入。
```python
from GeneralAgent import Agent
agent = Agent('You are a helpful assistant.')
with agent.temporary_context():
agent.user_input('My name is Henry.')
agent.user_input("What's my name?")
```
**Agent.clear(self)**
清除Agent的状态。
### 高级使用
[ ] # TODO
## 论文
[General Agent:Self Call and Stack Memory](./docs/paper/General_Agent__Self_Call_And_Stack_Memory.pdf)
## 加入我们👏🏻
使用微信扫描下方二维码,加入微信群聊,或参与贡献。
<p align="center">
<img src="./docs/images/wechat.jpg" alt="wechat" width=400/>
</p>
Raw data
{
"_id": null,
"home_page": "https://github.com/CosmosShadow/GeneralAgent",
"name": "GeneralAgent",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8.1",
"maintainer_email": null,
"keywords": null,
"author": "Chen Li",
"author_email": "lichenarthurdata@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/93/4a/7da38b094bad51228b223a017d7f44dbc82a1b00a1bdab83688dce60dc78/generalagent-0.3.29.tar.gz",
"platform": null,
"description": "# GeneralAgent: From LLM to Agent\n\n<p align=\"center\">\n<a href=\"README.md\"><img src=\"https://img.shields.io/badge/\u6587\u6863-\u4e2d\u6587\u7248-blue.svg\" alt=\"CN doc\"></a>\n<a href=\"README_EN.md\"><img src=\"https://img.shields.io/badge/document-English-blue.svg\" alt=\"EN doc\"></a>\n</p>\n\nGeneralAgent\u662f\u4e00\u4e2aPython\u539f\u751f\u7684Agent\u6846\u67b6\uff0c\u65e8\u5728\u5c06\u5927\u578b\u8bed\u8a00\u6a21\u578b \u4e0e Python \u65e0\u7f1d\u96c6\u6210\u3002\n\n\n**\u4e3b\u8981\u7279\u6027**\n\n* \u5de5\u5177\u8c03\u7528\uff1aGeneralAgent \u4e0d\u4f9d\u8d56\u5927\u6a21\u578b\u7684 function call\uff0c\u901a\u8fc7python\u4ee3\u7801\u89e3\u91ca\u5668\u6765\u8c03\u7528\u5de5\u5177\n\n* \u5e8f\u5217\u5316\uff1aGeneralAgent \u652f\u6301\u5e8f\u5217\u5316\uff0c\u5305\u62ec\u8bb0\u5fc6\u548cpython\u6267\u884c\u72b6\u6001\uff0c\u968f\u7528\u968f\u542f\n\n* \u5feb\u901f\u914d\u7f6e\u89d2\u8272\u3001\u51fd\u6570\u548c\u77e5\u8bc6\u5e93\uff0c\u521b\u5efaAgent\n\n* \u6267\u884c\u7a33\u5b9a\u7684\u590d\u6742\u4e1a\u52a1\u6d41\u7a0b\uff0c\u534f\u8c03\u591a\u4e2aAgent\u5b8c\u6210\u4efb\u52a1\n\n* \u4f7f\u7528 `agent.run` \u51fd\u6570\u6267\u884c\u547d\u4ee4\u5e76\u4ea7\u751f\u7ed3\u6784\u5316\u8f93\u51fa\uff0c\u8d85\u8d8a\u7b80\u5355\u7684\u6587\u672c\u54cd\u5e94\n\n* \u4f7f\u7528 `agent.user_input` \u51fd\u6570\u4e0e\u7528\u6237\u8fdb\u884c\u52a8\u6001\u4ea4\u4e92\n\n* \u81ea\u6211\u8c03\u7528(\u63a2\u7d22)\uff1aGeneralAgent\u901a\u8fc7\u81ea\u6211\u8c03\u7528\u548c\u5806\u6808\u8bb0\u5fc6\uff0c\u6700\u5c0f\u5316\u5927\u6a21\u578b\u7684\u8c03\u7528\u6b21\u6570\uff0c\u6765\u9ad8\u6548\u5904\u7406\u590d\u6742\u4efb\u52a1\u3002\u66f4\u591a\u8be6\u60c5\u8bf7\u89c1\u6211\u4eec\u7684 [\u8bba\u6587](./docs/paper/General_Agent__Self_Call_And_Stack_Memory.pdf)\n\n\n\n## \u5b89\u88c5\n\n```bash\npip install GeneralAgent\n```\n\n\n\n## \u914d\u7f6e\n### \u65b9\u5f0f\u4e00\uff1a\u4f7f\u7528\u73af\u5883\u53d8\u91cf\uff08\u63a8\u8350\uff09\n1. \u5b89\u88c5\u4f9d\u8d56\uff1a\n```bash\npip install python-dotenv\n```\n\n2. \u53c2\u8003 [.env.example](./.env.example) \u6587\u4ef6\uff0c\u521b\u5efa\u5e76\u914d\u7f6e .env \u6587\u4ef6\uff1a\n```bash\nOPENAI_API_KEY=your_openai_api_key\n# OPENAI_API_BASE=your_openai_base_url\n```\n\n3. \u5728\u4ee3\u7801\u4e2d\u52a0\u8f7d\u73af\u5883\u53d8\u91cf\uff1a\n```python\nfrom dotenv import load_dotenv\nfrom GeneralAgent import Agent\n\nload_dotenv()\nagent = Agent('You are a helpful agent.')\n```\n\n### \u65b9\u5f0f\u4e8c\uff1a\u76f4\u63a5\u5728\u4ee3\u7801\u4e2d\u914d\u7f6e\n\n```python\nfrom GeneralAgent import Agent\nagent = Agent('You are a helpful agent.', api_key='sk-xxx')\n```\n\n\n\n## \u4f7f\u7528\n\n### \u5feb\u901f\u5f00\u59cb\n\n```python\nfrom GeneralAgent import Agent\n\nagent = Agent('\u4f60\u662f\u4e00\u4e2aAI\u52a9\u624b')\nwhile True:\n query = input()\n agent.user_input(query)\n print('-'*50)\n```\n\n\n\n### \u51fd\u6570\u8c03\u7528\n\n```python\n# \u51fd\u6570\u8c03\u7528\nfrom GeneralAgent import Agent\n\n# \u51fd\u6570: \u83b7\u53d6\u5929\u6c14\u4fe1\u606f\ndef get_weather(city: str) -> str:\n \"\"\"\n get weather information\n @city: str, city name\n @return: str, weather information\n \"\"\"\n return f\"{city} weather: sunny\"\n\n\nagent = Agent('\u4f60\u662f\u4e00\u4e2a\u5929\u6c14\u5c0f\u52a9\u624b', functions=[get_weather])\nagent.user_input('\u6210\u90fd\u5929\u6c14\u600e\u4e48\u6837\uff1f')\n```\n\n\n\n### \u77e5\u8bc6\u5e93\n\n```python\n# \u77e5\u8bc6\u5e93\nfrom GeneralAgent import Agent\n\nknowledge_files = ['../docs/paper/General_Agent__Self_Call_And_Stack_Memory.pdf']\nagent = Agent('\u4f60\u662fAI\u52a9\u624b\uff0c\u7528\u4e2d\u6587\u56de\u590d\u3002', workspace='9_knowledge_files', knowledge_files=knowledge_files)\nagent.user_input('Self call \u662f\u4ec0\u4e48\u610f\u601d\uff1f')\n```\n\n\u77e5\u8bc6\u5e93\u9ed8\u8ba4\u4f7f\u7528 GeneralAgent.skills \u4e2d embedding_texts \u51fd\u6570\u6765\u5bf9\u6587\u672c\u8fdb\u884c embedding (\u9ed8\u8ba4\u662fOpenAI\u7684text-embedding-3-small\u6a21\u578b)\n\n\u4f60\u53ef\u4ee5\u91cd\u5199 embedding_texts \u51fd\u6570\uff0c\u4f7f\u7528\u5176\u4ed6\u5382\u5546 \u6216\u8005 \u672c\u5730\u7684 embedding \u65b9\u6cd5\uff0c\u5177\u4f53\u5982\u4e0b:\n\n```python\ndef new_embedding_texts(texts) -> [[float]]:\n \"\"\"\n \u5bf9\u6587\u672c\u6570\u7ec4\u8fdb\u884cembedding\n \"\"\"\n # \u4f60\u7684embedding\u65b9\u6cd5\n return result\nfrom GeneralAgent import skills\nskills.embedding_texts = new_embedding_texts\n```\n\n\n\n### \u5e8f\u5217\u5316\n\n```python\n# \u5e8f\u5217\u5316\nfrom GeneralAgent import Agent\n\n# agent\u5e8f\u5217\u5316\u4f4d\u7f6e\uff0c\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u4f1a\u81ea\u52a8\u4fdd\u5b58LLM\u7684messages\u548cpython\u89e3\u6790\u5668\u7684\u72b6\u6001\nworkspace='./5_serialize'\n\nrole = 'You are a helpful agent.'\nagent = Agent(workspace=workspace)\nagent.user_input('My name is Shadow.')\n\nagent = None\nagent = Agent(role, workspace=workspace)\nagent.user_input('What is my name?')\n# Output: Your name is Shadow. How can I help you today, Shadow?\n\n# agent: \u6e05\u9664\u8bb0\u5fc6 + python\u5e8f\u5217\u5316\u72b6\u6001\nagent.clear()\n\nagent.user_input('What is my name?')\n# Output: I'm sorry, but I don't have access to your personal information, including your name. How can I assist you today?\n\nimport shutil\nshutil.rmtree(workspace)\n```\n\n\n\n### \u5199\u5c0f\u8bf4\n\n```python\n# \u5199\u5c0f\u8bf4\nfrom GeneralAgent import Agent\nfrom GeneralAgent import skills\n\n# \u6b65\u9aa40: \u5b9a\u4e49Agent\nagent = Agent('\u4f60\u662f\u4e00\u4e2a\u5c0f\u8bf4\u5bb6')\n\n# \u6b65\u9aa41: \u4ece\u7528\u6237\u5904\u83b7\u53d6\u5c0f\u8bf4\u7684\u540d\u79f0\u548c\u4e3b\u9898\n# topic = skills.input('\u8bf7\u8f93\u5165\u5c0f\u8bf4\u7684\u540d\u79f0\u548c\u4e3b\u9898: ')\ntopic = '\u5c0f\u767d\u5154\u5403\u7cd6\u4e0d\u5237\u7259\u7684\u6545\u4e8b'\n\n# \u6b65\u9aa42: \u5c0f\u8bf4\u7684\u6982\u8981\nsummary = agent.run(f'\u5c0f\u8bf4\u7684\u540d\u79f0\u548c\u4e3b\u9898\u662f: {topic}\uff0c\u6269\u5c55\u548c\u5b8c\u5584\u4e00\u4e0b\u5c0f\u8bf4\u6982\u8981\u3002\u8981\u6c42\u5177\u5907\u6587\u827a\u6027\u3001\u6559\u80b2\u6027\u3001\u5a31\u4e50\u6027\u3002')\n\n# \u6b65\u9aa43: \u5c0f\u8bf4\u7684\u7ae0\u8282\u540d\u79f0\u548c\u6982\u8981\u5217\u8868\nchapters = agent.run('\u8f93\u51fa\u5c0f\u8bf4\u7684\u7ae0\u8282\u540d\u79f0\u548c\u6bcf\u4e2a\u7ae0\u8282\u7684\u6982\u8981\uff0c\u8fd4\u56de\u5217\u8868 [(chapter_title, chapter_summary), ....]', return_type=list)\n\n# \u6b65\u9aa44: \u751f\u6210\u5c0f\u8bf4\u6bcf\u4e00\u7ae0\u8282\u7684\u8be6\u7ec6\u5185\u5bb9\ncontents = []\nfor index, (chapter_title, chapter_summary) in enumerate(chapters):\n content = agent.run(f'\u5bf9\u4e8e\u7ae0\u8282: {chapter_title}\\n{chapter_summary}. \\n\u8f93\u51fa\u7ae0\u8282\u7684\u8be6\u7ec6\u5185\u5bb9\uff0c\u6ce8\u610f\u53ea\u8fd4\u56de\u5185\u5bb9\uff0c\u4e0d\u8981\u6807\u9898\u3002')\n content = '\\n'.join([x.strip() for x in content.split('\\n')])\n contents.append(content)\n\n# \u6b65\u9aa45: \u5c06\u5c0f\u8bf4\u683c\u5f0f\u5316\u5199\u5165\u6587\u4ef6\nwith open('novel.md', 'w') as f:\n for index in range(len(chapters)):\n f.write(f'### {chapters[index][0]}\\n')\n f.write(f'{contents[index]}\\n\\n')\n\n# \u6b65\u9aa46(\u53ef\u9009): \u5c06markdown\u6587\u4ef6\u8f6c\u6362\u4e3apdf\u6587\u4ef6\n\n# \u6b65\u9aa47: \u8f93\u51fa\u5c0f\u8bf4\u6587\u4ef6\u7ed9\u7528\u6237\nskills.output('\u4f60\u7684\u5c0f\u8bf4\u5df2\u7ecf\u751f\u6210[novel.md](novel.md)\\n')\n```\n\n\n\n### \u591aAgent\n\n```python\n# \u591aAgent\u914d\u5408\u5b8c\u6210\u4efb\u52a1\nfrom GeneralAgent import Agent\nstory_writer = Agent('\u4f60\u662f\u4e00\u4e2a\u6545\u4e8b\u521b\u4f5c\u5bb6\uff0c\u6839\u636e\u5927\u7eb2\u8981\u6c42\u6216\u8005\u6545\u4e8b\u6897\u6982\uff0c\u8fd4\u56de\u4e00\u4e2a\u66f4\u52a0\u8be6\u7ec6\u7684\u6545\u4e8b\u5185\u5bb9\u3002')\nhumor_enhancer = Agent('\u4f60\u662f\u4e00\u4e2a\u6da6\u8272\u4f5c\u5bb6\uff0c\u5c06\u4e00\u4e2a\u6545\u4e8b\u8fdb\u884c\u8bd9\u8c10\u6da6\u8272\uff0c\u589e\u52a0\u5e7d\u9ed8\u5143\u7d20\u3002\u76f4\u63a5\u8f93\u51fa\u6da6\u8272\u540e\u7684\u6545\u4e8b')\n\n# \u7981\u7528Python\u8fd0\u884c\nstory_writer.disable_python_run = True\nhumor_enhancer.disable_python_run = True\n\n# topic = skills.input('\u8bf7\u8f93\u5165\u5c0f\u8bf4\u7684\u5927\u7eb2\u8981\u6c42\u6216\u8005\u6545\u4e8b\u6897\u6982: ')\ntopic = '\u5199\u4e2a\u5c0f\u767d\u5154\u5403\u7cd6\u4e0d\u5237\u7259\u7684\u6545\u4e8b\uff0c\u6709\u6559\u80b2\u610f\u4e49\u3002'\ninitial_story = story_writer.run(topic)\nenhanced_story = humor_enhancer.run(initial_story)\nprint(enhanced_story)\n```\n\n\n\n\n### \u591a\u6a21\u6001\u8f93\u5165\n\nuser_input \u7684 input \u53c2\u6570\uff0c\u548c run \u7684 command \u53c2\u6570\uff0c\u652f\u6301\u5b57\u7b26\u4e32\u6216\u8005\u6570\u7ec4\u3002\n\n\u6570\u7ec4\u65f6\u652f\u6301\u591a\u6a21\u6001\uff0c\u683c\u5f0f\u4e3a\u6700\u7b80\u6a21\u5f0f: ['text_content', {'image': 'path/to/image'}, ...]\n\n```python\n# \u652f\u6301\u591a\u6a21\u6001: \u56fe\u7247\u8f93\u5165\nfrom GeneralAgent import Agent\n\nagent = Agent('You are a helpful assistant.')\nagent.user_input(['what is in the image?', {'image': '../docs/images/self_call.png'}])\n```\n\n\n\n### \u5927\u6a21\u578b\u5207\u6362\n\n#### OpenAI SDK\n\n\u5f97\u76ca\u4e8eGeneralAgent\u6846\u67b6\u4e0d\u4f9d\u8d56\u5927\u6a21\u578b\u5382\u5546\u7684 function call \u80fd\u529b\u5b9e\u73b0\u4e86\u51fd\u6570\u8c03\u7528\uff0c\u53ef\u4ee5\u65e0\u7f1d\u5207\u6362\u4e0d\u540c\u7684\u5927\u6a21\u578b\u5b9e\u73b0\u76f8\u540c\u7684\u80fd\u529b\u3002\n\nGeneralAgent\u6846\u67b6\u4f7f\u7528OpenAI Python SDK \u6765\u652f\u6301\u5176\u4ed6\u5927\u6a21\u578b\u3002\n\n```python\nfrom GeneralAgent import Agent\n\nagent = Agent('You are a helpful agent.', model='deepseek-chat', token_limit=32000, api_key='sk-xxx', base_url='https://api.deepseek.com/v1')\nagent.user_input('\u4ecb\u7ecd\u4e00\u4e0b\u6210\u90fd')\n```\n\n\u8be6\u60c5\u89c1: [examples/8_multi_model.py](./examples/8_multi_model.py)\n\n\n#### Azure OpenAI \n\n```python\nfrom GeneralAgent import Agent\n\n# api_key = os.getenv(\"OPENAI_API_KEY\")\n# base_url = os.getenv(\"OPENAI_API_BASE\")\napi_key = '8ef0b4df45e444079cd5xxx' # Azure API Key or use OPENAI_API_KEY environment variable\nbase_url = 'https://xxxx.openai.azure.com/' # Azure API Base URL or use OPENAI_API_BASE environment variable\nmodel = 'azure_cpgpt4' # azure_ with model name, e.g. azure_cpgpt4\n# azure api_version is default to '2024-05-01-preview'. You can set by environment variable AZURE_API_VERSION\n\nagent = Agent('You are a helpful assistant', api_key=api_key, base_url=base_url, model=model)\nwhile True:\n query = input('Please input your query:')\n agent.user_input(query)\n print('-'*50)\n```\n\n\n#### OneAPI\n\n\u5982\u679c\u5176\u4ed6\u5927\u6a21\u578b\u4e0d\u652f\u6301OpenAI SDK\uff0c\u53ef\u4ee5\u901a\u8fc7 https://github.com/songquanpeng/one-api \u6765\u652f\u6301\u3002\n\n\n#### \u81ea\u5b9a\u4e49\u5927\u6a21\u578b\n\n\u6216\u8005\u91cd\u5199 GeneralAgent.skills \u4e2d llm_inference \u51fd\u6570\u6765\u4f7f\u7528\u5176\u4ed6\u5927\u6a21\u578b\u3002\n\n```python\nfrom GeneralAgent import skills\ndef new_llm_inference(messages, model, stream=False, temperature=None, api_key=None, base_url=None):\n \"\"\"\n \u4f7f\u7528\u5927\u6a21\u578b\u8fdb\u884c\u63a8\u7406\n \"\"\"\n pass\nskills.llm_inference = new_llm_inference\n```\n\n\n\n### \u7981\u7528Python\u8fd0\u884c\n\n\u9ed8\u8ba4 GeneralAgent \u81ea\u52a8\u8fd0\u884c LLM \u8f93\u51fa\u7684python\u4ee3\u7801\u3002\n\n\u67d0\u4e9b\u573a\u666f\u4e0b\uff0c\u5982\u679c\u4e0d\u5e0c\u671b\u81ea\u52a8\u8fd0\u884c\uff0c\u8bbe\u7f6e `disable_python_run` \u4e3a `True` \u5373\u53ef\u3002\n\n```python\nfrom GeneralAgent import Agent\n\nagent = Agent('\u4f60\u662f\u4e00\u4e2apython\u4e13\u5bb6\uff0c\u8f85\u52a9\u7528\u6237\u89e3\u51b3python\u95ee\u9898\u3002')\nagent.disable_python_run = True\nagent.user_input('\u7528python\u5b9e\u73b0\u4e00\u4e2a\u8bfb\u53d6\u6587\u4ef6\u7684\u51fd\u6570')\n```\n\n### \u9690\u85cfpython\u8fd0\u884c\n\n\u5728\u6b63\u5f0f\u7684\u4e1a\u52a1\u573a\u666f\u4e2d\uff0c\u4e0d\u5e0c\u671b\u7528\u6237\u770b\u5230python\u4ee3\u7801\u7684\u8fd0\u884c\uff0c\u800c\u53ea\u662f\u770b\u5230\u6700\u7ec8\u7ed3\u679c\uff0c\u53ef\u4ee5\u8bbe\u7f6e `hide_python_code` \u4e3a `True`\u3002\n\n```python\nfrom GeneralAgent import Agent\nagent = Agent('You are a helpful assistant.', hide_python_code=True)\nagent.user_input('caculate 0.999 ** 1000')\n```\n\n\n\n### AI\u641c\u7d22\n\n```python\n# AI\u641c\u7d22\n# \u8fd0\u884c\u524d\u7f6e\u6761\u4ef6: \n# 1. \u8bf7\u5148\u914d\u7f6e\u73af\u5883\u53d8\u91cf SERPER_API_KEY (https://serper.dev/ \u7684API KEY)\uff1b\n# 2. \u5b89\u88c5 selenium \u5e93: pip install selenium\n\nfrom GeneralAgent import Agent\nfrom GeneralAgent import skills\n\ngoogle_results = []\n\n# \u6b65\u9aa41: \u7b2c\u4e00\u6b21google\u641c\u7d22\nquestion = input('\u8bf7\u8f93\u5165\u95ee\u9898\uff0c\u8fdb\u884c AI \u641c\u7d22: ')\n# question = '\u5468\u9e3f\u794e\u5356\u8f66'\ncontent1 = skills.google_search(question)\ngoogle_results.append(content1)\n\n# \u6b65\u9aa42: \u7b2c\u4e8c\u6b21google\u641c\u7d22: \u6839\u636e\u7b2c\u4e00\u6b21\u641c\u7d22\u7ed3\u6784\uff0c\u83b7\u53d6\u7ee7\u7eed\u641c\u7d22\u7684\u95ee\u9898\nagent = Agent('\u4f60\u662f\u4e00\u4e2aAI\u641c\u7d22\u52a9\u624b\u3002')\nquerys = agent.run(f'\u7528\u6237\u95ee\u9898: \\n{question}\\n\\n\u641c\u7d22\u5f15\u64ce\u7ed3\u679c: \\n{content1}\\n\\n\u3002\u8bf7\u95ee\u53ef\u4ee5\u5e2e\u52a9\u7528\u6237\uff0c\u9700\u8981\u7ee7\u7eed\u641c\u7d22\u7684\u5173\u952e\u77ed\u8bed\u6709\u54ea\u4e9b(\u6700\u591a3\u4e2a\uff0c\u4e14\u548c\u95ee\u9898\u672c\u8eab\u4e0d\u592a\u91cd\u5408)\uff1f\u8fd4\u56de\u5173\u952e\u77ed\u8bed\u5217\u8868\u53d8\u91cf([query1, query2])', return_type=list)\nprint(querys)\nfor query in querys:\n content = skills.google_search(query)\n google_results.append(content)\n\n# \u6b65\u9aa43: \u63d0\u53d6\u91cd\u70b9\u7f51\u9875\u5185\u5bb9\nagent.clear()\nweb_contents = []\ngoogle_result = '\\n\\n'.join(google_results)\nurls = agent.run(f'\u7528\u6237\u95ee\u9898: \\n{question}\\n\\n\u641c\u7d22\u5f15\u64ce\u7ed3\u679c: \\n{google_result}\\n\\n\u3002\u54ea\u4e9b\u7f51\u9875\u5bf9\u4e8e\u7528\u6237\u95ee\u9898\u6bd4\u8f83\u6709\u5e2e\u52a9\uff1f\u8bf7\u8fd4\u56de\u6700\u91cd\u8981\u7684\u4e0d\u8d85\u8fc75\u4e2a\u7684\u7f51\u9875url\u5217\u8868\u53d8\u91cf([url1, url2, ...])', return_type=list)\nfor url in urls:\n content = skills.web_get_text(url, wait_time=2)\n web_contents.append(content)\n\n# \u6b65\u9aa44: \u8f93\u51fa\u7ed3\u679c\nagent.clear()\nweb_content = '\\n\\n'.join(web_contents)\nagent.run(f'\u7528\u6237\u95ee\u9898: \\n{question}\\n\\n\u641c\u7d22\u5f15\u64ce\u7ed3\u679c: \\n{google_result}\\n\\n\u90e8\u5206\u7f51\u9875\u5185\u5bb9: \\n{web_content}\\n\\n\u3002\u8bf7\u6839\u636e\u7528\u6237\u95ee\u9898\uff0c\u641c\u7d22\u5f15\u64ce\u7ed3\u679c\uff0c\u7f51\u9875\u5185\u5bb9\uff0c\u7ed9\u51fa\u7528\u6237\u8be6\u7ec6\u7684\u56de\u7b54\uff0c\u8981\u6c42\u6309\u4e00\u5b9a\u76ee\u5f55\u7ed3\u6784\u6765\u8f93\u51fa\uff0c\u5e76\u4e14\u4f7f\u7528markdown\u683c\u5f0f\u3002')\n```\n\n### \u66f4\u591a\n\n\u66f4\u591a\u4f8b\u5b50\u8bf7\u89c1 [examples](./examples)\n\n\n\n## API\n\n### \u57fa\u7840\u4f7f\u7528\n\n**Agent.\\__init__(self, role: str, workspace: str = None, functions: List[Callable] = [], knowledge_files: List[str] = None)**\n\n\u521d\u59cb\u5316\u4e00\u4e2aAgent\u5b9e\u4f8b\u3002\n\n- role (str): Agent\u7684\u89d2\u8272\u3002\n- workspace (str, \u53ef\u9009): Agent\u7684\u5de5\u4f5c\u7a7a\u95f4\u3002\u9ed8\u8ba4\u503c\u4e3aNone\uff08\u4e0d\u5e8f\u5217\u5316\uff09\u3002\u5982\u679c\u6307\u5b9a\u4e86\u76ee\u5f55\uff0cAgent\u4f1a\u81ea\u52a8\u4fdd\u5b58\u72b6\u6001\u5e76\u5728\u4e0b\u6b21\u521d\u59cb\u5316\u65f6\u91cd\u65b0\u52a0\u8f7d\u3002\n- functions (List[Callable], \u53ef\u9009): Agent\u53ef\u4ee5\u8c03\u7528\u7684\u51fd\u6570\u5217\u8868\u3002\n- knowledge_files (List[str], \u53ef\u9009): Agent\u77e5\u8bc6\u5e93\u6587\u4ef6\u8def\u5f84\u5217\u8868\u3002\n- messages (List[str], \u53ef\u9009): Agent\u7684\u5386\u53f2\u6d88\u606f\u5217\u8868, \u6d88\u606f\u5b57\u6bb5\u4e2d\u5fc5\u987b\u5305\u542b 'role', 'content' \u5b57\u6bb5\u3002\n\n**Agent.run(self, command: Union[str, List[Union[str, Dict[str, str]]]], return_type: str = str, display: bool = False)**\n\n\u6267\u884c\u547d\u4ee4\u5e76\u8fd4\u56de\u6307\u5b9a\u7c7b\u578b\u7684\u7ed3\u679c\u3002\n\n- command (Union[str, List[Union[str, Dict[str, str]]]]): \u8981\u6267\u884c\u7684\u547d\u4ee4\u3002\u4f8b\u5982\uff1a'describe chengdu' \u6216 ['what is in image?', {'image': 'path/to/image'}]\u3002\n- return_type (str, \u53ef\u9009): \u7ed3\u679c\u7684\u8fd4\u56de\u7c7b\u578b\u3002\u9ed8\u8ba4\u503c\u4e3astr\u3002\n- display (bool, \u53ef\u9009): \u662f\u5426\u663e\u793aLLM\u751f\u6210\u7684\u4e2d\u95f4\u5185\u5bb9\u3002\u9ed8\u8ba4\u503c\u4e3aFalse\u3002\n\n**Agent.user_input(self, input: Union[str, List[Union[str, Dict[str, str]]]])**\n\n\u54cd\u5e94\u7528\u6237\u8f93\u5165\uff0c\u5e76\u59cb\u7ec8\u663e\u793aLLM\u751f\u6210\u7684\u4e2d\u95f4\u5185\u5bb9\u3002\n\n- input (Union[str, List[Union[str, Dict[str, str]]]]): \u7528\u6237\u8f93\u5165\u3002\n\n**Agent.temporary_context(self, input: Union[str, List[Union[str, Dict[str, str]]]])**\n\n\u5bf9\u8bdd\u4ea7\u751f\u7684\u6570\u636e\uff0c\u4e0d\u8fdb\u5165 agent memory \u4e2d\u3002\n\n- input (Union[str, List[Union[str, Dict[str, str]]]]): \u7528\u6237\u8f93\u5165\u3002\n\n```python\nfrom GeneralAgent import Agent\n\nagent = Agent('You are a helpful assistant.')\nwith agent.temporary_context():\n agent.user_input('My name is Henry.')\nagent.user_input(\"What's my name?\")\n```\n\n**Agent.clear(self)**\n\n\u6e05\u9664Agent\u7684\u72b6\u6001\u3002\n\n### \u9ad8\u7ea7\u4f7f\u7528\n\n[ ] # TODO\n\n\n\n\n## \u8bba\u6587\n\n[General Agent\uff1aSelf Call and Stack Memory](./docs/paper/General_Agent__Self_Call_And_Stack_Memory.pdf)\n\n\n\n\n\n## \u52a0\u5165\u6211\u4eec\ud83d\udc4f\ud83c\udffb\n\n\u4f7f\u7528\u5fae\u4fe1\u626b\u63cf\u4e0b\u65b9\u4e8c\u7ef4\u7801\uff0c\u52a0\u5165\u5fae\u4fe1\u7fa4\u804a\uff0c\u6216\u53c2\u4e0e\u8d21\u732e\u3002\n\n<p align=\"center\">\n<img src=\"./docs/images/wechat.jpg\" alt=\"wechat\" width=400/>\n</p>",
"bugtrack_url": null,
"license": "Apache 2.0",
"summary": "General Agent: From LLM to Agent",
"version": "0.3.29",
"project_urls": {
"Homepage": "https://github.com/CosmosShadow/GeneralAgent",
"Repository": "https://github.com/CosmosShadow/GeneralAgent"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "934a7da38b094bad51228b223a017d7f44dbc82a1b00a1bdab83688dce60dc78",
"md5": "3bb53562c5738921acf3461ecef7ec2e",
"sha256": "81bf7175cdbfdd671dc6ab204569c4d56b51bb17feca6c6c037a1b2dcb19a0f3"
},
"downloads": -1,
"filename": "generalagent-0.3.29.tar.gz",
"has_sig": false,
"md5_digest": "3bb53562c5738921acf3461ecef7ec2e",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8.1",
"size": 105622,
"upload_time": "2024-11-19T08:35:05",
"upload_time_iso_8601": "2024-11-19T08:35:05.532679Z",
"url": "https://files.pythonhosted.org/packages/93/4a/7da38b094bad51228b223a017d7f44dbc82a1b00a1bdab83688dce60dc78/generalagent-0.3.29.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-19 08:35:05",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "CosmosShadow",
"github_project": "GeneralAgent",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "generalagent"
}