适合程序员的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 的一些主要特点:

  1. 快速:FastAPI 基于标准 Python 类型提示,可以自动推断数据类型,从而实现高性能。
  2. 简洁:代码简洁,易于理解和维护。
  3. 功能丰富:提供了丰富的功能,如数据验证、序列化和认证等。
  4. 异步支持:支持异步请求处理,可以提高应用的并发处理能力。
  5. 交互式文档:自动生成交互式 API 文档,方便开发者和用户使用。
  6. 类型检查:利用 Python 类型提示,可以在运行时进行类型检查,减少错误。
  7. 依赖注入:支持依赖注入,方便管理依赖关系。
  8. 数据库集成:可以轻松集成数据库,如 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 协议》,转载必须注明作者和本文链接
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!