当前位置:   article > 正文

可控的大模型应用框架:simple_ai_toolset

可控的大模型应用框架:simple_ai_toolset

项目背景:

作为最普通的程序员一员,同时知道未来的开发必然是AI大模型相关开发为主,怎样入局?查看了市面多数开源项目,觉得大部分项目要么过度封装和复杂,要么就是困难和不灵活。普通程序员很难二开和可控利用。所以产生以下项目simple_ai_toolset:github.com/liangdabiao… 。 以下介绍它是什么,有什么用,未来计划和开发方向。

功能介绍:

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/sl…

考虑到程序员开发和利用大模型,需要把大模型的不确定性转为可控,所以利用了pydantic库来进行大模型输出的可控。利用pydantic可以指定一个 JSON 对象中必须包含哪些属性,这些属性的数据类型是什么,是否有默认值,以及其他一些约束条件。

考虑到大模型应用开发的工具库是有通用情况,所以框架集成了Image图片处理和生成,各种language大模型的集成(如openai,gemini等),Embedding向量数据库集成,prompts提示词工具,agent工具,读取解析各类文件工具,json数据可控工具,第三方数据api对接工具,数据库和缓存工具,搜索引擎内容工具等等。方便程序员快速利用和开发。

2,Embedding向量和RAG

RAG技术包括三个核心部分:索引(Indexing)、检索(Retrieval)和生成(Generation)

索引(Indexing) ,取用各大模型商提供的embeddings技术,把知识数据转化为向量数据。索引的一个关键部分是把知识整理好,本项目利用了llama_parse ([cloud.llamaindex.ai/parse),强大的工…]

检索(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)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

利用了自定义提示语等方法,把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"""

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

智能体利用工具例子:

"""   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)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

测试过很多,效果是很不错的,可控的利用好智能体,满足程序员开发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)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

利用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)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

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
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

总结:

本框架的目的就是为了:

1,利用好大模型技术带来的新作用,让程序员从处理信息转为处理知识,这是新的复杂性,带来很多新工作

2,可控性是整合各系统和流程的关键,同时, 智能知识处理输入输出,是整合多个复杂系统的粘合剂

3,本框架已经整合了很多有用的工具,节省大家开发时间。

4,本框架参考了多个开源项目,特别致谢 learnwithhasan.com

如何学习AI大模型?

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

在这里插入图片描述

第一阶段: 从大模型系统设计入手,讲解大模型的主要方法;

第二阶段: 在通过大模型提示词工程从Prompts角度入手更好发挥模型的作用;

第三阶段: 大模型平台应用开发借助阿里云PAI平台构建电商领域虚拟试衣系统;

第四阶段: 大模型知识库应用开发以LangChain框架为例,构建物流行业咨询智能问答系统;

第五阶段: 大模型微调开发借助以大健康、新零售、新媒体领域构建适合当前领域大模型;

第六阶段: 以SD多模态大模型为主,搭建了文生图小程序案例;

第七阶段: 以大模型平台应用与开发为主,通过星火大模型,文心大模型等成熟大模型构建大模型行业应用。

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/940613
推荐阅读