news 2026/9/1 5:35:12

【从零开发 AI Agent】【Day 1】【如何实现一问一答】

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【从零开发 AI Agent】【Day 1】【如何实现一问一答】

AI Agent,AI 智能体如何开发?
对此,我制定了一个路线:

  1. LLM API 单次调用,实现一问一答
  2. LLM API 循环调用,实现循环问答
  3. 实现 Chatbot
  4. 实现 Agent

今天先讲讲如何实现一问一答

Chapter 1. LLM API

以 Python 环境中调用 DeepSeek 为例
其实大模型的调用最底层只需要三行代码:

# 导入 requests 模块importrequests# 发送请求response=requests.post(url="https://api.deepseek.com/chat/completions",headers={"Authorization":"Bearer your_api_key"},json={"model":"deepseek-v4-flash","messages":[{"role":"user","content":"你好"}],},)# 打印响应print(response.json())

如此运行一次程序便能实现与大模型的一问一答。

大模型只能一问一答,这是日后开发 Chatbot 和 Agent 的核心、关键!

为了安全起见,我一般会把密钥写入环境变量。如果你的密钥也和我一样写入了电脑环境里,或者当前终端的临时环境中,那么你可以用下面的方式来使用你的密钥:

# 导入模块importosimportrequests# 读取环境变量中的密钥api_key=os.getenv("DEEPSEEK_API_KEY")# 发送请求response=requests.post(url="https://api.deepseek.com/chat/completions",headers={"Authorization":f"Bearer{api_key}"},json={"model":"deepseek-v4-flash","messages":[{"role":"user","content":"你好"}],},)# 打印响应print(response.json())

现在我们可以通过 API 调用,得到了自己的 AI 助手。虽然它现在还很简陋,但是恭喜你已经获得了大模型的能力。那么接下来的开发路径便产生了分支。

一问一答

循环问答

Web UI

终端输入

消息存储

流式输出

我首先选择实现终端输入,代码如下:

# 导入模块importosimportrequests# 读取环境变量中的密钥api_key=os.getenv("DEEPSEEK_API_KEY")# 终端输入question=input("请输入问题:")# 发送请求response=requests.post(url="https://api.deepseek.com/chat/completions",headers={"Authorization":f"Bearer{api_key}"},json={"model":"deepseek-v4-flash","messages":[{"role":"user","content":question}],},)# 打印响应print(response.json())

达成了终端输入成就之后,解除了输入的限制,总算像那么点回事了。但是眼下大模型的回答似乎有点奇怪……

这和咱们平时用的AI,对话起来似乎很不一样啊,有太多“杂乱无章”的东西。没关系,我们耐下心,来一一拆解它们。换换行,让其中的细节更加明显一些:

{'id':'33fa70d1-b89c-4b87-b658-d4bd13c187f4','object':'chat.completion','created':1788102644,'model':'deepseek-v4-flash','choices':[{'index':0,'message':{'role':'assistant','content':'你好!我是 DeepSeek,由深度求索公司开发的 AI 助手。\n\n我可以帮你做很多事情,比如:\n\n- **回答问题**:涵盖知识、生活、科技、学习等各种领域\n- **写作与创作**:文章、文案、代码、方案等\n- **分析总结**:帮你整理信息、提炼重点\n- **编程辅助**:写代码、调试、讲解技术概念\n\n我的一些特点:\n\n- **免费使用**:目前完全免费,没有收费计划\n- **支持长文本**:上下文窗口达到 1M,可以一次性处理超长内容\n- **文件上传**:支持上传图片、PDF、Word、Excel、PPT 等文件,我会读取其中的文字信息帮你处理\n- **联网搜索**:需要时可以手动开启联网功能获取实时信息\n- **语音输入**:App 端支持语音交互\n\n我的知识截止日期是 2025 年 5 月。虽然我不支持多模态视觉识别(比如识别图片内容),但可以读取图片中的文字。\n\n有什么我可以帮你的吗?尽管问我吧!😊','reasoning_content':'We need answer in Chinese. Need introduce myself. As AI assistant from DeepSeek. Mention capabilities, free, knowledge cutoff, file upload, context. Keep concise.'},'logprobs':None,'finish_reason':'stop'}],'usage':{'prompt_tokens':85,'completion_tokens':263,'total_tokens':348,'prompt_tokens_details':{'cached_tokens':0},'completion_tokens_details':{'reasoning_tokens':34},'prompt_cache_hit_tokens':0,'prompt_cache_miss_tokens':85},'system_fingerprint':'a26a7955944dc5c60445bff77fac9c8e'}

蛙趣!这行数可真多啊!没关系,我们先关注我们最关心的东西——像我们平时使用的 AI 对话中的回答的部分在哪?

'content':'你好!我是 DeepSeek,由深度求索公司开发的 AI 助手。\n\n我可以帮你做很多事情,比如:\n\n- **回答问题**:涵盖知识、生活、科技、学习等各种领域\n- **写作与创作**:文章、文案、代码、方案等\n- **分析总结**:帮你整理信息、提炼重点\n- **编程辅助**:写代码、调试、讲解技术概念\n\n我的一些特点:\n\n- **免费使用**:目前完全免费,没有收费计划\n- **支持长文本**:上下文窗口达到 1M,可以一次性处理超长内容\n- **文件上传**:支持上传图片、PDF、Word、Excel、PPT 等文件,我会读取其中的文字信息帮你处理\n- **联网搜索**:需要时可以手动开启联网功能获取实时信息\n- **语音输入**:App 端支持语音交互\n\n我的知识截止日期是 2025 年 5 月。虽然我不支持多模态视觉识别(比如识别图片内容),但可以读取图片中的文字。\n\n有什么我可以帮你的吗?尽管问我吧!😊',

content的中文意思就是“内容”。很显然这段代码本质上是一个键值对(key value pair)。键和值都是字符串类型的。那么右边的这部分字符串,便是 AI 回答的内容了。既是现在已经把回答内容单独取出来了,可是这个内容本身还是看起来很奇怪。我们使用代码放大器🔍把它再放大一点,聚焦其中的细节。

'你好!我是 DeepSeek,由深度求索公司开发的 AI 助手。\n\n我可以帮你做很多事情,比如:\n\n- **回答问题**:涵盖知识、生活、科技、学习等各种领域\n- **写作与创作**:文章、文案、代码、方案等\n- **分析总结**:帮你整理信息、提炼重点\n- **编程辅助**:写代码、调试、讲解技术概念\n\n我的一些特点:\n\n- **免费使用**:目前完全免费,没有收费计划\n- **支持长文本**:上下文窗口达到 1M,可以一次性处理超长内容\n- **文件上传**:支持上传图片、PDF、Word、Excel、PPT 等文件,我会读取其中的文字信息帮你处理\n- **联网搜索**:需要时可以手动开启联网功能获取实时信息\n- **语音输入**:App 端支持语音交互\n\n我的知识截止日期是 2025 年 5 月。虽然我不支持多模态视觉识别(比如识别图片内容),但可以读取图片中的文字。\n\n有什么我可以帮你的吗?尽管问我吧!😊'

通篇出现了明显的重复结构——成对的双星号,如果你有使用 Markdown 的经验,那么你不难回想到这是 Markdown 的文字加粗语法,继而我们不妨大胆猜测——这段字符串是 Markdown 格式的文本。但是如何直接复制粘贴到.md文件中的话,只能得到以下效果:

那是因为,这段文本其实不是严格意义上的 Markdown 文本,而是一段带转义符的 Markdown 文本。\n表示换行,-表示列表项。那么怎样才能把它转化为一个常见的 Markdown 文本呢?想要转化,首先我们需要搞清楚这段内容与我们前面得到的响应之间的关系,毕竟我们总不能每次都从一坨大模型返回的结果中挑出这一小部分再拿去转化呀,我们希望我们的程序能够自动进行解析。
我们重新看一眼大模型返回的内容,不过,content对应的值我们前面研究过了,这一次可以把它忽略掉,避免我们的注意力分散,减少我们的认知压力:

{'id':'33fa70d1-b89c-4b87-b658-d4bd13c187f4','object':'chat.completion','created':1788102644,'model':'deepseek-v4-flash','choices':[{'index':0,'message':{'role':'assistant','content':'','reasoning_content':'We need answer in Chinese. Need introduce myself. As AI assistant from DeepSeek. Mention capabilities, free, knowledge cutoff, file upload, context. Keep concise.'},'logprobs':None,'finish_reason':'stop'}],'usage':{'prompt_tokens':85,'completion_tokens':263,'total_tokens':348,'prompt_tokens_details':{'cached_tokens':0},'completion_tokens_details':{'reasoning_tokens':34},'prompt_cache_hit_tokens':0,'prompt_cache_miss_tokens':85},'system_fingerprint':'a26a7955944dc5c60445bff77fac9c8e'}

'content': ''是一个键值对,那么什么地方会有键值对呢?没错,字典!哪里有字典呢?根据就近原则,我们逐行向上打量。找到了!message是一个字典。

'message':{}

这个message也不一般,也是一个键,所以一定存在着更大的字典,不过我们当前先不管,先管好眼前——这个字典是怎样的呢?

'message':{'role':'assistant','content':'','reasoning_content':''}

message,中文“消息”的意思。它此时作为一个字典,包含三个元素,rolecontentreasoning_content。前面初步分析过了content,现在我们先看看与它最相似的reasoning_content是什么吧?reasoning content,中文意思是“推理内容”。它对应的就是大模型的推理思也就是常听说的思维链(CoT,Chain of Thought1)。

'reasoning_content':'We need answer in Chinese. Need introduce myself. As AI assistant from DeepSeek. Mention capabilities, free, knowledge cutoff, file upload, context. Keep concise.'

最后一个元素是rolerole的中文含义是“角色”,对应的值assistant则是“助手”的意思。逐一解析了message的细节之后,我们再回过头去重新打量一下message的整体:

'message':{'role':'assistant','content':'','reasoning_content':''}

有没有发现它的形象似曾相识——

"messages":[{"role":"user","content":"你好"}]"messages":[{"role":"user","content":question}]

相似之中,又有所不同。大模型的响应结果中,message的值是一个字典,而我们前面在请求的时候,message是一个列表。这其中自有玄机,后面我们很快就会用到这个细微的差别。
现在我们知道了contentmessage字典中的一个键值对,那么如何获取它的值呢?这个方法也就随即确定了:

message['content']

只不过,这个message也是一个字典元素,单靠上面那样子还不足以达到访问回答内容的目的。我么还需要继续分析一下大模型的响应结果。message所属于的字典在哪呢?

{'index':0,'message':{},'logprobs':None,'finish_reason':'stop'}

这个花括号括{}起来的部分,便是message所在的字典,而这个字典又位于数组中。

'choices':[{'index':0,'message':{},'logprobs':None,'finish_reason':'stop'}],

并且这个数组只有一个元素,就是message所在的这个字典。因此我们可以这样访问回答内容;

[0]['message']['content']

而这个数组呢,又是键choices所对应的值,

{'id':'33fa70d1-b89c-4b87-b658-d4bd13c187f4','object':'chat.completion','created':1788102644,'model':'deepseek-v4-flash','choices':[],...}

choices同样位于一个更大的字典中,而这个字典是谁呢?这个字典就出现在我们用来打印大模型响应结果的那句指令之中——

print(response.json())

response.json()
至此,我们总算理清楚了程序自动访问回答内容的指令:

response.json()['choices'][0]['message']['content']

而如果你想要在终端输出,你只需在外面套一层print()即可。

# 导入模块importosimportrequests# 读取环境变量中的密钥api_key=os.getenv("DEEPSEEK_API_KEY")# 终端输入question=input("请输入问题:")# 发送请求response=requests.post(url="https://api.deepseek.com/chat/completions",headers={"Authorization":f"Bearer{api_key}"},json={"model":"deepseek-v4-flash","messages":[{"role":"user","content":question}],},)# 打印响应中的回答内容print(response.json()['choices'][0]['message']['content'])


以上便是今日的开发 or 学习笔记——如何在 Python 环境中调用 LLM API 进行一问一答。

明天我们将学习如何流式输出,让 AI 的回答一个字一个字、一个词一个词蹦出,就仿佛是在一边思考一边回复一样。以及如何存储对话消息记录,为持续对话提供关键的基石。


  1. Chain-of-Thought Prompting Elicits Reasoning in Large Language Models ↩︎

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/1 5:34:17

微胶囊香味油墨原理、丝印工艺与量产故障解析

摘要 香味油墨属于特种功能油墨,依靠微胶囊包覆香精实现摩擦释香,在文创绘本、包装印刷、防伪标签领域应用广。很多项目打样效果理想,批量生产却出现提前散香、香味微弱、堵网等不良。本文从材料原理、印刷工艺控制点、常见故障排查、选型测试…

作者头像 李华
网站建设 2026/9/1 5:33:57

三款一键生成论文工具横评:从写作到润色怎么选才不踩坑?

写论文这事,最怕的不是写不出来,而是写得心里没底。 题目改了七八版还怕选重了,文献下载了两百篇越读越乱,参考文献格式调到崩溃,交稿前还得担心重复率和AIGC检测。今年开学季一到,又有一波人在搜"AI论…

作者头像 李华
网站建设 2026/9/1 5:33:54

爱奇艺2024数据岗面试全解析:业务+工程+数仓交叉点

面试这几年聊下来,我最大的感受是:视频平台的数据岗面试,题目本身往往不难,难的是你能不能站在“业务 工程 数仓”的交叉点上回答问题。爱奇艺2024年这批数据面试题,看似是在考SQL、考Python、考指标体系&#xff0c…

作者头像 李华
网站建设 2026/9/1 5:33:49

ESP32/ESP8266接入涂鸦云Tuyalink:MQTT over TLS实战

简介:这是一份面向物联网开发者的ESP8266/32接入涂鸦Tuyalink平台的Arduino项目源码包,适合需要实现智能设备联网、远程控制与OTA在线升级的嵌入式工程师。压缩包共3个文件,包含inscode工程配置文件、index.html设备控制页面和.gitignore版本…

作者头像 李华
网站建设 2026/9/1 5:33:23

用友前端秋招笔试考点全解析:从响应式原理到手写Promise

又到了秋招季,不少学弟学妹私信问我:“学长,用友的前端笔试到底考什么?”说实话,用友这两年在校招圈的存在感不低,老牌ToB大厂、上市公司、企业服务赛道头部玩家,技术栈随着云转型越铺越广&…

作者头像 李华
网站建设 2026/9/1 5:32:34

开源AI数据标注平台Label Studio:源码部署与二次开发实战

简介:Label Studio数据标注指南附带可运行源码,面向大模型训练中的数据工程师、算法工程师及AI产品经理,旨在解决多模态数据标注流程搭建与实操落地问题。压缩包共3个文件,以HTML说明文档为主体,配合inscode在线运行配…

作者头像 李华