适合程序员的AI大模型开发框架-simple_ai_toolset
项目背景:
作为最普通的程序员一员,同时知道未来的开发必然是AI大模型相关开发为主,怎样入局?查看了市面多数开源项目,觉得大部分项目要么过度封装和复杂,要么就是困难和不灵活。普通程序员很难二开和可控利用。所以产生以下项目simple_ai_toolset:github.com/liangdabiao/simple_ai_t... 。 以下介绍它是什么,有什么用,未来计划和开发方向。
功能介绍:
simple_ai_toolset :AI大模型的基本开发框架,适合普通后端程序员,功能类似coze,包括:fastapi后端接口,搜索引擎对接,RAG文档解析和向量化,RPA和爬虫,自定义agent,对接第三方数据接口,mongodb数据库,控制json返回,多模态理解和生成等等。有新的AI功能,会马上跟随潮流,添加上去。
AI大模型应用开发理念:
1, 理解复杂,处理复杂,生成复杂
2, 尽量把不确定的AI黑盒子转为更加确定性的可控的流程和结果
3, 大模型应用原型开发是容易的,但是真实可用的AI应用其实需要程序员深入开发,本框架就是这个目的
技术介绍:
1,后端用fastapi
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API。它基于标准 Python 类型提示,并且非常适合初学者和大型项目。以下是 FastAPI 的一些主要特点:
- 快速:FastAPI 基于标准 Python 类型提示,可以自动推断数据类型,从而实现高性能。
- 简洁:代码简洁,易于理解和维护。
- 功能丰富:提供了丰富的功能,如数据验证、序列化和认证等。
- 异步支持:支持异步请求处理,可以提高应用的并发处理能力。
- 交互式文档:自动生成交互式 API 文档,方便开发者和用户使用。
- 类型检查:利用 Python 类型提示,可以在运行时进行类型检查,减少错误。
- 依赖注入:支持依赖注入,方便管理依赖关系。
- 数据库集成:可以轻松集成数据库,如 SQLAlchemy、Django ORM 等。
FastAPI 特别适合用于构建高性能的微服务和 Web 应用,并且可以与现代前端框架(如 React、Vue.js 等)无缝集成。
项目取用 python的 fastapi作为框架,我觉得这是最适合AI大模型开发的框架,同时也是最适合现代后端开发的框架。
考虑到AI资源有限,必须在框架增加保护和限制,所以加上使用slowapi对FastApi的接口进行限速:github.com/laurents/slowapi
考虑到程序员开发和利用大模型,需要把大模型的不确定性转为可控,所以利用了pydantic库来进行大模型输出的可控。利用pydantic可以指定一个 JSON 对象中必须包含哪些属性,这些属性的数据类型是什么,是否有默认值,以及其他一些约束条件。
考虑到大模型应用开发的工具库是有通用情况,所以框架集成了Image图片处理和生成,各种language大模型的集成(如openai,gemini等),Embedding向量数据库集成,prompts提示词工具,agent工具,读取解析各类文件工具,json数据可控工具,第三方数据api对接工具,数据库和缓存工具,搜索引擎内容工具等等。方便程序员快速利用和开发。
2,Embedding向量和RAG
RAG技术包括三个核心部分:索引(Indexing)、检索(Retrieval)和生成(Generation)
索引(Indexing),取用各大模型商提供的embeddings技术,把知识数据转化为向量数据。索引的一个关键部分是把知识整理好,本项目利用了llama_parse (https://cloud.llamaindex.ai/parse),强大的工具把各种文档的知识整理成markdown形式方便AI大模型学习和索引。同时也推荐doc2x和OmniParse等强大工具。
检索(Retrieval),本项目已经内置案例,本地文件保存和检索向量,还有pinecone和chromadb 等主流向量数据库。 chunking分段也有内置自定义函数,和利用llama_index的成熟方案。按自己实际情况选择,都有案例展示。chunking分段的可控也是RAG成功的重要部分,本项目有提供方法。
生成(Generation),常规的RAG对于我们程序员是很难可控的,输入输出都不可控,所以很难把AI大模型的技术整合在原有系统,所以本项目的重点是把它变成可控,生成(Generation)部分,代码例子如下:
定义qa prompt
qa_prompt_tmpl_str = (
"## 角色\n"
"请你扮演中国软件水平考试高级辅导专家,负责用户发送的概念讲解和发送的题目解答。\n"
"## 技能\n"
"### 技能1:概念讲解\n"
"当我发送一些软考概念题目的上下文信息。\n"
"Step1:根据概括帮我讲解一下相关内容,讲解时尽量通俗易懂,并给出恰当的例子,优先使用 markdown 表格的形式来呈现\n"
"Step2:出 2 道相关的选择题,在出完题目的最后给出答案和对答案的详细讲解。\n"
"输出格式为:\n"
"=====\n"
"# 一、AI 讲解\n"
"<概念讲解>\n"
"# 二、AI 出题\n"
"### (1)题目\n"
"<出对应的2道选择题>\n"
"### (2)答案和解析\n"
"<所有选择题的答案和解释,每个答案和对应解释放在一起>\n"
"=====\n"
"## 要求\n"
"1 必须使用中文回答我\n"
"2 解答时,尽量使用通俗易懂的语言\n"
"3 讲解时,如果有可能尽量给出相关例子\n"
"4 讲解时,优先考虑使用 markdown 表格的方式呈现,如果出现不同层级的概念,可以将不同层级的概念用不同的表格表示\n"
"5 给出答案和解析时,每道题的答案和解释要在一起给出,答案的解释需要详尽\n"
"上下文信息如下。\n"
"---------------------\n"
"{context_str}\n"
"---------------------\n"
"请根据上下文信息而不是先验知识来回答以下的查询。回复格式:markdown 。 "
"作为一个中国软考考试专家人工智能助手,你的回答要尽可能严谨。\n"
"Query: 关于 {query_str}\n"
"Answer: "
)
qa_prompt_tmpl = PromptTemplate(qa_prompt_tmpl_str)
# 更新查询引擎中的prompt template
query_engine.update_prompts(
{"response_synthesizer:text_qa_template": qa_prompt_tmpl,
"response_synthesizer:refine_template": refine_prompt_tmpl}
)
response = query_engine.query(question)
利用了自定义提示语等方法,把RAG的可控性大大增加。
3,Agent智能体代理
agent智能体必然会成为程序员开发的主要工作,因为这里太多模糊,定制,复杂,同时价值巨大。复杂性带来工作,所以必须非常重视这一块,所以本框架提供了最实用的智能体,同时做到最简化和最可控,这样才能整合在项目开发之中。利用了ReAct思想,让智能体自己选择合适的tool工具,反思和行动,然后一步一步自动完成和实现工作。
ReAct prompt 提示词如下:
prompt_template = “””
You run in a loop of Thought, Action, PAUSE, Action_Response.
At the end of the loop you output an Answer.
Use Thought to understand the question you have been asked.
Use Action to run one of the actions available to you - then return PAUSE.
Action_Response will be the result of running those actions.
Your available actions are:
{actions_list}
To use an action, please use the following format:
Thought: Do I need to use a tool? Yes
Action:
{{
"function_name": tool_name,
"function_params": {{
"param": "value"
}}
}}
Action_Response: the result of the action"""
智能体利用工具例子:
“”” ai agent tester “””
@router.get(“/ai_agent_lego”)
async def ai_agent_lego(question: str, request: Request):
llm_instance = LLM.create(provider=LLMProvider.OPENAI, model_name="gpt-4o")
# Create an agent instance
agent = Agent(LLMProvider.OPENAI, model_name="gpt-4o")
#add tools
agent.add_tool(tool_brick4_search)
agent.add_tool(tool_smzdm)
agent.add_tool(tool_brick4)
user_query = question
# Generate a response
final_result = agent.generate_response(user_query)
print(final_result)
测试过很多,效果是很不错的,可控的利用好智能体,满足程序员开发AI大模型应用的很重要部分。
框架使用的例子
1,可控的RAG应用:
documents = SimpleDirectoryReader(input_files=[‘./data/abc.txt’]).load_data()
print(documents)
index = VectorStoreIndex.from_documents(
documents, storage_context=storage_context
)
query_engine = index.as_query_engine()
# 可以指定固定回复格式 参考:https://segmentfault.com/a/1190000044329812
# query_engine = index.as_query_engine(output_cls=BlogTitles)
# 定义qa prompt
qa_prompt_tmpl_str = (
"上下文信息如下。\n"
"---------------------\n"
"{context_str}\n"
"---------------------\n"
"请根据上下文信息而不是先验知识来回答以下的查询。回复格式:请务必把上下文的图片image jpg放在回答的底部作为参考。"
"作为一个油画艺术人工智能助手,你的回答要尽可能严谨。\n"
"Query: {query_str}\n"
"Answer: "
)
qa_prompt_tmpl = PromptTemplate(qa_prompt_tmpl_str)
# 定义refine prompt
refine_prompt_tmpl_str = (
"原始查询如下:{query_str}"
"我们提供了现有答案:{existing_answer}"
"我们有机会通过下面的更多上下文来完善现有答案(仅在需要时)。"
"------------"
"{context_msg}"
"------------"
"考虑到新的上下文,优化原始答案以更好地回答查询。 如果上下文没有用,请返回原始答案。"
"Refined Answer:"
)
refine_prompt_tmpl = PromptTemplate(refine_prompt_tmpl_str)
# 更新查询引擎中的prompt template
query_engine.update_prompts(
{"response_synthesizer:text_qa_template": qa_prompt_tmpl,
"response_synthesizer:refine_template": refine_prompt_tmpl}
)
response = query_engine.query(question)
利用langchain,等框架往往都是黑盒子,很难可控的控制输入输出,本框架提供了一些方法让事情变得可控,适合程序员使用。太强大太通用,对于程序员来说不够,还不如可控有用,因为AI需要整合在项目,必须可控的输入输出。 RAG也是如此的可控的进入业务流程。
2,智能体问答助手
实现让智能体作为大模型的问答助手,自行判断用户的意图,自行调用不同的接口api和服务,来得到知识,准确的回答用户问题。以下是例子,实现一个积木问答机器人,用户可以问 积木新闻,搜索积木,积木新品,积木优惠活动,积木拼搭技术,等等,然后智能体自行判断调用哪个 积木函数,得到相关知识,多次调用,提供更好的问答。
本框架和langchain的不同agent使用在于,本框架的agent完全是透明的,可控的,代码和提示词都是自行修改,这样才能方便程序员实现可控的编程和整合。
“”” 多tools的智能体 “””
#Define a brick4 search tool 定义工具,依靠注释让agent自动判断调用哪个tool
def tool_brick4_search(keyword: str):
“””
Search content from a given Keyword.
Parameters: keyword (str)
“””
llm_instance = LLM.create(provider=LLMProvider.OPENAI, model_name=”gpt-4o”)
search_query_encoded = quote_plus(keyword)
sjina = str(“http://brick4.com/get/set?filter_brandorder=0&filter_order=1&brandorder=1&page=1&s="+search_query_encoded)
“”” ai agent tester “””
@router.get(“/ai_agent_lego”)
async def ai_agent_lego(question: str, request: Request):
Create an agent instance
agent = Agent(LLMProvider.OPENAI, model_name="gpt-4o")
#add tools
agent.add_tool(tool_brick4_search)
agent.add_tool(tool_smzdm)
agent.add_tool(tool_brick4)
user_query = question
# Generate a response
final_result = agent.generate_response(user_query)
3, 写作机器人
当我们把所有tools都变成可控,输入输出可控,那么我们也可以轻松实现类似coze等的控制流,利用程序判断流程,轻松实现流程化的AI调用和整合。coze等总是报错,总是遇到小意外就出错停止反馈和回答了,这种可用性很难达到程序员的需求,所以必须自行实现和控制流程判断,处理异常情况等等。
“”” 积木写作日报, 模仿hackernew 推送和新闻头条 “””
@router.get(“/ai_write_lego”)
async def ai_write_lego(request: Request):
llm_instance = LLM.create(provider=LLMProvider.OPENAI, model_name="moonshot-v1-128k")
tool_brick_news_str = tool_brick_news()
main_points_1 = llm_instance.generate_response(prompt=f"从以下[积木情报]中提取关键信息,格式为:(标题,日期时间,链接,图片),上下文是: {tool_brick_news_str}")
tool_brick_news2_str = tool_brick_news2()
main_points_1b = llm_instance.generate_response(prompt=f"从以下[积木情报]中提取关键信息,格式为:(标题,日期时间,链接,图片),上下文是: {tool_brick_news2_str}")
tool_smzdm_str = tool_smzdm()
main_points_2 = llm_instance.generate_response(prompt=f"从以下[积木优惠]中提取关键信息,格式为:(标题,价格,折扣,评价,平台,图片),上下文是: {tool_smzdm_str}")
tool_brick4_str = tool_brick4()
main_points_3 = llm_instance.generate_response(prompt=f"从以下[积木新品]中提取关键信息,格式为:(名称,价格,上市日期,平台,图片): {tool_brick4_str}")
all_str ="\n\n # 今天积木情报: \n\n" + main_points_1 + "\n\n " + main_points_1b + "\n\n # 今天积木优惠: \n\n" + main_points_2 + "\n\n # 今天积木新品: \n\n" + main_points_3
main_points_best = llm_instance.generate_response(prompt=f"你是一个积木专栏作家,请给上下文内容一个总结,用中文回答,上下文如下: {all_str}")
print(main_points_best)
print(all_str)
总结:
本框架的目的就是为了:
1,利用好大模型技术带来的新作用,让程序员从处理信息转为处理知识,这是新的复杂性,带来很多新工作
2,可控性是整合各系统和流程的关键,同时智能的知识处理是整个多个复杂系统的粘合剂
3,本框架已经整合了很多有用的工具,节省大家开发时间。
4,本框架参考了多个开源项目,特别致谢 learnwithhasan.com
欢迎点赞,项目地址: github.com/liangdabiao/simple_ai_t...
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: