news 2026/9/6 11:09:18

四、《从零手撸 Agent》 — 流式输出:接住 AI “一个字一个字” 想出来的过程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
四、《从零手撸 Agent》 — 流式输出:接住 AI “一个字一个字” 想出来的过程

本文是《从零手撸 Agent》系列第 1 篇。这个系列假设你刚起步,从最基础的 API 调用一路写到能部署的多智能体系统,代码全部可复现。

起因

前阵子公司想搞个内部 AI 工具,活儿落我头上。说实话我当时对大模型的认知停留在"网页上跟它聊天",代码怎么调、钱怎么算、Key 从哪来,一概不知。折腾了一晚上跑通第一次调用之后我发现,这件事本身不难,难的是没人告诉你坑在哪。

所以第一篇不讲 Agent,就讲怎么从零跑通第一次调用。后面所有复杂的东西,都建立在这 10 行代码上。

装环境:虚拟环境别跳过

Python 3.10 以上,去官网装。Windows 用户注意安装界面最底下那个 “Add Python to PATH”,勾上。我就是没勾,对着python: command not found懵了十分钟。

然后建项目、建虚拟环境:

1mkdir my-first-agent && cd my-first-agent 2python -m venv .venv 3 4# Windows PowerShell: 5.venv\Scripts\activate 6# Mac / Linux: 7source .venv/bin/activate 8 9pip install openai

虚拟环境这步很多人嫌麻烦直接跳过。别。我同事图省事往系统 Python 里装了一堆库,后来版本冲突,最后重装环境解决了。给它一个独立小房间,省得以后拆家。

pip 慢的话换清华源:pip install openai -i https://pypi.tuna.tsinghua.edu.cn/simple

申请 Key

我用的 DeepSeek,注册就送额度,国内直连,适合起步。通义千问也行。注册完在控制台找 “API Keys”,创建,复制那串sk-开头的字符。

注意它只显示一次,马上存到本地记事本。还有一条铁律:Key 绝不进 git 仓库。被盗刷的案例见得太多了。

第一次调用

新建first_call.py

1from openai import OpenAI 2 3client = OpenAI( 4 api_key="sk-你自己的key", 5 base_url="https://api.deepseek.com", 6) 7 8response = client.chat.completions.create( 9 model="deepseek-chat", 10 messages=[ 11 {"role": "user", "content": "用一句话解释什么是API"} 12 ], 13) 14 15print(response.choices[0].message.content)

运行:

1python first_call.py

我拿到的回答是:“API 就像餐厅的服务员:你点菜(发请求),它转达厨房(服务器),再把做好的菜(数据)端回来。”

行,通了。但如果你跟我一样是个较真的人,这 10 行里至少有三个地方值得停下来想想。

为什么要base_url因为 DeepSeek、千问这些厂商都兼容 OpenAI 的接口格式,同一个 SDK 换个地址就能打给不同家。以后换模型,改一个字符串的事。

choices[0]是什么鬼?历史遗留。早期接口支持一次生成多个候选回答,现在固定返回 1 个,所以永远是choices[0],背下来就行。

messages 为什么是个数组?这是下一篇的主题,先埋个伏笔:模型根本不记得你上一次说了什么。

钱是怎么算的

把最后一行换成print(response),跑一遍,在输出里找usage

usage={ 'prompt_tokens': 12, # 你发过去的内容 'completion_tokens': 35, # 模型的回答 'total_tokens': 47, }

token 是模型的计量单位,大概 0.75 个英文单词或者 0.6 个汉字。计费按这个来。第一次看到这个字段的时候我还没什么感觉,后来做了 Agent 才知道,这个字段能让你省一半的钱。这里先记住一句话:你发的内容越多,越贵。后面讲上下文管理时全靠这条。

Key 别写死在代码里

我第一版代码就把 Key 硬编码了,被同事看到骂了一顿。标准做法是环境变量:

1# Mac / Linux: 2export OPENAI_API_KEY="sk-你的key" 3# Windows PowerShell: 4$env:OPENAI_API_KEY="sk-你的key"
1import os 2from openai import OpenAI 3client = OpenAI( 4 api_key=os.environ["OPENAI_API_KEY"], 5 base_url="https://api.deepseek.com", 6)

我踩过的 4 个坑,希望你绕开

  1. python: command not found—— 装的时候没勾 Add to PATH,重装勾上
  2. pip install卡死 —— 网络问题,换镜像源
  3. Key 泄露 —— 只存本地环境变量,.gitignore里加上相关文件
  4. AttributeError: 'dict' object has no attribute ...—— 后面会反复遇到,十有八九是把字典当对象用了,或者反过来

收个尾

这一篇其实就干了一件事:跑通 10 行代码。但把每一行都搞明白,后面会顺很多。

下一篇讲一个更反直觉的事:你连着问它两个问题,第二个问题里它根本不记得第一个问题说了什么。很多人第一次发现这一点时的反应是"这模型怎么这么笨"。其实不是它笨,是 API 的设计就是这样。

动手环节

  • 不看文章,独立跑通一次调用
  • 把问题换掉,确认自己会改
  • 打印完整 response,找到 usage,算算花了几个 token

写在最后

如果想系统、完整地吃透 Harness、Hermes 整套前沿智能体开发体系,完成从只会调模型到可控、高质量、可落地的 AI 工程交付进阶,可以关注慕课网近期上新的《Harness&Hermes 多智能体开发特训营》

💡 课程直达:https://class.imooc.com/sale/hagent

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

UL 1699-2023标准解读:AFCI电弧故障检测原理与工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/6 11:01:58

CMSIS-DSP源码深度剖析:架构、优化与工业落地实践

最近在评估工业固件里做信号处理方案时,又把Arm CMSIS-DSP整个源码逐行啃了一遍。这个库在嵌入式圈子里名气很大,但真正把它吃透、敢在量产固件里放心用的人不多。大部分开发者停留在“调用API”的层面,遇到性能不对、移植报错、编译器兼容问…

作者头像 李华
网站建设 2026/9/6 11:01:26

具身智能端侧AI算力芯片选型实战指南:避开TOPS陷阱

如果你正在为自己的具身智能机器人项目挑选端侧AI算力芯片,大概率会经历和我一样的循环:打开几十个数据手册,翻遍所有测评,对比TOPS、TDP、内存带宽,最后把板卡装上车/机载体,实际跑起来却发现根本不是那么…

作者头像 李华
网站建设 2026/9/6 11:01:19

医疗嵌入式接口协议设计:从状态建模到文档实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/6 10:57:11

RISC-V启动流程与Bootloader设计:从复位向量到内核加载

拿到一块 RISC-V 开发板,上电之后到底发生了什么?这个问题我当年也困惑过很久。习惯了 ARM 那套"固定复位向量 BootROM 引导 U-Boot"的路径之后,第一次调 RISC-V 启动流程时,光是"复位后 PC 指向哪里"就折腾…

作者头像 李华
网站建设 2026/9/6 10:54:52

跨平台文件删除技术全解析:从原理到安全实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华